@techspokes/typescript-wsdl-client 0.7.14 → 0.8.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1504 -263
- package/dist/cli.js +423 -270
- package/dist/{emit/clientEmitter.d.ts → client/generateClient.d.ts} +2 -2
- package/dist/client/generateClient.d.ts.map +1 -0
- package/dist/{emit/clientEmitter.js → client/generateClient.js} +5 -5
- package/dist/{emit/typesEmitter.d.ts → client/generateTypes.d.ts} +4 -4
- package/dist/client/generateTypes.d.ts.map +1 -0
- package/dist/{emit/typesEmitter.js → client/generateTypes.js} +6 -6
- package/dist/{emit/utilsEmitter.d.ts → client/generateUtils.d.ts} +4 -4
- package/dist/client/generateUtils.d.ts.map +1 -0
- package/dist/{emit/utilsEmitter.js → client/generateUtils.js} +7 -7
- package/dist/{emit/catalogEmitter.d.ts → compiler/generateCatalog.d.ts} +4 -4
- package/dist/compiler/generateCatalog.d.ts.map +1 -0
- package/dist/{emit/catalogEmitter.js → compiler/generateCatalog.js} +5 -5
- package/dist/compiler/schemaCompiler.d.ts +1 -1
- package/dist/compiler/schemaCompiler.js +1 -1
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -0
- package/dist/gateway/generateGateway.d.ts +73 -0
- package/dist/gateway/generateGateway.d.ts.map +1 -0
- package/dist/gateway/generateGateway.js +135 -0
- package/dist/gateway/generators.d.ts +90 -0
- package/dist/gateway/generators.d.ts.map +1 -0
- package/dist/gateway/generators.js +270 -0
- package/dist/gateway/helpers.d.ts +115 -0
- package/dist/gateway/helpers.d.ts.map +1 -0
- package/dist/gateway/helpers.js +224 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -18
- package/dist/loader/wsdlLoader.d.ts.map +1 -1
- package/dist/loader/wsdlLoader.js +1 -3
- package/dist/openapi/generateOpenAPI.d.ts +25 -1
- package/dist/openapi/generateOpenAPI.d.ts.map +1 -1
- package/dist/openapi/generateOpenAPI.js +28 -27
- package/dist/openapi/{buildPaths.d.ts → generatePaths.d.ts} +6 -6
- package/dist/openapi/generatePaths.d.ts.map +1 -0
- package/dist/openapi/{buildPaths.js → generatePaths.js} +1 -1
- package/dist/openapi/{buildSchemas.d.ts → generateSchemas.d.ts} +10 -10
- package/dist/openapi/generateSchemas.d.ts.map +1 -0
- package/dist/openapi/{buildSchemas.js → generateSchemas.js} +5 -5
- package/dist/openapi/security.d.ts.map +1 -1
- package/dist/openapi/security.js +2 -1
- package/dist/pipeline.d.ts +21 -7
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +66 -32
- package/dist/util/builder.d.ts +25 -0
- package/dist/util/builder.d.ts.map +1 -0
- package/dist/util/builder.js +52 -0
- package/dist/util/cli.d.ts +106 -0
- package/dist/util/cli.d.ts.map +1 -0
- package/dist/util/cli.js +164 -0
- package/package.json +11 -8
- package/dist/emit/catalogEmitter.d.ts.map +0 -1
- package/dist/emit/clientEmitter.d.ts.map +0 -1
- package/dist/emit/typesEmitter.d.ts.map +0 -1
- package/dist/emit/utilsEmitter.d.ts.map +0 -1
- package/dist/openapi/buildPaths.d.ts.map +0 -1
- package/dist/openapi/buildSchemas.d.ts.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// noinspection RequiredAttributes,XmlDeprecatedElement,HtmlDeprecatedTag
|
|
2
3
|
/**
|
|
3
4
|
* CLI Entry Point for TypeScript WSDL Client Generator
|
|
4
5
|
*
|
|
5
6
|
* This file implements the command-line interface for the wsdl-tsc tool, which generates
|
|
6
|
-
* fully-typed TypeScript SOAP clients from WSDL/XSD schemas. The CLI supports
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* The CLI is built using yargs for argument parsing and provides extensive options for
|
|
12
|
-
* customizing the code generation process, including TypeScript output configurations and
|
|
13
|
-
* OpenAPI specification details.
|
|
7
|
+
* fully-typed TypeScript SOAP clients from WSDL/XSD schemas. The CLI supports subcommands for
|
|
8
|
+
* client generation, OpenAPI generation, full pipeline, and gateway generation. The bare
|
|
9
|
+
* invocation (no subcommand) is kept for backward compatibility and behaves like the client
|
|
10
|
+
* command with legacy flags.
|
|
14
11
|
*/
|
|
15
12
|
import yargs from "yargs/yargs";
|
|
16
13
|
import { hideBin } from "yargs/helpers";
|
|
@@ -18,14 +15,174 @@ import fs from "node:fs";
|
|
|
18
15
|
import path from "node:path";
|
|
19
16
|
import { loadWsdl } from "./loader/wsdlLoader.js";
|
|
20
17
|
import { compileCatalog } from "./compiler/schemaCompiler.js";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
18
|
+
import { generateTypes } from "./client/generateTypes.js";
|
|
19
|
+
import { generateUtils } from "./client/generateUtils.js";
|
|
20
|
+
import { generateCatalog } from "./compiler/generateCatalog.js";
|
|
21
|
+
import { generateClient } from "./client/generateClient.js";
|
|
25
22
|
import { generateOpenAPI } from "./openapi/generateOpenAPI.js";
|
|
26
23
|
import { runGenerationPipeline } from "./pipeline.js";
|
|
24
|
+
import { resolveCompilerOptions } from "./config.js";
|
|
25
|
+
import { emitClientArtifacts, handleCLIError, parseServers, parseStatusCodes, reportCompilationStats, reportOpenApiSuccess, success, validateGatewayRequirements, } from "./util/cli.js";
|
|
26
|
+
import { buildCompilerOptionsFromArgv, buildOpenApiOptionsFromArgv } from "./util/builder.js";
|
|
27
27
|
// Process command line arguments, removing the first two elements (node executable and script path)
|
|
28
28
|
const rawArgs = hideBin(process.argv);
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Show help if no subcommand provided
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
if (!rawArgs[0] || !["compile", "client", "openapi", "gateway", "pipeline"].includes(rawArgs[0])) {
|
|
33
|
+
await yargs(rawArgs)
|
|
34
|
+
.version(false)
|
|
35
|
+
.scriptName("wsdl-tsc")
|
|
36
|
+
.usage("$0 <command> [options]")
|
|
37
|
+
.command("compile", "Compile WSDL to catalog.json")
|
|
38
|
+
.command("client", "Generate TypeScript SOAP client from WSDL or catalog")
|
|
39
|
+
.command("openapi", "Generate OpenAPI specification from WSDL or catalog")
|
|
40
|
+
.command("gateway", "Generate Fastify gateway from OpenAPI specification")
|
|
41
|
+
.command("pipeline", "Run full generation pipeline (client + OpenAPI + gateway)")
|
|
42
|
+
.demandCommand(1, "Please specify a command: compile, client, openapi, gateway, or pipeline")
|
|
43
|
+
.strict()
|
|
44
|
+
.help()
|
|
45
|
+
.parse();
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Compile subcommand - Parse WSDL and generate catalog
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
if (rawArgs[0] === "compile") {
|
|
52
|
+
const compileArgv = await yargs(rawArgs.slice(1))
|
|
53
|
+
.version(false)
|
|
54
|
+
.scriptName("wsdl-tsc compile")
|
|
55
|
+
.usage("$0 --wsdl-source <file|url> --catalog-file <path> [options]")
|
|
56
|
+
.option("wsdl-source", { type: "string", demandOption: true, desc: "Path or URL to the WSDL" })
|
|
57
|
+
.option("catalog-file", { type: "string", demandOption: true, desc: "Output path for catalog.json" })
|
|
58
|
+
// Compiler flags
|
|
59
|
+
.option("import-extensions", {
|
|
60
|
+
type: "string",
|
|
61
|
+
choices: ["js", "ts", "bare"],
|
|
62
|
+
default: "js",
|
|
63
|
+
desc: "Intra-generated import specifiers: 'js', 'ts', or 'bare'.",
|
|
64
|
+
})
|
|
65
|
+
.option("client-attributes-key", { type: "string", default: "$attributes" })
|
|
66
|
+
.option("client-class-name", { type: "string" })
|
|
67
|
+
.option("client-int64-as", { type: "string", choices: ["string", "number", "bigint"], default: "string" })
|
|
68
|
+
.option("client-bigint-as", { type: "string", choices: ["string", "number"], default: "string" })
|
|
69
|
+
.option("client-decimal-as", { type: "string", choices: ["string", "number"], default: "string" })
|
|
70
|
+
.option("client-date-as", { type: "string", choices: ["string", "Date"], default: "string" })
|
|
71
|
+
.option("client-choice-mode", { type: "string", choices: ["all-optional", "union"], default: "all-optional" })
|
|
72
|
+
.option("client-fail-on-unresolved", { type: "boolean", default: false })
|
|
73
|
+
.option("client-nillable-as-optional", { type: "boolean", default: false })
|
|
74
|
+
.strict()
|
|
75
|
+
.help()
|
|
76
|
+
.parse();
|
|
77
|
+
const catalogOut = path.resolve(String(compileArgv["catalog-file"]));
|
|
78
|
+
// Load WSDL
|
|
79
|
+
const wsdlCatalog = await loadWsdl(String(compileArgv["wsdl-source"]));
|
|
80
|
+
// Build compiler options using shared resolver and builder
|
|
81
|
+
const compilerOptions = resolveCompilerOptions({
|
|
82
|
+
...buildCompilerOptionsFromArgv(compileArgv),
|
|
83
|
+
catalog: true, // Always emit catalog for compile subcommand
|
|
84
|
+
}, {
|
|
85
|
+
wsdl: String(compileArgv["wsdl-source"]),
|
|
86
|
+
out: path.dirname(catalogOut),
|
|
87
|
+
});
|
|
88
|
+
const compiled = compileCatalog(wsdlCatalog, compilerOptions);
|
|
89
|
+
// Report compilation statistics
|
|
90
|
+
reportCompilationStats(wsdlCatalog, compiled);
|
|
91
|
+
// Ensure output directory exists
|
|
92
|
+
fs.mkdirSync(path.dirname(catalogOut), { recursive: true });
|
|
93
|
+
// Emit catalog
|
|
94
|
+
generateCatalog(catalogOut, compiled);
|
|
95
|
+
success(`Compiled catalog written to ${catalogOut}`);
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Client generation subcommand
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
if (rawArgs[0] === "client") {
|
|
102
|
+
const clientArgv = await yargs(rawArgs.slice(1))
|
|
103
|
+
.version(false)
|
|
104
|
+
.scriptName("wsdl-tsc client")
|
|
105
|
+
.usage("$0 [--wsdl-source <file|url> | --catalog-file <file>] --client-dir <dir> [--catalog-file <path>] [options]")
|
|
106
|
+
.option("wsdl-source", {
|
|
107
|
+
type: "string",
|
|
108
|
+
desc: "Path or URL to the WSDL (exclusive with --catalog-file when used as input)"
|
|
109
|
+
})
|
|
110
|
+
.option("catalog-file", {
|
|
111
|
+
type: "string",
|
|
112
|
+
desc: "Existing compiled catalog.json (for input), or output path when compiling from WSDL (default: tmp/catalog.json)"
|
|
113
|
+
})
|
|
114
|
+
.option("client-dir", {
|
|
115
|
+
type: "string",
|
|
116
|
+
demandOption: true,
|
|
117
|
+
desc: "Directory for generated client (client.ts, types.ts, utils.ts)"
|
|
118
|
+
})
|
|
119
|
+
// Compiler flags
|
|
120
|
+
.option("import-extensions", {
|
|
121
|
+
type: "string",
|
|
122
|
+
choices: ["js", "ts", "bare"],
|
|
123
|
+
default: "js",
|
|
124
|
+
desc: "Intra-generated import specifiers: 'js', 'ts', or 'bare'.",
|
|
125
|
+
})
|
|
126
|
+
.option("client-attributes-key", { type: "string", default: "$attributes" })
|
|
127
|
+
.option("client-class-name", { type: "string" })
|
|
128
|
+
.option("client-int64-as", { type: "string", choices: ["string", "number", "bigint"], default: "string" })
|
|
129
|
+
.option("client-bigint-as", { type: "string", choices: ["string", "number"], default: "string" })
|
|
130
|
+
.option("client-decimal-as", { type: "string", choices: ["string", "number"], default: "string" })
|
|
131
|
+
.option("client-date-as", { type: "string", choices: ["string", "Date"], default: "string" })
|
|
132
|
+
.option("client-choice-mode", { type: "string", choices: ["all-optional", "union"], default: "all-optional" })
|
|
133
|
+
.option("client-fail-on-unresolved", { type: "boolean", default: false })
|
|
134
|
+
.option("client-nillable-as-optional", { type: "boolean", default: false })
|
|
135
|
+
.strict()
|
|
136
|
+
.help()
|
|
137
|
+
.parse();
|
|
138
|
+
// Validate mutually exclusive options
|
|
139
|
+
const hasWsdl = !!clientArgv["wsdl-source"];
|
|
140
|
+
const hasCatalog = !!clientArgv["catalog-file"];
|
|
141
|
+
if (!hasWsdl && !hasCatalog) {
|
|
142
|
+
handleCLIError("either --wsdl-source or --catalog-file must be provided for client generation");
|
|
143
|
+
}
|
|
144
|
+
const clientOutDir = path.resolve(String(clientArgv["client-dir"]));
|
|
145
|
+
let compiled;
|
|
146
|
+
let catalogOutPath;
|
|
147
|
+
// Determine if catalog-file is input or output based on wsdl-source presence
|
|
148
|
+
if (hasWsdl && !hasCatalog) {
|
|
149
|
+
// WSDL provided, no catalog-file: default catalog output to client-dir/catalog.json
|
|
150
|
+
catalogOutPath = path.join(clientOutDir, "catalog.json");
|
|
151
|
+
}
|
|
152
|
+
else if (hasWsdl && hasCatalog) {
|
|
153
|
+
// Both provided: catalog-file is output path
|
|
154
|
+
catalogOutPath = path.resolve(String(clientArgv["catalog-file"]));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Only catalog-file provided: it's an input, load it
|
|
158
|
+
const catalogPath = path.resolve(String(clientArgv["catalog-file"]));
|
|
159
|
+
const catalogContent = fs.readFileSync(catalogPath, "utf-8");
|
|
160
|
+
compiled = JSON.parse(catalogContent);
|
|
161
|
+
success(`Loaded catalog from ${catalogPath}`);
|
|
162
|
+
}
|
|
163
|
+
// If we need to compile from WSDL
|
|
164
|
+
if (hasWsdl) {
|
|
165
|
+
const wsdlCatalog = await loadWsdl(String(clientArgv["wsdl-source"]));
|
|
166
|
+
// Build compiler options using shared resolver and builder
|
|
167
|
+
const compilerOptions = resolveCompilerOptions({
|
|
168
|
+
...buildCompilerOptionsFromArgv(clientArgv),
|
|
169
|
+
catalog: true, // Always generate catalog when compiling from WSDL
|
|
170
|
+
}, {
|
|
171
|
+
wsdl: String(clientArgv["wsdl-source"]),
|
|
172
|
+
out: clientOutDir,
|
|
173
|
+
});
|
|
174
|
+
compiled = compileCatalog(wsdlCatalog, compilerOptions);
|
|
175
|
+
// Report compilation statistics
|
|
176
|
+
reportCompilationStats(wsdlCatalog, compiled);
|
|
177
|
+
// Emit catalog
|
|
178
|
+
fs.mkdirSync(path.dirname(catalogOutPath), { recursive: true });
|
|
179
|
+
generateCatalog(catalogOutPath, compiled);
|
|
180
|
+
success(`Compiled catalog written to ${catalogOutPath}`);
|
|
181
|
+
}
|
|
182
|
+
// Emit client artifacts (excluding catalog since we already emitted it above if needed)
|
|
183
|
+
emitClientArtifacts(clientOutDir, compiled, generateClient, generateTypes, generateUtils);
|
|
184
|
+
process.exit(0);
|
|
185
|
+
}
|
|
29
186
|
/**
|
|
30
187
|
* Command handler for "openapi" subcommand
|
|
31
188
|
*
|
|
@@ -36,325 +193,321 @@ if (rawArgs[0] === "openapi") {
|
|
|
36
193
|
const openapiArgv = await yargs(rawArgs.slice(1))
|
|
37
194
|
.version(false)
|
|
38
195
|
.scriptName("wsdl-tsc openapi")
|
|
39
|
-
.usage("$0 --wsdl <file|url> --
|
|
40
|
-
.option("wsdl", { type: "string", desc: "Path or URL to the WSDL (exclusive with --catalog)" })
|
|
41
|
-
.option("catalog", { type: "string", desc: "Existing compiled catalog.json (
|
|
42
|
-
.option("
|
|
43
|
-
.option("format", {
|
|
196
|
+
.usage("$0 [--wsdl-source <file|url> | --catalog-file <file>] --openapi-file <path> [options]")
|
|
197
|
+
.option("wsdl-source", { type: "string", desc: "Path or URL to the WSDL (exclusive with --catalog-file)" })
|
|
198
|
+
.option("catalog-file", { type: "string", desc: "Existing compiled catalog.json (default: tmp/catalog.json if --wsdl-source not provided)" })
|
|
199
|
+
.option("openapi-file", { type: "string", demandOption: true, desc: "Output file or base path for OpenAPI" })
|
|
200
|
+
.option("openapi-format", {
|
|
44
201
|
type: "string",
|
|
45
202
|
choices: ["json", "yaml", "both"],
|
|
46
203
|
desc: "Output format: json|yaml|both (default json)"
|
|
47
204
|
})
|
|
48
|
-
.option("
|
|
49
|
-
.option("
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
.option("
|
|
205
|
+
.option("openapi-title", { type: "string", desc: "API title (defaults to derived service name)" })
|
|
206
|
+
.option("openapi-version-tag", {
|
|
207
|
+
type: "string",
|
|
208
|
+
desc: "API version tag for info.version (e.g. 1.0.2; default 0.0.0)"
|
|
209
|
+
})
|
|
210
|
+
.option("openapi-servers", { type: "string", desc: "Comma-separated server URLs" })
|
|
211
|
+
.option("openapi-base-path", {
|
|
212
|
+
type: "string",
|
|
213
|
+
desc: "Base path prefix added before operation segments (e.g. /v1/soap)"
|
|
214
|
+
})
|
|
215
|
+
.option("openapi-path-style", {
|
|
54
216
|
type: "string",
|
|
55
217
|
choices: ["kebab", "asis", "lower"],
|
|
56
218
|
default: "kebab",
|
|
57
219
|
desc: "Path segment style applied to operation names"
|
|
58
220
|
})
|
|
59
|
-
.option("method", {
|
|
221
|
+
.option("openapi-default-method", {
|
|
60
222
|
type: "string",
|
|
61
223
|
choices: ["post", "get", "put", "patch", "delete"],
|
|
62
224
|
default: "post",
|
|
63
|
-
desc: "Default HTTP method for all operations (can be overridden via --ops)"
|
|
225
|
+
desc: "Default HTTP method for all operations (can be overridden via --openapi-ops-file)"
|
|
64
226
|
})
|
|
65
|
-
.option("security", { type: "string", desc: "Path to security.json configuration" })
|
|
66
|
-
.option("tags", { type: "string", desc: "Path to tags.json mapping operation name -> tag" })
|
|
67
|
-
.option("ops", {
|
|
227
|
+
.option("openapi-security-file", { type: "string", desc: "Path to security.json configuration" })
|
|
228
|
+
.option("openapi-tags-file", { type: "string", desc: "Path to tags.json mapping operation name -> tag" })
|
|
229
|
+
.option("openapi-ops-file", {
|
|
68
230
|
type: "string",
|
|
69
231
|
desc: "Path to ops.json per-operation overrides (method, deprecated, summary, description)"
|
|
70
232
|
})
|
|
71
|
-
.option("
|
|
233
|
+
.option("openapi-closed-schemas", {
|
|
72
234
|
type: "boolean",
|
|
73
235
|
default: false,
|
|
74
236
|
desc: "Emit additionalProperties:false for object schemas"
|
|
75
237
|
})
|
|
76
|
-
.option("
|
|
238
|
+
.option("openapi-prune-unused-schemas", {
|
|
77
239
|
type: "boolean",
|
|
78
240
|
default: false,
|
|
79
241
|
desc: "Emit only schemas reachable from operations"
|
|
80
242
|
})
|
|
81
|
-
.option("
|
|
82
|
-
.option("no-validate", { type: "boolean", default: false, desc: "Alias for --validate=false" })
|
|
83
|
-
.option("tag-style", {
|
|
243
|
+
.option("openapi-tag-style", {
|
|
84
244
|
type: "string",
|
|
85
245
|
choices: ["default", "first", "service"],
|
|
86
246
|
default: "default",
|
|
87
|
-
desc: "Heuristic for inferring tags when no
|
|
247
|
+
desc: "Heuristic for inferring tags when no map is provided"
|
|
88
248
|
})
|
|
89
|
-
|
|
90
|
-
.option("envelope-namespace", {
|
|
249
|
+
.option("openapi-envelope-namespace", {
|
|
91
250
|
type: "string",
|
|
92
|
-
desc: "Override the standard response envelope base name segment
|
|
251
|
+
desc: "Override the standard response envelope base name segment"
|
|
93
252
|
})
|
|
94
|
-
.option("error-namespace", {
|
|
253
|
+
.option("openapi-error-namespace", {
|
|
95
254
|
type: "string",
|
|
96
|
-
desc: "Override the standard error object schema name segment
|
|
255
|
+
desc: "Override the standard error object schema name segment"
|
|
97
256
|
})
|
|
98
257
|
.strict()
|
|
99
258
|
.help()
|
|
100
259
|
.parse();
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
openapiArgv
|
|
260
|
+
// Resolve format
|
|
261
|
+
const format = openapiArgv["openapi-format"] ?? "json";
|
|
262
|
+
// Default to {openapi-file-dir}/catalog.json if neither wsdl-source nor catalog-file provided
|
|
263
|
+
if (!openapiArgv["wsdl-source"] && !openapiArgv["catalog-file"]) {
|
|
264
|
+
const openapiFileArg = String(openapiArgv["openapi-file"]);
|
|
265
|
+
const openapiDir = path.dirname(path.resolve(openapiFileArg));
|
|
266
|
+
openapiArgv["catalog-file"] = path.join(openapiDir, "catalog.json");
|
|
108
267
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
console.error("Error: either --wsdl or --catalog must be provided for openapi generation.");
|
|
112
|
-
process.exit(1);
|
|
268
|
+
if (openapiArgv["wsdl-source"] && openapiArgv["catalog-file"]) {
|
|
269
|
+
handleCLIError("provide only one of --wsdl-source or --catalog-file, not both");
|
|
113
270
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
271
|
+
const servers = parseServers(openapiArgv["openapi-servers"]);
|
|
272
|
+
const outBase = path.resolve(String(openapiArgv["openapi-file"]));
|
|
273
|
+
const openApiOptions = buildOpenApiOptionsFromArgv(openapiArgv, format, servers);
|
|
274
|
+
const result = await generateOpenAPI({
|
|
275
|
+
...openApiOptions,
|
|
276
|
+
catalogFile: openapiArgv["catalog-file"],
|
|
277
|
+
outFile: outBase,
|
|
278
|
+
wsdl: openapiArgv["wsdl-source"],
|
|
279
|
+
});
|
|
280
|
+
// Report success
|
|
281
|
+
reportOpenApiSuccess(result);
|
|
282
|
+
process.exit(0);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Command handler for "gateway" subcommand
|
|
286
|
+
*
|
|
287
|
+
* This branch handles the Fastify gateway generation mode, which creates production-ready
|
|
288
|
+
* Fastify route scaffolding and JSON Schema validation from OpenAPI 3.1 specifications.
|
|
289
|
+
*/
|
|
290
|
+
if (rawArgs[0] === "gateway") {
|
|
291
|
+
const { generateGateway } = await import("./gateway/generateGateway.js");
|
|
292
|
+
const gatewayArgv = await yargs(rawArgs.slice(1))
|
|
293
|
+
.version(false)
|
|
294
|
+
.scriptName("wsdl-tsc gateway")
|
|
295
|
+
.usage("$0 --openapi-file <file> --client-dir <dir> --gateway-dir <dir> --gateway-service-name <slug> --gateway-version-prefix <slug> [options]")
|
|
296
|
+
.option("openapi-file", {
|
|
297
|
+
type: "string",
|
|
298
|
+
demandOption: true,
|
|
299
|
+
desc: "Path to OpenAPI 3.1 JSON/YAML file"
|
|
300
|
+
})
|
|
301
|
+
.option("client-dir", {
|
|
302
|
+
type: "string",
|
|
303
|
+
demandOption: true,
|
|
304
|
+
desc: "Path to client directory (where client.ts is located)"
|
|
305
|
+
})
|
|
306
|
+
.option("gateway-dir", {
|
|
307
|
+
type: "string",
|
|
308
|
+
demandOption: true,
|
|
309
|
+
desc: "Output directory for gateway code"
|
|
310
|
+
})
|
|
311
|
+
.option("gateway-version-prefix", {
|
|
312
|
+
type: "string",
|
|
313
|
+
demandOption: true,
|
|
314
|
+
desc: "Version prefix for URN generation (e.g. v1, v2, urn:1.0.2:schema)"
|
|
315
|
+
})
|
|
316
|
+
.option("gateway-service-name", {
|
|
317
|
+
type: "string",
|
|
318
|
+
demandOption: true,
|
|
319
|
+
desc: "Service identifier for URN generation"
|
|
320
|
+
})
|
|
321
|
+
.option("import-extensions", {
|
|
322
|
+
type: "string",
|
|
323
|
+
choices: ["js", "ts", "bare"],
|
|
324
|
+
default: "js",
|
|
325
|
+
desc: "Import-extension mode for generated TypeScript modules",
|
|
326
|
+
})
|
|
327
|
+
.option("gateway-default-status-codes", {
|
|
328
|
+
type: "string",
|
|
329
|
+
desc: "Comma-separated status codes to backfill with default response (default: 200,400,401,403,404,409,422,429,500,502,503,504)"
|
|
330
|
+
})
|
|
331
|
+
.strict()
|
|
332
|
+
.help()
|
|
333
|
+
.parse();
|
|
334
|
+
// Parse default response status codes
|
|
335
|
+
let defaultResponseStatusCodes;
|
|
336
|
+
if (gatewayArgv["gateway-default-status-codes"]) {
|
|
337
|
+
try {
|
|
338
|
+
defaultResponseStatusCodes = parseStatusCodes(String(gatewayArgv["gateway-default-status-codes"]), "--gateway-default-status-codes");
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
handleCLIError(err);
|
|
342
|
+
}
|
|
117
343
|
}
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
version: openapiArgv.version,
|
|
129
|
-
servers,
|
|
130
|
-
basePath: openapiArgv.basePath,
|
|
131
|
-
pathStyle: openapiArgv.pathStyle,
|
|
132
|
-
defaultMethod: openapiArgv.method,
|
|
133
|
-
securityConfigFile: openapiArgv.security,
|
|
134
|
-
tagsFile: openapiArgv.tags,
|
|
135
|
-
opsFile: openapiArgv.ops,
|
|
136
|
-
closedSchemas: openapiArgv.closedSchemas,
|
|
137
|
-
pruneUnusedSchemas: openapiArgv.pruneUnusedSchemas,
|
|
138
|
-
format: inferredFormat,
|
|
139
|
-
skipValidate: openapiArgv.validate === false,
|
|
140
|
-
tagStyle: openapiArgv["tag-style"],
|
|
141
|
-
envelopeNamespace: openapiArgv["envelope-namespace"],
|
|
142
|
-
errorNamespace: openapiArgv["error-namespace"],
|
|
344
|
+
const outDir = path.resolve(gatewayArgv["gateway-dir"]);
|
|
345
|
+
const clientDir = path.resolve(gatewayArgv["client-dir"]);
|
|
346
|
+
await generateGateway({
|
|
347
|
+
openapiFile: gatewayArgv["openapi-file"],
|
|
348
|
+
outDir,
|
|
349
|
+
clientDir,
|
|
350
|
+
versionSlug: gatewayArgv["gateway-version-prefix"],
|
|
351
|
+
serviceSlug: gatewayArgv["gateway-service-name"],
|
|
352
|
+
defaultResponseStatusCodes,
|
|
353
|
+
imports: gatewayArgv["import-extensions"],
|
|
143
354
|
});
|
|
144
|
-
|
|
355
|
+
success(`Gateway code generated in ${outDir}`);
|
|
145
356
|
process.exit(0);
|
|
146
357
|
}
|
|
147
358
|
if (rawArgs[0] === "pipeline") {
|
|
148
359
|
const pipelineArgv = await yargs(rawArgs.slice(1))
|
|
149
360
|
.version(false)
|
|
150
361
|
.scriptName("wsdl-tsc pipeline")
|
|
151
|
-
.usage("$0 --wsdl <file|url> --
|
|
152
|
-
.option("wsdl", { type: "string", demandOption: true, desc: "Path or URL to the WSDL" })
|
|
153
|
-
|
|
362
|
+
.usage("$0 --wsdl-source <file|url> [--client-dir <dir>] [--openapi-file <path>] [--gateway-dir <dir> --gateway-service-name <slug> --gateway-version-prefix <slug>] [--catalog-file <path>] [options]")
|
|
363
|
+
.option("wsdl-source", { type: "string", demandOption: true, desc: "Path or URL to the WSDL" })
|
|
364
|
+
// Per-artifact outputs
|
|
365
|
+
.option("client-dir", {
|
|
366
|
+
type: "string",
|
|
367
|
+
desc: "Output directory for generated client (client.ts, types.ts, utils.ts)"
|
|
368
|
+
})
|
|
369
|
+
.option("openapi-file", {
|
|
370
|
+
type: "string",
|
|
371
|
+
desc: "Output base or file for OpenAPI (enables OpenAPI generation when provided)"
|
|
372
|
+
})
|
|
373
|
+
.option("gateway-dir", {
|
|
374
|
+
type: "string",
|
|
375
|
+
desc: "Output directory for gateway code (enables gateway generation when provided)"
|
|
376
|
+
})
|
|
377
|
+
.option("catalog-file", {
|
|
378
|
+
type: "string",
|
|
379
|
+
desc: "Output path for catalog.json (default: tmp/catalog.json)"
|
|
380
|
+
})
|
|
154
381
|
.option("clean", {
|
|
155
382
|
type: "boolean",
|
|
156
383
|
default: false,
|
|
157
|
-
desc: "Remove existing contents of
|
|
384
|
+
desc: "Remove existing contents of the client output directory before generation (safety: will refuse if it resolves to project root)"
|
|
158
385
|
})
|
|
159
386
|
// Compiler flags
|
|
160
|
-
.option("
|
|
161
|
-
.option("
|
|
162
|
-
.option("
|
|
163
|
-
.option("
|
|
164
|
-
.option("
|
|
165
|
-
.option("
|
|
166
|
-
.option("
|
|
167
|
-
.option("
|
|
168
|
-
.option("
|
|
169
|
-
.option("nillable-as-optional", { type: "boolean", default: false })
|
|
387
|
+
.option("import-extensions", { type: "string", choices: ["js", "ts", "bare"], default: "js" })
|
|
388
|
+
.option("client-attributes-key", { type: "string", default: "$attributes" })
|
|
389
|
+
.option("client-class-name", { type: "string" })
|
|
390
|
+
.option("client-bigint-as", { type: "string", choices: ["string", "number"], default: "string" })
|
|
391
|
+
.option("client-choice-mode", { type: "string", choices: ["all-optional", "union"], default: "all-optional" })
|
|
392
|
+
.option("client-date-as", { type: "string", choices: ["string", "Date"], default: "string" })
|
|
393
|
+
.option("client-decimal-as", { type: "string", choices: ["string", "number"], default: "string" })
|
|
394
|
+
.option("client-fail-on-unresolved", { type: "boolean", default: false })
|
|
395
|
+
.option("client-int64-as", { type: "string", choices: ["string", "number", "bigint"], default: "string" })
|
|
396
|
+
.option("client-nillable-as-optional", { type: "boolean", default: false })
|
|
170
397
|
// OpenAPI flags
|
|
171
|
-
.option("openapi-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
.option("
|
|
177
|
-
.option("
|
|
178
|
-
.option("
|
|
179
|
-
.option("
|
|
180
|
-
.option("
|
|
181
|
-
.option("
|
|
182
|
-
.option("
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
.option("
|
|
188
|
-
.option("
|
|
398
|
+
.option("openapi-format", {
|
|
399
|
+
type: "string",
|
|
400
|
+
choices: ["json", "yaml", "both"],
|
|
401
|
+
desc: "OpenAPI output format (default json)"
|
|
402
|
+
})
|
|
403
|
+
.option("openapi-title", { type: "string" })
|
|
404
|
+
.option("openapi-version-tag", { type: "string" })
|
|
405
|
+
.option("openapi-tag-style", { type: "string", choices: ["default", "first", "service"], default: "default" })
|
|
406
|
+
.option("openapi-servers", { type: "string" })
|
|
407
|
+
.option("openapi-base-path", { type: "string" })
|
|
408
|
+
.option("openapi-path-style", { type: "string", choices: ["kebab", "asis", "lower"], default: "kebab" })
|
|
409
|
+
.option("openapi-default-method", {
|
|
410
|
+
type: "string",
|
|
411
|
+
choices: ["post", "get", "put", "patch", "delete"],
|
|
412
|
+
default: "post"
|
|
413
|
+
})
|
|
414
|
+
.option("openapi-security-file", { type: "string" })
|
|
415
|
+
.option("openapi-tags-file", { type: "string" })
|
|
416
|
+
.option("openapi-ops-file", { type: "string" })
|
|
417
|
+
.option("openapi-closed-schemas", { type: "boolean", default: false })
|
|
418
|
+
.option("openapi-prune-unused-schemas", { type: "boolean", default: false })
|
|
419
|
+
.option("openapi-envelope-namespace", { type: "string" })
|
|
420
|
+
.option("openapi-error-namespace", { type: "string" })
|
|
421
|
+
// Gateway flags
|
|
422
|
+
.option("gateway-service-name", {
|
|
423
|
+
type: "string",
|
|
424
|
+
desc: "Service name for gateway URN generation (required when --gateway-dir is provided)"
|
|
425
|
+
})
|
|
426
|
+
.option("gateway-version-prefix", {
|
|
427
|
+
type: "string",
|
|
428
|
+
desc: "Version prefix for gateway URN generation (required when --gateway-dir is provided)"
|
|
429
|
+
})
|
|
430
|
+
.option("gateway-default-status-codes", {
|
|
431
|
+
type: "string",
|
|
432
|
+
desc: "Comma-separated status codes for gateway (default: 200,400,401,403,404,409,422,429,500,502,503,504)"
|
|
433
|
+
})
|
|
189
434
|
.strict()
|
|
190
435
|
.help()
|
|
191
436
|
.parse();
|
|
192
|
-
|
|
193
|
-
|
|
437
|
+
const format = pipelineArgv["openapi-format"] ?? "json";
|
|
438
|
+
const clientOut = pipelineArgv["client-dir"];
|
|
439
|
+
const openapiOut = pipelineArgv["openapi-file"];
|
|
440
|
+
const gatewayOut = pipelineArgv["gateway-dir"];
|
|
441
|
+
const catalogOutArg = pipelineArgv["catalog-file"];
|
|
442
|
+
if (!clientOut && !openapiOut && !gatewayOut) {
|
|
443
|
+
handleCLIError("At least one of --catalog-file, --client-dir, --openapi-file, or --gateway-dir must be provided for pipeline generation.");
|
|
444
|
+
}
|
|
445
|
+
// Determine catalog output path (always required since we always compile WSDL)
|
|
446
|
+
let catalogOut;
|
|
447
|
+
if (catalogOutArg) {
|
|
448
|
+
catalogOut = path.resolve(catalogOutArg);
|
|
449
|
+
}
|
|
450
|
+
else if (clientOut) {
|
|
451
|
+
// Default to client-dir/catalog.json
|
|
452
|
+
catalogOut = path.join(path.resolve(clientOut), "catalog.json");
|
|
453
|
+
}
|
|
454
|
+
else if (openapiOut) {
|
|
455
|
+
// Default to openapi-file-dir/catalog.json
|
|
456
|
+
const openapiDir = path.dirname(path.resolve(openapiOut));
|
|
457
|
+
catalogOut = path.join(openapiDir, "catalog.json");
|
|
194
458
|
}
|
|
195
|
-
if (
|
|
196
|
-
|
|
459
|
+
else if (gatewayOut) {
|
|
460
|
+
// Default to gateway-dir/catalog.json
|
|
461
|
+
catalogOut = path.join(path.resolve(gatewayOut), "catalog.json");
|
|
197
462
|
}
|
|
198
|
-
|
|
199
|
-
|
|
463
|
+
else {
|
|
464
|
+
// Fallback to tmp/catalog.json (should rarely happen due to validation above)
|
|
465
|
+
catalogOut = path.resolve("tmp/catalog.json");
|
|
466
|
+
}
|
|
467
|
+
// Handle --clean flag for client output
|
|
468
|
+
if (pipelineArgv.clean && clientOut) {
|
|
469
|
+
const clientOutDir = path.resolve(clientOut);
|
|
200
470
|
const projectRoot = path.resolve(process.cwd());
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
process.exit(2);
|
|
471
|
+
if (clientOutDir === projectRoot) {
|
|
472
|
+
handleCLIError("Refusing to clean project root. Choose a subdirectory for --client-dir.", 2);
|
|
204
473
|
}
|
|
205
|
-
if (fs.existsSync(
|
|
206
|
-
fs.rmSync(
|
|
474
|
+
if (fs.existsSync(clientOutDir)) {
|
|
475
|
+
fs.rmSync(clientOutDir, { recursive: true, force: true });
|
|
207
476
|
}
|
|
208
477
|
}
|
|
209
|
-
const servers = (pipelineArgv
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
bigIntegerAs: pipelineArgv["bigint-as"],
|
|
221
|
-
decimalAs: pipelineArgv["decimal-as"],
|
|
222
|
-
dateAs: pipelineArgv["date-as"],
|
|
223
|
-
},
|
|
224
|
-
choice: pipelineArgv.choice,
|
|
225
|
-
failOnUnresolved: pipelineArgv["fail-on-unresolved"],
|
|
226
|
-
nillableAsOptional: pipelineArgv["nillable-as-optional"],
|
|
227
|
-
},
|
|
228
|
-
openapi: {
|
|
229
|
-
outFile: pipelineArgv["openapi-out"],
|
|
230
|
-
format,
|
|
231
|
-
skipValidate: pipelineArgv.validate === false,
|
|
232
|
-
tagStyle: pipelineArgv["tag-style"],
|
|
233
|
-
servers,
|
|
234
|
-
basePath: pipelineArgv.basePath,
|
|
235
|
-
pathStyle: pipelineArgv.pathStyle,
|
|
236
|
-
defaultMethod: pipelineArgv.method,
|
|
237
|
-
securityConfigFile: pipelineArgv.security,
|
|
238
|
-
tagsFile: pipelineArgv.tags,
|
|
239
|
-
opsFile: pipelineArgv.ops,
|
|
240
|
-
closedSchemas: pipelineArgv.closedSchemas,
|
|
241
|
-
pruneUnusedSchemas: pipelineArgv.pruneUnusedSchemas,
|
|
242
|
-
envelopeNamespace: pipelineArgv["envelope-namespace"],
|
|
243
|
-
errorNamespace: pipelineArgv["error-namespace"],
|
|
478
|
+
const servers = parseServers(pipelineArgv["openapi-servers"]);
|
|
479
|
+
// Validate gateway requirements
|
|
480
|
+
validateGatewayRequirements(gatewayOut, openapiOut, pipelineArgv["gateway-service-name"], pipelineArgv["gateway-version-prefix"]);
|
|
481
|
+
// Parse gateway default response status codes if provided
|
|
482
|
+
let gatewayDefaultResponseStatusCodes;
|
|
483
|
+
if (pipelineArgv["gateway-default-status-codes"]) {
|
|
484
|
+
try {
|
|
485
|
+
gatewayDefaultResponseStatusCodes = parseStatusCodes(String(pipelineArgv["gateway-default-status-codes"]), "--gateway-default-status-codes");
|
|
486
|
+
}
|
|
487
|
+
catch (err) {
|
|
488
|
+
handleCLIError(err);
|
|
244
489
|
}
|
|
490
|
+
}
|
|
491
|
+
// Build options using helpers
|
|
492
|
+
const compilerOptions = buildCompilerOptionsFromArgv(pipelineArgv);
|
|
493
|
+
const openApiOptions = openapiOut
|
|
494
|
+
? buildOpenApiOptionsFromArgv(pipelineArgv, format, servers)
|
|
495
|
+
: undefined;
|
|
496
|
+
await runGenerationPipeline({
|
|
497
|
+
wsdl: pipelineArgv["wsdl-source"],
|
|
498
|
+
clientOutDir: clientOut ? path.resolve(clientOut) : undefined,
|
|
499
|
+
catalogOut,
|
|
500
|
+
compiler: compilerOptions,
|
|
501
|
+
openapi: openApiOptions ? {
|
|
502
|
+
...openApiOptions,
|
|
503
|
+
outFile: path.resolve(openapiOut),
|
|
504
|
+
} : undefined,
|
|
505
|
+
gateway: gatewayOut ? {
|
|
506
|
+
defaultResponseStatusCodes: gatewayDefaultResponseStatusCodes,
|
|
507
|
+
outDir: path.resolve(gatewayOut),
|
|
508
|
+
serviceSlug: pipelineArgv["gateway-service-name"],
|
|
509
|
+
versionSlug: pipelineArgv["gateway-version-prefix"],
|
|
510
|
+
} : undefined,
|
|
245
511
|
});
|
|
246
|
-
console.log(`✅ Pipeline complete (format=${format || 'json'})`);
|
|
247
512
|
process.exit(0);
|
|
248
513
|
}
|
|
249
|
-
// ---------- Original generation CLI (unchanged) ----------
|
|
250
|
-
const argv = await yargs(rawArgs)
|
|
251
|
-
.scriptName("wsdl-tsc")
|
|
252
|
-
.option("wsdl", {
|
|
253
|
-
type: "string",
|
|
254
|
-
demandOption: true,
|
|
255
|
-
desc: "Path or URL to the WSDL"
|
|
256
|
-
})
|
|
257
|
-
.option("out", {
|
|
258
|
-
type: "string",
|
|
259
|
-
demandOption: true,
|
|
260
|
-
desc: "Output directory for generated files"
|
|
261
|
-
})
|
|
262
|
-
.option("imports", {
|
|
263
|
-
type: "string",
|
|
264
|
-
choices: ["js", "ts", "bare"],
|
|
265
|
-
default: "js",
|
|
266
|
-
desc: "Intra-generated import specifiers: 'js', 'ts', or 'bare' (no extension). Default is 'js'.",
|
|
267
|
-
})
|
|
268
|
-
.option("catalog", {
|
|
269
|
-
type: "boolean",
|
|
270
|
-
default: false,
|
|
271
|
-
desc: "Emit catalog.json file with complied catalog object for introspection. Default is false.",
|
|
272
|
-
})
|
|
273
|
-
.option("attributes-key", {
|
|
274
|
-
type: "string",
|
|
275
|
-
default: "$attributes",
|
|
276
|
-
desc: "Key used by runtime marshaller for XML attributes",
|
|
277
|
-
})
|
|
278
|
-
.option("client-name", {
|
|
279
|
-
type: "string",
|
|
280
|
-
desc: "Override the generated client class name (exact export name). If not provided, it will be derived from the WSDL name or 'GeneratedSOAPClient' will be used.",
|
|
281
|
-
})
|
|
282
|
-
// Primitive mapping knobs (safe defaults)
|
|
283
|
-
.option("int64-as", {
|
|
284
|
-
type: "string",
|
|
285
|
-
choices: ["string", "number", "bigint"],
|
|
286
|
-
default: "string",
|
|
287
|
-
desc: "How to map xs:long/xs:unsignedLong",
|
|
288
|
-
})
|
|
289
|
-
.option("bigint-as", {
|
|
290
|
-
type: "string",
|
|
291
|
-
choices: ["string", "number"],
|
|
292
|
-
default: "string",
|
|
293
|
-
desc: "How to map xs:integer family (positive/nonNegative/etc.)",
|
|
294
|
-
})
|
|
295
|
-
.option("decimal-as", {
|
|
296
|
-
type: "string",
|
|
297
|
-
choices: ["string", "number"],
|
|
298
|
-
default: "string",
|
|
299
|
-
desc: "How to map xs:decimal (money/precision)",
|
|
300
|
-
})
|
|
301
|
-
.option("date-as", {
|
|
302
|
-
type: "string",
|
|
303
|
-
choices: ["string", "Date"],
|
|
304
|
-
default: "string",
|
|
305
|
-
desc: "How to map date/time/duration types",
|
|
306
|
-
})
|
|
307
|
-
.option("choice", {
|
|
308
|
-
type: "string",
|
|
309
|
-
choices: ["all-optional", "union"],
|
|
310
|
-
default: "all-optional",
|
|
311
|
-
desc: "Representation of <choice> elements: all-optional properties or discriminated union",
|
|
312
|
-
})
|
|
313
|
-
.option("fail-on-unresolved", {
|
|
314
|
-
type: "boolean",
|
|
315
|
-
default: true,
|
|
316
|
-
desc: "Emit errors if any type references cannot be resolved in the WSDL schema",
|
|
317
|
-
})
|
|
318
|
-
.option("nillable-as-optional", {
|
|
319
|
-
type: "boolean",
|
|
320
|
-
default: false,
|
|
321
|
-
desc: "Emit nillable elements as optional properties in types.",
|
|
322
|
-
})
|
|
323
|
-
.strict()
|
|
324
|
-
.help()
|
|
325
|
-
.parse();
|
|
326
|
-
const outDir = path.resolve(String(argv.out));
|
|
327
|
-
// Load & compile
|
|
328
|
-
const catalog = await loadWsdl(String(argv.wsdl));
|
|
329
|
-
const compiled = compileCatalog(catalog, {
|
|
330
|
-
wsdl: argv.wsdl,
|
|
331
|
-
out: argv.out,
|
|
332
|
-
imports: argv.imports,
|
|
333
|
-
catalog: argv["catalog"],
|
|
334
|
-
primitive: {
|
|
335
|
-
int64As: argv["int64-as"],
|
|
336
|
-
bigIntegerAs: argv["bigint-as"],
|
|
337
|
-
decimalAs: argv["decimal-as"],
|
|
338
|
-
dateAs: argv["date-as"],
|
|
339
|
-
},
|
|
340
|
-
choice: argv.choice,
|
|
341
|
-
failOnUnresolved: argv["fail-on-unresolved"],
|
|
342
|
-
attributesKey: argv["attributes-key"],
|
|
343
|
-
clientName: argv["client-name"],
|
|
344
|
-
nillableAsOptional: argv["nillable-as-optional"],
|
|
345
|
-
});
|
|
346
|
-
// Report counts of types and operations for user visibility
|
|
347
|
-
console.log(`Schemas discovered: ${catalog.schemas.length}`);
|
|
348
|
-
console.log(`Compiled types: ${compiled.types.length}`);
|
|
349
|
-
console.log(`Operations: ${compiled.operations.length}`);
|
|
350
|
-
// Ensure output directory exists
|
|
351
|
-
fs.mkdirSync(outDir, { recursive: true });
|
|
352
|
-
// Emit files
|
|
353
|
-
emitClient(path.join(outDir, "client.ts"), compiled);
|
|
354
|
-
emitTypes(path.join(outDir, "types.ts"), compiled);
|
|
355
|
-
emitUtils(path.join(outDir, "utils.ts"), compiled);
|
|
356
|
-
// Emit catalog if requested
|
|
357
|
-
if (compiled.options.catalog) {
|
|
358
|
-
emitCatalog(path.join(outDir, "catalog.json"), compiled);
|
|
359
|
-
}
|
|
360
|
-
console.log(`✅ Generated TypeScript client in ${outDir}`);
|