@techspokes/typescript-wsdl-client 0.6.3 → 0.7.1

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 (53) hide show
  1. package/README.md +296 -166
  2. package/dist/cli.js +239 -1
  3. package/dist/compiler/schemaCompiler.d.ts +54 -0
  4. package/dist/compiler/schemaCompiler.d.ts.map +1 -1
  5. package/dist/compiler/schemaCompiler.js +74 -7
  6. package/dist/config.d.ts +23 -0
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/emit/catalogEmitter.d.ts +18 -0
  9. package/dist/emit/catalogEmitter.d.ts.map +1 -1
  10. package/dist/emit/catalogEmitter.js +31 -0
  11. package/dist/emit/clientEmitter.d.ts +17 -0
  12. package/dist/emit/clientEmitter.d.ts.map +1 -1
  13. package/dist/emit/clientEmitter.js +33 -3
  14. package/dist/emit/typesEmitter.d.ts +16 -5
  15. package/dist/emit/typesEmitter.d.ts.map +1 -1
  16. package/dist/emit/typesEmitter.js +30 -5
  17. package/dist/emit/utilsEmitter.d.ts +18 -0
  18. package/dist/emit/utilsEmitter.d.ts.map +1 -1
  19. package/dist/emit/utilsEmitter.js +30 -0
  20. package/dist/index.d.ts +22 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +36 -1
  23. package/dist/loader/fetch.d.ts +31 -0
  24. package/dist/loader/fetch.d.ts.map +1 -1
  25. package/dist/loader/fetch.js +31 -0
  26. package/dist/loader/wsdlLoader.d.ts +32 -0
  27. package/dist/loader/wsdlLoader.d.ts.map +1 -1
  28. package/dist/loader/wsdlLoader.js +80 -9
  29. package/dist/openapi/buildPaths.d.ts +74 -0
  30. package/dist/openapi/buildPaths.d.ts.map +1 -0
  31. package/dist/openapi/buildPaths.js +66 -0
  32. package/dist/openapi/buildSchemas.d.ts +44 -0
  33. package/dist/openapi/buildSchemas.d.ts.map +1 -0
  34. package/dist/openapi/buildSchemas.js +196 -0
  35. package/dist/openapi/casing.d.ts +38 -0
  36. package/dist/openapi/casing.d.ts.map +1 -0
  37. package/dist/openapi/casing.js +49 -0
  38. package/dist/openapi/generateOpenAPI.d.ts +61 -0
  39. package/dist/openapi/generateOpenAPI.d.ts.map +1 -0
  40. package/dist/openapi/generateOpenAPI.js +315 -0
  41. package/dist/openapi/security.d.ts +82 -0
  42. package/dist/openapi/security.d.ts.map +1 -0
  43. package/dist/openapi/security.js +145 -0
  44. package/dist/pipeline.d.ts +37 -0
  45. package/dist/pipeline.d.ts.map +1 -0
  46. package/dist/pipeline.js +72 -0
  47. package/dist/util/tools.d.ts +100 -7
  48. package/dist/util/tools.d.ts.map +1 -1
  49. package/dist/util/tools.js +85 -7
  50. package/dist/xsd/primitives.d.ts +33 -0
  51. package/dist/xsd/primitives.d.ts.map +1 -1
  52. package/dist/xsd/primitives.js +59 -7
  53. package/package.json +7 -2
package/README.md CHANGED
@@ -6,224 +6,354 @@
6
6
  [![npm downloads](https://img.shields.io/npm/dm/@techspokes%2Ftypescript-wsdl-client.svg)](https://www.npmjs.com/package/@techspokes/typescript-wsdl-client)
7
7
  [![GitHub Stars](https://img.shields.io/github/stars/techspokes/typescript-wsdl-client?style=social)](https://github.com/techspokes/typescript-wsdl-client/stargazers)
8
8
  [![GitHub Forks](https://img.shields.io/github/forks/techspokes/typescript-wsdl-client?style=social)](https://github.com/techspokes/typescript-wsdl-client/network/members)
9
- [![GitHub Watchers](https://img.shields.io/github/watchers/techspokes/typescript-wsdl-client?style=social)](https://github.com/techspokes/typescript-wsdl-client/watchers)
10
-
11
9
  [![TechSpokes Org](https://img.shields.io/badge/org-techspokes-181717?logo=github)](https://github.com/techspokes)
12
- [![Sponsor TechSpokes](https://img.shields.io/badge/sponsor-GitHub-blue?logo=github-sponsors)](https://github.com/sponsors/TechSpokes)
13
-
14
- ## Introduction
15
-
16
- - TypeScript WSDL Client transforms WSDL/XSD schemas into a fully-typed, ready-to-use SOAP client for TypeScript.
17
- - Eliminates common SOAP pain points: inconsistent XML mappings, complex type inheritance, and module interop headaches.
18
- - Generates maintainable, diff-friendly code that runs in modern Node.js (ESM/CJS) and strict TypeScript.
10
+ [![Sponsor](https://img.shields.io/badge/sponsor-GitHub-blue?logo=github-sponsors)](https://github.com/sponsors/TechSpokes)
19
11
 
20
- With this tool you get:
21
- - End-to-end type safety: generated interfaces, aliases, and marshalling/unmarshalling logic.
22
- - Deterministic JSON ⇄ SOAP metadata: clear attribute vs element ordering.
23
- - Flexible primitive mapping: control decimals, dates, integers, and more via flags.
24
- - Automatic flattening of `<complexContent>`/`<simpleContent>` inheritance.
25
- - `<choice>` handling strategies and WS-Policy security hints baked in.
26
- - Pluggable ESM/CJS imports: target your runtime with `--imports` alone.
27
-
28
- Vendor: **[TechSpokes](https://www.techspokes.com)**
29
- Maintainer: **Serge Liatko** ([@sergeliatko](https://github.com/sergeliatko))
12
+ > **Mission**: Turn complex WSDL/XSD definitions into ergonomic, stable, type‑safe TypeScript SOAP clients — with an optional OpenAPI 3.1 bridge — so you can integrate legacy enterprise services confidently.
30
13
 
31
14
  ---
15
+ ## 1. Why This Project (What Sets It Apart)
16
+ Most generators stop at loosely typed stubs or leak XML complexity into your application layer. This tool focuses on **correct flattening and determinism**:
17
+
18
+ | Core Differentiator | What You Get |
19
+ |----------------------------------|-------------------------------------------------------------------------------------------------|
20
+ | Attribute + Element Flattening | Attributes and child elements appear as peer properties (no nested wrapper noise). |
21
+ | `$value` Text Content Convention | Simple & mixed content always represented as a `$value` property (collision-safe & documented). |
22
+ | Inheritance Resolution | `complexContent` and `simpleContent` extensions are merged or extended consistently. |
23
+ | Choice Strategy | Predictable `all-optional` modeling today (future advanced discriminators planned). |
24
+ | WS‑Policy Security Hints | Inline scan of policies surfaces required auth hints (e.g. `usernameToken`, `https`). |
25
+ | Deterministic Output | Sorted declarations and stable alias resolution for diff‑friendly regeneration. |
26
+ | Primitive Mapping Controls | Explicit flags for long / big integer / decimal / temporal families (string‑first safety). |
27
+ | Catalog Introspection | One JSON artifact (`catalog.json`) to drive further tooling (including OpenAPI). |
28
+ | OpenAPI 3.1 Bridge | Mirrors the exact TypeScript model — no divergence between runtime and spec. |
29
+ | Multi‑format Output | `--format json |yaml|both` with always‑on validation (unless disabled). |
30
+ | One‑Shot Pipeline | Single pass (parse → TS → OpenAPI) for CI & automation. |
31
+
32
+ **Vendor**: [TechSpokes](https://www.techspokes.com) · **Maintainer**: Serge Liatko ([@sergeliatko](https://github.com/sergeliatko))
32
33
 
33
- ## Installation
34
-
35
- Install the generator as a development dependency:
36
34
 
35
+ ---
36
+ ## 2. Installation
37
37
  ```bash
38
38
  npm i -D @techspokes/typescript-wsdl-client
39
- # Your app will use node-soap at runtime:
40
- npm i soap
39
+ npm i soap # runtime dependency for actual SOAP calls
41
40
  ```
42
41
 
43
42
  ---
43
+ ## 3. Typical Repository Layout
44
+ You usually want generated SOAP clients under a namespaced integration folder. Examples:
45
+ ```
46
+ src/
47
+ services/
48
+ third-party/
49
+ weather/
50
+ client.ts
51
+ types.ts
52
+ utils.ts
53
+ catalog.json
54
+ openapi.json
55
+ ```
56
+ Pick a structure that communicates ownership and stability. Regenerate into the same folder for clean diffs.
44
57
 
45
- ## Quick Start
46
-
47
- ### Generate a SOAP Client
48
-
49
- Run the following command to generate a client from your WSDL file:
58
+ ---
59
+ ## 4. Primary Usage: Generate a TypeScript SOAP Client
60
+ The **SOAP client generation** is the core of this project and the most common use case.
50
61
 
62
+ ### 4.1 Quick Start
51
63
  ```bash
52
- npx wsdl-tsc --wsdl ./spec/wsdl/MyService.wsdl --out ./src/services/my-service
64
+ npx wsdl-tsc --wsdl ./wsdl/Weather.wsdl --out ./src/services/third-party/weather
53
65
  ```
54
66
 
55
- ### Use the Generated Client
67
+ **Try with included example:**
68
+ ```bash
69
+ npx wsdl-tsc --wsdl examples/minimal/weather.wsdl --out ./tmp/weather
70
+ ```
56
71
 
72
+ Imports afterward:
57
73
  ```ts
58
- import soap from "soap";
59
- import { MyService } from "./services/my-service/client.js";
74
+ import { Weather } from "../services/third-party/weather/client.js";
75
+ ```
60
76
 
61
- const client = new MyService({
62
- source: "https://example.com/MyService?wsdl",
63
- security: new soap.WSSecurity("user", "pass")
64
- });
77
+ ### 4.2 What Gets Generated
78
+ | File | Purpose |
79
+ |----------------|-------------------------------------------------------------------------|
80
+ | `client.ts` | Strongly typed wrapper with one method per operation. |
81
+ | `types.ts` | Flattened interfaces & literal/enum aliases. |
82
+ | `utils.ts` | Metadata (attribute vs element, occurrence, nillable). |
83
+ | `catalog.json` | (If `--catalog`) compiled representation for debugging / OpenAPI reuse. |
84
+
85
+ ### 4.3 Key Modeling Rules Recap
86
+ - **Attributes & elements** → peer properties.
87
+ - **Text content** → `$value`.
88
+ - **Required attributes**: `use!=optional`; elements `min>=1`.
89
+ - **Multiplicity**: `max>1` or `unbounded` → arrays.
90
+ - **Nillable**: `nillable="true"` preserved (optionally modelled optional with `--nillable-as-optional`).
91
+ - **Inheritance**: extensions merged or emitted as extends; simpleContent base collapsed logically.
92
+
93
+ ### 4.4 CLI Flags (SOAP Client)
94
+ | Flag | Default | Description |
95
+ |--------------------------|----------------|---------------------------------------------------|
96
+ | `--wsdl` | (required) | Local path or URL to WSDL. |
97
+ | `--out` | (required) | Output directory. |
98
+ | `--imports` | `js` | Intra‑generated import style: `js`, `ts`, `bare`. |
99
+ | `--catalog` | `false` | Emit `catalog.json`. |
100
+ | `--client-name` | derived | Override exported class name. |
101
+ | `--attributes-key` | `$attributes` | Attribute bag key. |
102
+ | `--choice` | `all-optional` | Current choice strategy. |
103
+ | `--nillable-as-optional` | `false` | Treat nillable elements as optional props. |
104
+ | `--fail-on-unresolved` | `true` | Fail build on unresolved references. |
105
+ | `--int64-as` | `string` | Map 64‑bit integer types. |
106
+ | `--bigint-as` | `string` | Map arbitrary-size integer family. |
107
+ | `--decimal-as` | `string` | Map `xs:decimal`. |
108
+ | `--date-as` | `string` | Map date/time/duration primitives. |
109
+
110
+ ### 4.5 Example With Safer Numeric Decisions
111
+ ```bash
112
+ npx wsdl-tsc \
113
+ --wsdl https://example.com/Hotel.wsdl \
114
+ --out ./src/integrations/soap/hotel \
115
+ --int64-as number \
116
+ --decimal-as string \
117
+ --date-as string \
118
+ --catalog
119
+ ```
65
120
 
66
- const response = await client.MyOperation({
67
- MyOperationRQ: {
68
- MyElement: {
69
- MyAttribute: "value",
70
- ChildElementA: "valueA",
71
- },
72
- },
121
+ ### 4.6 Programmatic Generation (TypeScript Only)
122
+ ```ts
123
+ import { compileWsdlToProject } from "@techspokes/typescript-wsdl-client";
124
+ await compileWsdlToProject({
125
+ wsdl: "./wsdl/Hotel.wsdl",
126
+ outDir: "./src/integrations/soap/hotel"
73
127
  });
74
-
75
- console.log(response);
76
128
  ```
77
129
 
78
130
  ---
131
+ ## 5. Generating an OpenAPI 3.1 Definition (as a standalone run)
132
+ If you already have generated your SOAP client and just want an HTTP-friendly spec for proxies / gateways / docs:
133
+ ```bash
134
+ npx wsdl-tsc openapi --wsdl ./wsdl/Hotel.wsdl --out ./openapi/hotel --format both
135
+ ```
136
+ Or reuse a previously generated catalog:
137
+ ```bash
138
+ npx wsdl-tsc openapi --catalog ./src/integrations/soap/hotel/catalog.json --out ./openapi/hotel
139
+ ```
79
140
 
80
- ## Features
141
+ ### 5.1 Formats & Validation
142
+ | Flag | Purpose |
143
+ |----------------------------|------------------------------------------------------------|
144
+ | `--format json | yaml |both` | Output format (default json). |
145
+ | `--yaml` | (Deprecated) alias for `--format yaml` when format absent. |
146
+ | `--validate/--no-validate` | Validation on by default. |
147
+ | `--out` | Base path or explicit file (extension optional). |
148
+
149
+ ### 5.2 Core Schema Parity
150
+ The OpenAPI schemas reproduce the **exact** flattening & naming used in `types.ts` — crucial for avoiding drift between SOAP and REST surfaces.
151
+
152
+ ### 5.3 Additional Flags (Selected)
153
+ | Flag | Description |
154
+ |------------------------|--------------------------------------------------------------------------------|
155
+ | `--basePath` | Prefix for REST path segments (e.g. `/v1/booking`). |
156
+ | `--pathStyle kebab | asis |lower` | Control operation name → path transformation. |
157
+ | `--method` | Default HTTP method (per‑op override via `--ops`). |
158
+ | `--tag-style` | Tag inference: `default`, `service`, `first`. |
159
+ | `--security` | Path to `security.json` (schemes + headers + overrides). |
160
+ | `--tags` | Path to `tags.json` (explicit operation → tag map). |
161
+ | `--ops` | Path to `ops.json` (method/summary/description/deprecated). |
162
+ | `--closedSchemas` | Apply `additionalProperties:false` globally. |
163
+ | `--pruneUnusedSchemas` | Emit only reachable schemas. |
164
+ | `--servers` | Comma‑separated server base URLs for the spec (default: `/` if none provided). |
165
+
166
+ Deterministic ordering: all path keys, HTTP methods, component schema names, securitySchemes, parameters, component section keys, and operation tag arrays are alphabetically sorted for diff‑friendly output. The generator also omits a custom `jsonSchemaDialect` declaration to maximize IDE/tool compatibility (JetBrains warning avoidance) unless a future flag introduces non‑default dialect selection.
167
+
168
+ ### 5.4 Programmatic OpenAPI Generation
169
+ ```ts
170
+ import { generateOpenAPI } from "@techspokes/typescript-wsdl-client";
171
+ const { jsonPath, yamlPath } = await generateOpenAPI({
172
+ wsdl: "./wsdl/Hotel.wsdl",
173
+ outFile: "./openapi/hotel",
174
+ format: "both",
175
+ servers: ["https://api.example.com/v1"] // optional; defaults to ["/"] when omitted
176
+ });
177
+ ```
81
178
 
82
- - **Primitive-type mapping**: Fine-grained flags (`--int64-as`, `--bigint-as`, `--decimal-as`, `--date-as`) so you don't have to hand-roll conversions for odd XSD primitives.
83
- - **Complex/simpleContent inheritance**: Automatically flattens and extends base types for `<complexContent>` and `<simpleContent>` extensions.
84
- - **Deterministic metadata**: Emits runtime maps for JSON ⇄ SOAP mapping—clear attribute vs element distinctions and order.
85
- - **Choice element support**: Two modes (`all-optional` or `union`) to handle `<choice>` constructs exactly how you need.
86
- - **Fail-fast unresolved references**: `--fail-on-unresolved` aborts codegen on missing type refs to catch XSD import issues early.
87
- - **WS-Policy security hints**: Parses WS-Policy tokens and surfaces required security hints in generated JSDoc.
88
- - **Full catalog introspection**: `--catalog` emits a JSON dump of the compiled schema for debugging large/malformed WSDLs.
89
- - **Stable, sorted output**: Interfaces, aliases, attributes, and elements are consistently sorted for diff-friendly regeneration.
90
- - **ESM/CJS interop & custom imports**: `--imports js|ts|bare` lets you target your module system without manual edits.
91
- - **Attributes and child elements**: Supports both XML attributes and nested elements (including mixed `$value` content).
92
- - **Security integration**: Works with any `soap.ISecurity` (e.g., `WSSecurity`, `BasicAuthSecurity`) for seamless auth.
179
+ ### 5.5 Standard Response Envelope (Always On Since 0.7.1)
180
+ To provide a consistent, debuggable, gateway‑friendly REST surface over SOAP operations, all responses are wrapped in a **standard envelope**. You can customize naming, but disabling the envelope is no longer supported.
181
+
182
+ #### Collision Avoidance
183
+ If the base name you are concatenating already ends with the leading token of the namespace (first CamelCase word), an underscore is inserted to avoid unreadable duplicates. Examples (default `ResponseEnvelope`):
184
+ - Payload type `WeatherResponse` `WeatherResponse_ResponseEnvelope` (instead of `WeatherResponseResponseEnvelope`).
185
+ - Service `Booking` + default envelope `BookingResponseEnvelope` (no underscore since `Booking` does not end with `Response`).
186
+ The same rule applies to the error namespace (e.g. `StatusErrorObject`, `StatusError_ErrorObject`). This keeps the intent obvious and signals to developers they might want to pick a shorter custom namespace.
187
+
188
+ Core properties (always present in the base envelope):
189
+ | Field | Type | Purpose |
190
+ |-------|------|---------|
191
+ | `status` | string | High‑level machine status (e.g. `SUCCESS`, `FAILURE`, `PENDING`). |
192
+ | `message` | string \| null | Diagnostic / log message (not for end‑user UI). |
193
+ | `data` | any \| null | Operation payload (per‑operation extension specializes this). |
194
+ | `error` | Error object \| null | Populated on failures; null on success. |
195
+
196
+ Error object schema fields:
197
+ | Field | Type | Notes |
198
+ |-------|------|-------|
199
+ | `code` | string | Stable machine error code. |
200
+ | `message` | string | Brief description. |
201
+ | `details` | object \| null | Arbitrary extra info (trace IDs, validation detail, etc.). |
202
+
203
+ #### Naming Rules
204
+ * Base envelope component: `${serviceName}ResponseEnvelope` (override with `--envelope-namespace`).
205
+ * Error object component: `${serviceName}ErrorObject` (override with `--error-namespace`).
206
+ * Per operation extension: `<PayloadType|OperationName><EnvelopeNamespace>` (alphabetically sorted for stable diffs) which refines `data` to that operation's output type.
207
+ * When you pass an explicit namespace flag its value is used verbatim (no service name prefix).
208
+
209
+ #### CLI Flags
210
+ | Flag | Description |
211
+ |-------------------------------|------------------------------------------------|
212
+ | `--envelope-namespace <Name>` | Override base envelope component name segment. |
213
+ | `--error-namespace <Name>` | Override error object component name segment. |
214
+
215
+ #### Example
216
+ ```bash
217
+ npx wsdl-tsc openapi \
218
+ --wsdl ./wsdl/Hotel.wsdl \
219
+ --out ./openapi/hotel \
220
+ --format json \
221
+ --envelope-namespace ApiEnvelope \
222
+ --error-namespace ApiError
223
+ ```
224
+ Yields components in order:
225
+ 1. `HotelApiEnvelope` (base)
226
+ 2. `<Payload…>ApiEnvelope` extension schemas (A→Z)
227
+ 3. `HotelApiError` (error object)
228
+ 4. Remaining domain schemas.
93
229
 
94
230
  ---
95
-
96
- ## CLI Usage
97
-
231
+ ## 6. One‑Shot Pipeline (SOAP Client + OpenAPI Together)
232
+ Ideal for CI: single WSDL parse → TS artifacts + catalog + OpenAPI (validated).
98
233
  ```bash
99
- wsdl-tsc --wsdl <path-or-url> --out <dir> [options]
234
+ npx wsdl-tsc pipeline --wsdl ./wsdl/Hotel.wsdl --out ./src/integrations/soap/hotel --format both
100
235
  ```
101
236
 
102
- ### Required Flags
103
- - `--wsdl`: Path or URL to the WSDL file.
104
- - `--out`: Output directory for the generated files.
237
+ | Pipeline Flag | Default | Notes |
238
+ |----------------------------|----------|---------------------------------------|
239
+ | All SOAP flags | — | Same semantics as base generation. |
240
+ | All OpenAPI flags | — | Same semantics as standalone openapi. |
241
+ | `--openapi-out` | derived | Override OpenAPI base file. |
242
+ | `--format` | json | Multi-format control. |
243
+ | `--validate/--no-validate` | validate | Spec validation toggle. |
244
+ | `--tag-style` | default | Tag inference. |
105
245
 
106
- ### Options
107
-
108
- | Flag | Type | Choices | Default | Description |
109
- |------------------------|-----------|--------------------------------|----------------|------------------------------------------------------------------|
110
- | `--imports` | string | js, ts, bare | js | Intra-generated import specifiers: '.js', '.ts', or bare |
111
- | `--catalog` | boolean | true, false | false | Emit catalog.json for introspection |
112
- | `--client-name` | string | — | derived | Override the exported client class name |
113
- | `--attributes-key` | string | any | $attributes | Key used by runtime marshaller for XML attributes |
114
- | `--int64-as` | string | string, number, bigint | string | How to map xs:long/xs:unsignedLong |
115
- | `--bigint-as` | string | string, number | string | How to map xs:integer family (positive/nonNegative/etc.) |
116
- | `--decimal-as` | string | string, number | string | How to map xs:decimal (money/precision) |
117
- | `--date-as` | string | string, Date | string | How to map date/time/duration types |
118
- | `--choice` | string | all-optional, union | all-optional | Representation of `<choice>` elements |
119
- | `--fail-on-unresolved` | boolean | true, false | true | Fail if any type references cannot be resolved |
120
- | `--nillable-as-optional` | boolean | true, false | false | Treat nillable elements as optional properties in types |
246
+ Programmatic single pass:
247
+ ```ts
248
+ import { runGenerationPipeline } from "@techspokes/typescript-wsdl-client";
249
+ await runGenerationPipeline({
250
+ wsdl: "./wsdl/Hotel.wsdl",
251
+ outDir: "./src/integrations/soap/hotel",
252
+ openapi: { format: "both", tagStyle: "service" }
253
+ });
254
+ ```
121
255
 
122
256
  ---
123
-
124
- ## Generated Files
125
-
126
- The generator produces the following files in the output directory:
127
-
128
- ```
129
- <out>/
130
- types.ts # TypeScript interfaces and type aliases
131
- utils.ts # Runtime metadata for JSON ⇄ SOAP mapping
132
- client.ts # Strongly-typed SOAP client wrapper
133
- catalog.json # (optional) Compiled catalog JSON if `--catalog` is set
257
+ ## 7. Security Configuration (OpenAPI)
258
+ `security.json` example:
259
+ ```json
260
+ {
261
+ "global": {
262
+ "scheme": "bearer",
263
+ "bearer": { "bearerFormat": "JWT" },
264
+ "headers": [ { "name": "X-Correlation-Id", "required": false, "schema": { "type": "string" } } ]
265
+ },
266
+ "overrides": {
267
+ "CancelBooking": { "scheme": "apiKey" }
268
+ }
269
+ }
134
270
  ```
271
+ Supported `scheme`: `none|basic|bearer|apiKey|oauth2`.
135
272
 
136
273
  ---
274
+ ## 8. Tag Inference Strategies
275
+ | Strategy | Behavior |
276
+ |-----------|------------------------------------------------------------------------------------|
277
+ | `default` | Single tag = service name (fallback `SOAP`). |
278
+ | `service` | Always service name (even if operation prefix differs). |
279
+ | `first` | First lexical segment of CamelCase operation (e.g. `GetCityWeatherByZIP` → `Get`). |
137
280
 
138
- ## Advanced Usage
139
-
140
- ### Programmatic API
141
-
142
- You can use the generator programmatically:
281
+ Provide `tags.json` for explicit mapping when heuristics are insufficient.
143
282
 
283
+ ---
284
+ ## 9. Working With the Generated Client
285
+ ### 9.1 SOAP Client Construction
144
286
  ```ts
145
- import { compileWsdlToProject } from "@techspokes/typescript-wsdl-client";
287
+ import soap from "soap";
288
+ import { Hotel } from "./src/integrations/soap/hotel/client.js";
146
289
 
147
- await compileWsdlToProject({
148
- wsdl: "./spec/wsdl/MyService.wsdl",
149
- outDir: "./generated",
150
- options: {
151
- imports: "js",
152
- catalog: true,
153
- primitive: {
154
- int64As: "string",
155
- bigIntegerAs: "string",
156
- decimalAs: "string",
157
- dateAs: "string",
158
- },
159
- choice: "all-optional",
160
- failOnUnresolved: true,
161
- attributesKey: "$attributes",
162
- clientName: "MyServiceClient",
163
- nillableAsOptional: false,
164
- },
290
+ const hotel = new Hotel({
291
+ source: "https://example.com/HotelService?wsdl",
292
+ security: new soap.WSSecurity("user", "pass")
293
+ });
294
+
295
+ const res = await hotel.GetReservation({
296
+ GetReservationRQ: { ReservationId: "ABC123" }
165
297
  });
166
298
  ```
299
+ ### 9.2 Attributes & Text Values
300
+ If an element has text content and attributes, you pass both:
301
+ ```ts
302
+ const Price = {
303
+ currencyCode: "USD",
304
+ $value: "123.45"
305
+ };
306
+ ```
167
307
 
168
308
  ---
169
-
170
- ## Troubleshooting
171
-
172
- - CLI errors
173
- "Error: Cannot parse WSDL" verify file path or URL; test with `curl -I <wsdl-url>`.
174
- "Cannot resolve type XYZ" ensure all XSD imports are reachable or use `--fail-on-unresolved=false`.
175
- - Module resolution
176
- `ERR_MODULE_NOT_FOUND` align import extensions: use `--imports js` (adds `.js`), `--imports ts` (adds `.ts`), or `--imports bare` for no extension.
177
- - TypeScript type issues
178
- • "Cannot find module './client'" → run `npm run typecheck`, confirm your `outDir` matches import paths, and include generated `.d.ts`.
179
- - Runtime SOAP errors
180
- • Enable raw SOAP logging:
181
- ```bash
182
- NODE_DEBUG=soap node your-app.js
183
- ```
184
- • "wsdl is not valid" → update `soap` to latest (`npm i soap@latest`).
185
- - Security warnings
186
- • Missing or invalid headers → pass a valid `soap.ISecurity` instance:
187
- ```ts
188
- new soap.WSSecurity("user","pass",{passwordType:"PasswordText"});
189
- ```
190
- - XML attribute/content issues
191
- • Wrong key in requests → override with `--attributes-key inKey[:outKey]` (e.g., `--attributes-key $attributes:attributes`).
309
+ ## 10. Advanced Topics
310
+ | Topic | Notes |
311
+ |------------------------------|-------------------------------------------------------------------------------------|
312
+ | Primitive mapping philosophy | Defaults prefer string to avoid precision loss. |
313
+ | Choice flattening | Represented as optional union of fields simpler consumption. |
314
+ | Array wrappers | Single repeated child w/out attributes collapses to an array schema in OpenAPI. |
315
+ | Validation | Uses `@apidevtools/swagger-parser`; disable with `--no-validate`. |
316
+ | Future | Discriminated unions for choices, richer policy extraction, snapshot OpenAPI tests. |
192
317
 
193
318
  ---
194
-
195
- ## Roadmap
196
-
197
- Please see the [ROADMAP.md](ROADMAP.md) for planned features and improvements.
319
+ ## 11. Troubleshooting
320
+ | Symptom | Resolution |
321
+ |---------------------------|--------------------------------------------------------------------------|
322
+ | WSDL fetch fails | Curl the URL, check TLS/proxy, retry with local copy. |
323
+ | Unresolved types | Re-run with `--fail-on-unresolved=false` to inspect partial graph. |
324
+ | Missing schema in OpenAPI | Ensure the global element exists (catalog shows compiled symbols). |
325
+ | Wrong array modeling | Check `maxOccurs` in WSDL; tool only arrays when `max>1` or `unbounded`. |
326
+ | Auth errors at runtime | Provide a proper `soap.ISecurity` instance (`WSSecurity`, etc.). |
327
+ | Date/time confusion | Use `--date-as Date` for runtime Date objects. |
328
+
329
+ Enable SOAP wire logging:
330
+ ```bash
331
+ NODE_DEBUG=soap node app.js
332
+ ```
198
333
 
199
334
  ---
200
-
201
- ## Contributing
202
-
203
- We welcome contributions! Please see the following resources:
204
- - [CONTRIBUTING.md](CONTRIBUTING.md): Development workflow and guidelines.
205
- - [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md): Community expectations.
206
- - [SECURITY.md](SECURITY.md): Reporting vulnerabilities.
335
+ ## 12. Programmatic Reference (Summary)
336
+ | Function | Purpose |
337
+ |-------------------------|-------------------------------------------------|
338
+ | `compileWsdlToProject` | WSDL TS artifacts. |
339
+ | `generateOpenAPI` | WSDL or catalog → OpenAPI (json / yaml / both). |
340
+ | `runGenerationPipeline` | One pass: compile + TS emit + OpenAPI. |
207
341
 
208
342
  ---
343
+ ## 13. Contributing
344
+ 1. Fork & branch.
345
+ 2. `npm i && npm run build`.
346
+ 3. Use `npm run smoke:gen`, `npm run smoke:pipeline`.
347
+ - Pipeline smoke validates envelope, ordering & validation.
348
+ 4. Add a bullet under **Unreleased** in `CHANGELOG.md`.
209
349
 
210
- ## License
211
-
212
- MIT © TechSpokes.
213
- *The tool is MIT-licensed. Generated artifacts are owned by you; the tool imposes no license on generated files.*
350
+ See also: `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`.
214
351
 
215
352
  ---
353
+ ## 14. License
354
+ MIT © TechSpokes — Generated artifacts are fully yours.
216
355
 
217
- ## Sponsors
218
-
219
- **Silver Sponsors**
220
- - Your Name Here!
221
-
222
- **Gold Sponsors**
223
- - [Your Name or Company (with a link) Here!](https://your-link-here.com)
224
-
225
- **Platinum Sponsors**
226
- - [Your Name or Company (with a link) Here!](https://your-link-here.com)
227
- - **AND** 30-min one-to-one video meeting on AI, business automations, vacation rentals industry, development, tools, or a subject of your choice.
228
-
229
- Want to see your name or company here? [Become a sponsor!](https://github.com/sponsors/TechSpokes)
356
+ ---
357
+ ## 15. Sponsors
358
+ Support ongoing maintenance: https://github.com/sponsors/TechSpokes
359
+ *Your brand could be featured here.*