tsoap-cli 0.0.2 → 0.0.3
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/dist/cli.js +35 -15
- package/dist/cli.js.map +1 -1
- package/dist/generator/codegen.d.ts.map +1 -1
- package/dist/generator/codegen.js +6 -1
- package/dist/generator/codegen.js.map +1 -1
- package/dist/parser/wsdl-parser.d.ts +0 -2
- package/dist/parser/wsdl-parser.d.ts.map +1 -1
- package/dist/parser/wsdl-parser.js +72 -20
- package/dist/parser/wsdl-parser.js.map +1 -1
- package/package.json +15 -9
- package/src/cli.ts +0 -45
- package/src/generator/codegen.ts +0 -135
- package/src/generator/writer.ts +0 -14
- package/src/generator/xsd-types.ts +0 -102
- package/src/parser/wsdl-parser.ts +0 -402
- package/tsconfig.json +0 -8
package/dist/cli.js
CHANGED
|
@@ -1,34 +1,54 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { resolve, basename, join } from "node:path";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { dirname } from "node:path";
|
|
3
6
|
import { Command } from "commander";
|
|
4
7
|
import { parseWsdl } from "./parser/wsdl-parser.js";
|
|
5
8
|
import { generateTypeScript } from "./generator/codegen.js";
|
|
6
9
|
import { writeGeneratedFile } from "./generator/writer.js";
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
7
13
|
const program = new Command();
|
|
8
14
|
program
|
|
9
15
|
.name("tsoap")
|
|
10
16
|
.description("Generate type-safe TypeScript clients from WSDL files")
|
|
11
|
-
.version(
|
|
17
|
+
.version(pkg.version);
|
|
12
18
|
program
|
|
13
19
|
.command("generate")
|
|
14
20
|
.description("Parse a WSDL and generate a typed TypeScript client")
|
|
15
21
|
.requiredOption("-i, --input <path>", "Path or URL to the WSDL file")
|
|
16
22
|
.requiredOption("-o, --output <dir>", "Output directory for generated files")
|
|
17
23
|
.action(async (opts) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
try {
|
|
25
|
+
const inputPath = opts.input;
|
|
26
|
+
const outputDir = resolve(opts.output);
|
|
27
|
+
const isUrl = inputPath.startsWith("http://") || inputPath.startsWith("https://");
|
|
28
|
+
const resolvedInput = isUrl ? inputPath : resolve(inputPath);
|
|
29
|
+
const outputFileName = basename(inputPath, ".wsdl") + ".ts";
|
|
30
|
+
const outputPath = join(outputDir, outputFileName);
|
|
31
|
+
console.log(`Parsing WSDL: ${resolvedInput}`);
|
|
32
|
+
const parsed = await parseWsdl(resolvedInput);
|
|
33
|
+
const totalOps = parsed.services.reduce((sum, svc) => sum + svc.ports.reduce((s, p) => s + p.operations.length, 0), 0);
|
|
34
|
+
if (parsed.services.length === 0) {
|
|
35
|
+
console.warn("Warning: WSDL contains no services. Generated file will be empty.");
|
|
36
|
+
}
|
|
37
|
+
else if (totalOps === 0) {
|
|
38
|
+
console.warn("Warning: WSDL services contain no operations. Generated file will have no callable methods.");
|
|
39
|
+
}
|
|
40
|
+
console.log(`Found ${parsed.services.length} service(s), ` +
|
|
41
|
+
`${parsed.types.length} type(s), ` +
|
|
42
|
+
`${parsed.enums.length} enum(s)`);
|
|
43
|
+
const source = generateTypeScript(parsed, basename(inputPath));
|
|
44
|
+
await writeGeneratedFile(outputPath, source);
|
|
45
|
+
console.log(`Generated: ${outputPath}`);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
49
|
+
console.error(`Error: ${message}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
32
52
|
});
|
|
33
53
|
program.parse();
|
|
34
54
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,uDAAuD,CAAC;KACpE,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/generator/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAIX,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/generator/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAIX,MAAM,0BAA0B,CAAC;AAmGlC;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAiCjF"}
|
|
@@ -20,8 +20,13 @@ function emitInterface(type) {
|
|
|
20
20
|
lines.push("}");
|
|
21
21
|
return lines.join("\n");
|
|
22
22
|
}
|
|
23
|
+
function escapeStringLiteral(value) {
|
|
24
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
25
|
+
}
|
|
23
26
|
function emitEnum(enumType) {
|
|
24
|
-
const values = enumType.values
|
|
27
|
+
const values = enumType.values
|
|
28
|
+
.map((v) => `"${escapeStringLiteral(v)}"`)
|
|
29
|
+
.join(" | ");
|
|
25
30
|
return `export type ${enumType.name} = ${values};`;
|
|
26
31
|
}
|
|
27
32
|
function emitServiceDefinition(parsed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/generator/codegen.ts"],"names":[],"mappings":"AAOA,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,aAAa,CAAC,KAAkB,EAAE,WAAmB;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CACR,GAAG,MAAM,CAAC,WAAW,CAAC,iEAAiE,CACxF,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,KAAK,CAAC,IAAI,CACR,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,QAAQ,KAAK,KAAK,CAAC,MAAM,GAAG,WAAW,GAAG,CACjF,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,aAAa,CAAC,IAAgB;IACrC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;IAC9C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,QAAQ,CAAC,QAAoB;IACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/generator/codegen.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export interface ParsedField {
|
|
2
2
|
name: string;
|
|
3
|
-
/** TypeScript type as a source string (e.g. "string", "number", "MyInterface") */
|
|
4
3
|
tsType: string;
|
|
5
4
|
isArray: boolean;
|
|
6
5
|
isOptional: boolean;
|
|
7
|
-
/** If true, the generated type should include a JSDoc precision warning */
|
|
8
6
|
precisionRisk: boolean;
|
|
9
7
|
}
|
|
10
8
|
export interface ParsedType {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wsdl-parser.d.ts","sourceRoot":"","sources":["../../src/parser/wsdl-parser.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,
|
|
1
|
+
{"version":3,"file":"wsdl-parser.d.ts","sourceRoot":"","sources":["../../src/parser/wsdl-parser.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AA4UD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA4ErE"}
|
|
@@ -46,8 +46,11 @@ function resolveElementNames(client, serviceName, portName, opName) {
|
|
|
46
46
|
return { input: inputName, output: outputName };
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
catch {
|
|
50
|
-
|
|
49
|
+
catch (err) {
|
|
50
|
+
if (err instanceof TypeError) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
throw err;
|
|
51
54
|
}
|
|
52
55
|
return null;
|
|
53
56
|
}
|
|
@@ -84,8 +87,63 @@ function extractFields(node) {
|
|
|
84
87
|
}
|
|
85
88
|
return fields;
|
|
86
89
|
}
|
|
90
|
+
const TS_RESERVED_WORDS = new Set([
|
|
91
|
+
"break", "case", "catch", "class", "const", "continue", "debugger",
|
|
92
|
+
"default", "delete", "do", "else", "enum", "export", "extends",
|
|
93
|
+
"false", "finally", "for", "function", "if", "import", "in",
|
|
94
|
+
"instanceof", "new", "null", "return", "super", "switch", "this",
|
|
95
|
+
"throw", "true", "try", "typeof", "var", "void", "while", "with",
|
|
96
|
+
"yield", "let", "static", "implements", "interface", "package",
|
|
97
|
+
"private", "protected", "public", "type",
|
|
98
|
+
]);
|
|
99
|
+
const TS_GLOBAL_TYPES = new Set([
|
|
100
|
+
"Date", "Error", "Map", "Set", "Array", "Object", "Function",
|
|
101
|
+
"Number", "String", "Boolean", "Symbol", "Promise", "RegExp",
|
|
102
|
+
"Buffer", "Record", "Partial", "Required", "Readonly", "Pick",
|
|
103
|
+
"Omit", "Exclude", "Extract", "NonNullable", "ReturnType",
|
|
104
|
+
"InstanceType", "Parameters",
|
|
105
|
+
]);
|
|
106
|
+
/**
|
|
107
|
+
* Converts a string to PascalCase, splitting on hyphens, dots,
|
|
108
|
+
* underscores, and whitespace.
|
|
109
|
+
*/
|
|
87
110
|
function pascalCase(str) {
|
|
88
|
-
return str
|
|
111
|
+
return str
|
|
112
|
+
.split(/[-._\s]+/)
|
|
113
|
+
.filter(Boolean)
|
|
114
|
+
.map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1))
|
|
115
|
+
.join("");
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Ensures a string is a valid TypeScript identifier.
|
|
119
|
+
* Strips invalid characters, handles leading digits,
|
|
120
|
+
* and avoids TS reserved words (for type names).
|
|
121
|
+
*/
|
|
122
|
+
function sanitizeTypeName(raw) {
|
|
123
|
+
let name = pascalCase(raw);
|
|
124
|
+
name = name.replace(/[^a-zA-Z0-9_$]/g, "");
|
|
125
|
+
if (!name || /^[0-9]/.test(name)) {
|
|
126
|
+
name = "_" + name;
|
|
127
|
+
}
|
|
128
|
+
if (TS_RESERVED_WORDS.has(name)) {
|
|
129
|
+
name = name + "Type";
|
|
130
|
+
}
|
|
131
|
+
if (TS_GLOBAL_TYPES.has(name)) {
|
|
132
|
+
name = name + "Type";
|
|
133
|
+
}
|
|
134
|
+
return name;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Sanitizes a field name for use in a TypeScript interface.
|
|
138
|
+
* TS allows reserved words as property names, so we only strip
|
|
139
|
+
* characters that are invalid in identifiers and handle leading digits.
|
|
140
|
+
*/
|
|
141
|
+
function sanitizeFieldName(raw) {
|
|
142
|
+
let name = raw.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
143
|
+
if (!name || /^[0-9]/.test(name)) {
|
|
144
|
+
name = "_" + name;
|
|
145
|
+
}
|
|
146
|
+
return name;
|
|
89
147
|
}
|
|
90
148
|
/**
|
|
91
149
|
* Parses an element descriptor from `client.describe()`,
|
|
@@ -94,18 +152,19 @@ function pascalCase(str) {
|
|
|
94
152
|
function parseFieldDescriptor(fieldName, descriptor, collectedTypes, collectedEnums, schemaMap, parentSchemaInfo) {
|
|
95
153
|
const isArray = fieldName.endsWith("[]");
|
|
96
154
|
const cleanName = isArray ? fieldName.slice(0, -2) : fieldName;
|
|
155
|
+
const safeName = sanitizeFieldName(cleanName);
|
|
97
156
|
const schemaField = parentSchemaInfo?.fields.find((f) => f.name === cleanName);
|
|
98
157
|
const isOptional = schemaField?.minOccurs === "0";
|
|
99
158
|
if (typeof descriptor === "string") {
|
|
100
159
|
const enumMatch = descriptor.match(/^(\w+)\|[^|]+\|(.+)$/);
|
|
101
160
|
if (enumMatch) {
|
|
102
|
-
const enumName = enumMatch[1];
|
|
161
|
+
const enumName = sanitizeTypeName(enumMatch[1]);
|
|
103
162
|
const values = enumMatch[2].split(",");
|
|
104
163
|
if (!collectedEnums.has(enumName)) {
|
|
105
164
|
collectedEnums.set(enumName, { name: enumName, values });
|
|
106
165
|
}
|
|
107
166
|
return {
|
|
108
|
-
name:
|
|
167
|
+
name: safeName,
|
|
109
168
|
tsType: enumName,
|
|
110
169
|
isArray,
|
|
111
170
|
isOptional,
|
|
@@ -116,7 +175,7 @@ function parseFieldDescriptor(fieldName, descriptor, collectedTypes, collectedEn
|
|
|
116
175
|
const primitive = resolveXsdPrimitive(localName);
|
|
117
176
|
if (primitive) {
|
|
118
177
|
return {
|
|
119
|
-
name:
|
|
178
|
+
name: safeName,
|
|
120
179
|
tsType: primitive.tsType,
|
|
121
180
|
isArray,
|
|
122
181
|
isOptional,
|
|
@@ -124,7 +183,7 @@ function parseFieldDescriptor(fieldName, descriptor, collectedTypes, collectedEn
|
|
|
124
183
|
};
|
|
125
184
|
}
|
|
126
185
|
return {
|
|
127
|
-
name:
|
|
186
|
+
name: safeName,
|
|
128
187
|
tsType: localName,
|
|
129
188
|
isArray,
|
|
130
189
|
isOptional,
|
|
@@ -135,14 +194,12 @@ function parseFieldDescriptor(fieldName, descriptor, collectedTypes, collectedEn
|
|
|
135
194
|
let typeName;
|
|
136
195
|
if (schemaField?.type) {
|
|
137
196
|
const localTypeName = stripNamespace(schemaField.type);
|
|
138
|
-
typeName =
|
|
197
|
+
typeName = sanitizeTypeName(localTypeName);
|
|
139
198
|
}
|
|
140
199
|
else {
|
|
141
|
-
typeName =
|
|
200
|
+
typeName = sanitizeTypeName(cleanName);
|
|
142
201
|
}
|
|
143
202
|
if (!collectedTypes.has(typeName)) {
|
|
144
|
-
// BUG 1 FIX: insert placeholder BEFORE recursing to prevent
|
|
145
|
-
// infinite recursion on self-referencing types (e.g. TreeNode)
|
|
146
203
|
const placeholder = { name: typeName, fields: [] };
|
|
147
204
|
collectedTypes.set(typeName, placeholder);
|
|
148
205
|
const nestedSchemaInfo = schemaMap.get(typeName) ?? schemaMap.get(cleanName);
|
|
@@ -150,7 +207,7 @@ function parseFieldDescriptor(fieldName, descriptor, collectedTypes, collectedEn
|
|
|
150
207
|
placeholder.fields = fields;
|
|
151
208
|
}
|
|
152
209
|
return {
|
|
153
|
-
name:
|
|
210
|
+
name: safeName,
|
|
154
211
|
tsType: typeName,
|
|
155
212
|
isArray,
|
|
156
213
|
isOptional,
|
|
@@ -158,7 +215,7 @@ function parseFieldDescriptor(fieldName, descriptor, collectedTypes, collectedEn
|
|
|
158
215
|
};
|
|
159
216
|
}
|
|
160
217
|
return {
|
|
161
|
-
name:
|
|
218
|
+
name: safeName,
|
|
162
219
|
tsType: "unknown",
|
|
163
220
|
isArray,
|
|
164
221
|
isOptional,
|
|
@@ -205,16 +262,11 @@ export async function parseWsdl(wsdlPath) {
|
|
|
205
262
|
const opObj = opDesc;
|
|
206
263
|
const inputDesc = opObj.input ?? {};
|
|
207
264
|
const outputDesc = opObj.output ?? {};
|
|
208
|
-
// BUG 3 FIX: resolve actual element names from the port's binding
|
|
209
|
-
// instead of guessing based on naming conventions.
|
|
210
265
|
const elementNames = resolveElementNames(client, serviceName, portName, opName);
|
|
211
266
|
const inputElementName = elementNames?.input ?? `${opName}Request`;
|
|
212
267
|
const outputElementName = elementNames?.output ?? `${opName}Response`;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const inputTypeName = uniqueTypeName(pascalCase(inputElementName), portName, collectedTypes);
|
|
216
|
-
const outputTypeName = uniqueTypeName(pascalCase(outputElementName), portName, collectedTypes);
|
|
217
|
-
// BUG 3 FIX: look up schema info by the actual element name
|
|
268
|
+
const inputTypeName = uniqueTypeName(sanitizeTypeName(inputElementName), portName, collectedTypes);
|
|
269
|
+
const outputTypeName = uniqueTypeName(sanitizeTypeName(outputElementName), portName, collectedTypes);
|
|
218
270
|
const inputSchemaInfo = schemaMap.get(inputElementName) ?? schemaMap.get(inputTypeName);
|
|
219
271
|
const outputSchemaInfo = schemaMap.get(outputElementName) ?? schemaMap.get(outputTypeName);
|
|
220
272
|
const inputFields = parseObjectDescriptor(inputDesc, collectedTypes, collectedEnums, schemaMap, inputSchemaInfo);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wsdl-parser.js","sourceRoot":"","sources":["../../src/parser/wsdl-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"wsdl-parser.js","sourceRoot":"","sources":["../../src/parser/wsdl-parser.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsoap-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "End-to-end type-safe SOAP client for TypeScript. Generate typed RPC wrappers directly from WSDLs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"soap",
|
|
@@ -14,22 +14,24 @@
|
|
|
14
14
|
"generator"
|
|
15
15
|
],
|
|
16
16
|
"type": "module",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
17
20
|
"bin": {
|
|
18
21
|
"tsoap": "./dist/cli.js"
|
|
19
22
|
},
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "tsc",
|
|
22
|
-
"dev": "tsc --watch"
|
|
23
|
-
},
|
|
24
23
|
"dependencies": {
|
|
25
24
|
"commander": "^13.1.0",
|
|
26
|
-
"soap": "^1.1.6"
|
|
27
|
-
"typescript": "^5.9.2"
|
|
25
|
+
"soap": "^1.1.6"
|
|
28
26
|
},
|
|
29
27
|
"devDependencies": {
|
|
30
|
-
"@types/node": "^18.0.0"
|
|
28
|
+
"@types/node": "^18.0.0",
|
|
29
|
+
"typescript": "^5.9.2"
|
|
31
30
|
},
|
|
32
31
|
"license": "MIT",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
33
35
|
"repository": {
|
|
34
36
|
"type": "git",
|
|
35
37
|
"url": "https://github.com/Deodat-Lawson/tsoap.git",
|
|
@@ -37,5 +39,9 @@
|
|
|
37
39
|
},
|
|
38
40
|
"publishConfig": {
|
|
39
41
|
"registry": "https://registry.npmjs.org/"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc",
|
|
45
|
+
"dev": "tsc --watch"
|
|
40
46
|
}
|
|
41
|
-
}
|
|
47
|
+
}
|
package/src/cli.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { resolve, basename, join } from "node:path";
|
|
4
|
-
import { Command } from "commander";
|
|
5
|
-
import { parseWsdl } from "./parser/wsdl-parser.js";
|
|
6
|
-
import { generateTypeScript } from "./generator/codegen.js";
|
|
7
|
-
import { writeGeneratedFile } from "./generator/writer.js";
|
|
8
|
-
|
|
9
|
-
const program = new Command();
|
|
10
|
-
|
|
11
|
-
program
|
|
12
|
-
.name("tsoap")
|
|
13
|
-
.description("Generate type-safe TypeScript clients from WSDL files")
|
|
14
|
-
.version("0.0.1");
|
|
15
|
-
|
|
16
|
-
program
|
|
17
|
-
.command("generate")
|
|
18
|
-
.description("Parse a WSDL and generate a typed TypeScript client")
|
|
19
|
-
.requiredOption("-i, --input <path>", "Path or URL to the WSDL file")
|
|
20
|
-
.requiredOption("-o, --output <dir>", "Output directory for generated files")
|
|
21
|
-
.action(async (opts: { input: string; output: string }) => {
|
|
22
|
-
const inputPath = opts.input;
|
|
23
|
-
const outputDir = resolve(opts.output);
|
|
24
|
-
|
|
25
|
-
const isUrl = inputPath.startsWith("http://") || inputPath.startsWith("https://");
|
|
26
|
-
const resolvedInput = isUrl ? inputPath : resolve(inputPath);
|
|
27
|
-
const outputFileName = basename(inputPath, ".wsdl") + ".ts";
|
|
28
|
-
const outputPath = join(outputDir, outputFileName);
|
|
29
|
-
|
|
30
|
-
console.log(`Parsing WSDL: ${resolvedInput}`);
|
|
31
|
-
const parsed = await parseWsdl(resolvedInput);
|
|
32
|
-
|
|
33
|
-
console.log(
|
|
34
|
-
`Found ${parsed.services.length} service(s), ` +
|
|
35
|
-
`${parsed.types.length} type(s), ` +
|
|
36
|
-
`${parsed.enums.length} enum(s)`,
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
const source = generateTypeScript(parsed, basename(inputPath));
|
|
40
|
-
await writeGeneratedFile(outputPath, source);
|
|
41
|
-
|
|
42
|
-
console.log(`Generated: ${outputPath}`);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
program.parse();
|
package/src/generator/codegen.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ParsedWsdl,
|
|
3
|
-
ParsedType,
|
|
4
|
-
ParsedEnum,
|
|
5
|
-
ParsedField,
|
|
6
|
-
} from "../parser/wsdl-parser.js";
|
|
7
|
-
|
|
8
|
-
function indent(level: number): string {
|
|
9
|
-
return " ".repeat(level);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function fieldToString(field: ParsedField, indentLevel: number): string {
|
|
13
|
-
const lines: string[] = [];
|
|
14
|
-
if (field.precisionRisk) {
|
|
15
|
-
lines.push(
|
|
16
|
-
`${indent(indentLevel)}/** WARNING: values > Number.MAX_SAFE_INTEGER lose precision */`,
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
const optional = field.isOptional ? "?" : "";
|
|
20
|
-
const arraySuffix = field.isArray ? "[]" : "";
|
|
21
|
-
lines.push(
|
|
22
|
-
`${indent(indentLevel)}${field.name}${optional}: ${field.tsType}${arraySuffix};`,
|
|
23
|
-
);
|
|
24
|
-
return lines.join("\n");
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function emitInterface(type: ParsedType): string {
|
|
28
|
-
const lines: string[] = [];
|
|
29
|
-
lines.push(`export interface ${type.name} {`);
|
|
30
|
-
for (const field of type.fields) {
|
|
31
|
-
lines.push(fieldToString(field, 1));
|
|
32
|
-
}
|
|
33
|
-
lines.push("}");
|
|
34
|
-
return lines.join("\n");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function emitEnum(enumType: ParsedEnum): string {
|
|
38
|
-
const values = enumType.values.map((v) => `"${v}"`).join(" | ");
|
|
39
|
-
return `export type ${enumType.name} = ${values};`;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function emitServiceDefinition(parsed: ParsedWsdl): string {
|
|
43
|
-
const lines: string[] = [];
|
|
44
|
-
const defName = parsed.services.length === 1
|
|
45
|
-
? `${parsed.services[0].name}Definition`
|
|
46
|
-
: "GeneratedServiceDefinition";
|
|
47
|
-
|
|
48
|
-
lines.push(`export interface ${defName} extends ServiceDefinition {`);
|
|
49
|
-
|
|
50
|
-
for (const service of parsed.services) {
|
|
51
|
-
lines.push(`${indent(1)}${service.name}: {`);
|
|
52
|
-
for (const port of service.ports) {
|
|
53
|
-
lines.push(`${indent(2)}${port.name}: {`);
|
|
54
|
-
for (const op of port.operations) {
|
|
55
|
-
lines.push(`${indent(3)}${op.name}: {`);
|
|
56
|
-
lines.push(`${indent(4)}input: ${op.input.name};`);
|
|
57
|
-
lines.push(`${indent(4)}output: ${op.output.name};`);
|
|
58
|
-
lines.push(`${indent(3)}};`);
|
|
59
|
-
}
|
|
60
|
-
lines.push(`${indent(2)}};`);
|
|
61
|
-
}
|
|
62
|
-
lines.push(`${indent(1)}};`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
lines.push("}");
|
|
66
|
-
return lines.join("\n");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function emitFactoryFunction(parsed: ParsedWsdl): string {
|
|
70
|
-
const defName = parsed.services.length === 1
|
|
71
|
-
? `${parsed.services[0].name}Definition`
|
|
72
|
-
: "GeneratedServiceDefinition";
|
|
73
|
-
|
|
74
|
-
const clientType =
|
|
75
|
-
parsed.services.length === 1
|
|
76
|
-
? `${parsed.services[0].name}Client`
|
|
77
|
-
: "GeneratedClient";
|
|
78
|
-
|
|
79
|
-
const factoryName =
|
|
80
|
-
parsed.services.length === 1
|
|
81
|
-
? `create${parsed.services[0].name}Client`
|
|
82
|
-
: "createGeneratedClient";
|
|
83
|
-
|
|
84
|
-
const lines: string[] = [];
|
|
85
|
-
|
|
86
|
-
lines.push(`export type ${clientType} = InferClient<${defName}>;`);
|
|
87
|
-
lines.push("");
|
|
88
|
-
lines.push(
|
|
89
|
-
`export async function ${factoryName}(wsdlUrl: string, options?: SoapClientOptions): Promise<${clientType}> {`,
|
|
90
|
-
);
|
|
91
|
-
lines.push(
|
|
92
|
-
`${indent(1)}return createSoapClient<${defName}>(wsdlUrl, options);`,
|
|
93
|
-
);
|
|
94
|
-
lines.push("}");
|
|
95
|
-
|
|
96
|
-
return lines.join("\n");
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Generates a complete TypeScript source file from a parsed WSDL.
|
|
101
|
-
*/
|
|
102
|
-
export function generateTypeScript(parsed: ParsedWsdl, sourceWsdl: string): string {
|
|
103
|
-
const emittedTypes = new Set<string>();
|
|
104
|
-
const sections: string[] = [];
|
|
105
|
-
|
|
106
|
-
sections.push(
|
|
107
|
-
`// Auto-generated by tsoap-cli — do not edit`,
|
|
108
|
-
`// Source: ${sourceWsdl}`,
|
|
109
|
-
`// Generated: ${new Date().toISOString()}`,
|
|
110
|
-
"",
|
|
111
|
-
`import { createSoapClient } from "typed-soap";`,
|
|
112
|
-
`import type { ServiceDefinition, InferClient, SoapClientOptions } from "typed-soap";`,
|
|
113
|
-
"",
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
for (const enumType of parsed.enums) {
|
|
117
|
-
sections.push(emitEnum(enumType));
|
|
118
|
-
sections.push("");
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
for (const type of parsed.types) {
|
|
122
|
-
if (!emittedTypes.has(type.name)) {
|
|
123
|
-
sections.push(emitInterface(type));
|
|
124
|
-
sections.push("");
|
|
125
|
-
emittedTypes.add(type.name);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
sections.push(emitServiceDefinition(parsed));
|
|
130
|
-
sections.push("");
|
|
131
|
-
sections.push(emitFactoryFunction(parsed));
|
|
132
|
-
sections.push("");
|
|
133
|
-
|
|
134
|
-
return sections.join("\n");
|
|
135
|
-
}
|
package/src/generator/writer.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
-
import { dirname } from "node:path";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Writes generated TypeScript source to a file, creating
|
|
6
|
-
* parent directories as needed.
|
|
7
|
-
*/
|
|
8
|
-
export async function writeGeneratedFile(
|
|
9
|
-
filePath: string,
|
|
10
|
-
content: string,
|
|
11
|
-
): Promise<void> {
|
|
12
|
-
await mkdir(dirname(filePath), { recursive: true });
|
|
13
|
-
await writeFile(filePath, content, "utf-8");
|
|
14
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Maps XSD primitive type local names (without namespace prefix) to
|
|
3
|
-
* their TypeScript type representation as a source string.
|
|
4
|
-
*
|
|
5
|
-
* The soap package natively deserializes: int, integer, short, long,
|
|
6
|
-
* float, double, decimal (to number), boolean (to boolean), dateTime
|
|
7
|
-
* and date (to Date). Our runtime's customDeserializer fills in the
|
|
8
|
-
* gaps for byte, unsigned*, and named integer types so they also
|
|
9
|
-
* arrive as numbers at runtime.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const SAFE_NUMBER_TYPES = new Set([
|
|
13
|
-
"int",
|
|
14
|
-
"short",
|
|
15
|
-
"byte",
|
|
16
|
-
"unsignedInt",
|
|
17
|
-
"unsignedShort",
|
|
18
|
-
"unsignedByte",
|
|
19
|
-
"float",
|
|
20
|
-
"double",
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
|
-
/** WARNING: values > Number.MAX_SAFE_INTEGER lose precision */
|
|
24
|
-
const PRECISION_RISK_NUMBER_TYPES = new Set([
|
|
25
|
-
"long",
|
|
26
|
-
"unsignedLong",
|
|
27
|
-
"integer",
|
|
28
|
-
"decimal",
|
|
29
|
-
"negativeInteger",
|
|
30
|
-
"nonNegativeInteger",
|
|
31
|
-
"positiveInteger",
|
|
32
|
-
"nonPositiveInteger",
|
|
33
|
-
]);
|
|
34
|
-
|
|
35
|
-
const DATE_TYPES = new Set(["dateTime", "date"]);
|
|
36
|
-
|
|
37
|
-
const STRING_TYPES = new Set([
|
|
38
|
-
"string",
|
|
39
|
-
"normalizedString",
|
|
40
|
-
"token",
|
|
41
|
-
"language",
|
|
42
|
-
"Name",
|
|
43
|
-
"NCName",
|
|
44
|
-
"NMTOKEN",
|
|
45
|
-
"ID",
|
|
46
|
-
"IDREF",
|
|
47
|
-
"ENTITY",
|
|
48
|
-
"anyURI",
|
|
49
|
-
"QName",
|
|
50
|
-
"NOTATION",
|
|
51
|
-
"time",
|
|
52
|
-
"duration",
|
|
53
|
-
"gYear",
|
|
54
|
-
"gYearMonth",
|
|
55
|
-
"gMonth",
|
|
56
|
-
"gMonthDay",
|
|
57
|
-
"gDay",
|
|
58
|
-
"base64Binary",
|
|
59
|
-
"hexBinary",
|
|
60
|
-
]);
|
|
61
|
-
|
|
62
|
-
export interface XsdTypeInfo {
|
|
63
|
-
tsType: string;
|
|
64
|
-
/** If true, emitted with a JSDoc precision warning. */
|
|
65
|
-
precisionRisk: boolean;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Strips namespace prefix from an XSD type string.
|
|
70
|
-
* `"xsd:string"` -> `"string"`, `"tns:MyType"` -> `"MyType"`
|
|
71
|
-
*/
|
|
72
|
-
export function stripNamespace(xsdType: string): string {
|
|
73
|
-
const idx = xsdType.indexOf(":");
|
|
74
|
-
return idx >= 0 ? xsdType.slice(idx + 1) : xsdType;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Resolves an XSD primitive type to its TypeScript representation.
|
|
79
|
-
* Returns `null` if the type is not a known primitive (i.e. it's a
|
|
80
|
-
* complex or user-defined type that needs to be looked up elsewhere).
|
|
81
|
-
*/
|
|
82
|
-
export function resolveXsdPrimitive(localName: string): XsdTypeInfo | null {
|
|
83
|
-
if (localName === "boolean") {
|
|
84
|
-
return { tsType: "boolean", precisionRisk: false };
|
|
85
|
-
}
|
|
86
|
-
if (SAFE_NUMBER_TYPES.has(localName)) {
|
|
87
|
-
return { tsType: "number", precisionRisk: false };
|
|
88
|
-
}
|
|
89
|
-
if (PRECISION_RISK_NUMBER_TYPES.has(localName)) {
|
|
90
|
-
return { tsType: "number", precisionRisk: true };
|
|
91
|
-
}
|
|
92
|
-
if (DATE_TYPES.has(localName)) {
|
|
93
|
-
return { tsType: "Date", precisionRisk: false };
|
|
94
|
-
}
|
|
95
|
-
if (STRING_TYPES.has(localName)) {
|
|
96
|
-
return { tsType: "string", precisionRisk: false };
|
|
97
|
-
}
|
|
98
|
-
if (localName === "anyType") {
|
|
99
|
-
return { tsType: "unknown", precisionRisk: false };
|
|
100
|
-
}
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
import * as soap from "soap";
|
|
2
|
-
import { stripNamespace, resolveXsdPrimitive } from "../generator/xsd-types.js";
|
|
3
|
-
|
|
4
|
-
export interface ParsedField {
|
|
5
|
-
name: string;
|
|
6
|
-
/** TypeScript type as a source string (e.g. "string", "number", "MyInterface") */
|
|
7
|
-
tsType: string;
|
|
8
|
-
isArray: boolean;
|
|
9
|
-
isOptional: boolean;
|
|
10
|
-
/** If true, the generated type should include a JSDoc precision warning */
|
|
11
|
-
precisionRisk: boolean;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface ParsedType {
|
|
15
|
-
name: string;
|
|
16
|
-
fields: ParsedField[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface ParsedEnum {
|
|
20
|
-
name: string;
|
|
21
|
-
values: string[];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface ParsedOperation {
|
|
25
|
-
name: string;
|
|
26
|
-
input: ParsedType;
|
|
27
|
-
output: ParsedType;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface ParsedPort {
|
|
31
|
-
name: string;
|
|
32
|
-
operations: ParsedOperation[];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ParsedService {
|
|
36
|
-
name: string;
|
|
37
|
-
ports: ParsedPort[];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface ParsedWsdl {
|
|
41
|
-
services: ParsedService[];
|
|
42
|
-
enums: ParsedEnum[];
|
|
43
|
-
types: ParsedType[];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
type DescribeResult = Record<
|
|
47
|
-
string,
|
|
48
|
-
Record<string, Record<string, Record<string, unknown>>>
|
|
49
|
-
>;
|
|
50
|
-
|
|
51
|
-
interface SchemaFieldInfo {
|
|
52
|
-
name: string;
|
|
53
|
-
type: string;
|
|
54
|
-
minOccurs: string | undefined;
|
|
55
|
-
maxOccurs: string | undefined;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
interface SchemaElementInfo {
|
|
59
|
-
fields: SchemaFieldInfo[];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
type SchemaMap = Map<string, SchemaElementInfo>;
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Walks `client.wsdl.definitions.schemas` to build a lookup map
|
|
66
|
-
* of element/complexType names to their field metadata (type ref,
|
|
67
|
-
* minOccurs, maxOccurs). This gives us data that `describe()` loses.
|
|
68
|
-
*/
|
|
69
|
-
function buildSchemaMap(client: soap.Client): SchemaMap {
|
|
70
|
-
const map: SchemaMap = new Map();
|
|
71
|
-
const wsdl = client.wsdl as unknown as Record<string, unknown>;
|
|
72
|
-
const definitions = wsdl.definitions as Record<string, unknown> | undefined;
|
|
73
|
-
const schemas = definitions?.schemas as
|
|
74
|
-
| Record<string, Record<string, unknown>>
|
|
75
|
-
| undefined;
|
|
76
|
-
|
|
77
|
-
if (!schemas) return map;
|
|
78
|
-
|
|
79
|
-
for (const schema of Object.values(schemas)) {
|
|
80
|
-
extractFromSchemaSection(schema.complexTypes, map);
|
|
81
|
-
extractFromSchemaSection(schema.elements, map);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return map;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Resolves the actual WSDL element names for an operation's input/output
|
|
89
|
-
* by reading from the port's resolved binding. This avoids guessing
|
|
90
|
-
* based on naming conventions (e.g. `${opName}Request`).
|
|
91
|
-
*
|
|
92
|
-
* The soap library attaches the full binding object (with resolved
|
|
93
|
-
* portType methods) directly to each port at
|
|
94
|
-
* `definitions.services[svc].ports[port].binding.methods[op]`.
|
|
95
|
-
*/
|
|
96
|
-
function resolveElementNames(
|
|
97
|
-
client: soap.Client,
|
|
98
|
-
serviceName: string,
|
|
99
|
-
portName: string,
|
|
100
|
-
opName: string,
|
|
101
|
-
): { input: string; output: string } | null {
|
|
102
|
-
try {
|
|
103
|
-
const wsdl = client.wsdl as unknown as Record<string, unknown>;
|
|
104
|
-
const definitions = wsdl.definitions as Record<string, unknown>;
|
|
105
|
-
const services = definitions.services as Record<string, Record<string, unknown>>;
|
|
106
|
-
const svc = services[serviceName];
|
|
107
|
-
const ports = svc?.ports as Record<string, Record<string, unknown>> | undefined;
|
|
108
|
-
const port = ports?.[portName];
|
|
109
|
-
const binding = port?.binding as Record<string, unknown> | undefined;
|
|
110
|
-
const methods = binding?.methods as
|
|
111
|
-
| Record<string, Record<string, unknown>>
|
|
112
|
-
| undefined;
|
|
113
|
-
const method = methods?.[opName];
|
|
114
|
-
const inputEl = method?.input as Record<string, unknown> | undefined;
|
|
115
|
-
const outputEl = method?.output as Record<string, unknown> | undefined;
|
|
116
|
-
const inputName = inputEl?.$name as string | undefined;
|
|
117
|
-
const outputName = outputEl?.$name as string | undefined;
|
|
118
|
-
|
|
119
|
-
if (inputName && outputName) {
|
|
120
|
-
return { input: inputName, output: outputName };
|
|
121
|
-
}
|
|
122
|
-
} catch {
|
|
123
|
-
// fall through
|
|
124
|
-
}
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function extractFromSchemaSection(
|
|
129
|
-
section: unknown,
|
|
130
|
-
map: SchemaMap,
|
|
131
|
-
): void {
|
|
132
|
-
if (!section || typeof section !== "object") return;
|
|
133
|
-
|
|
134
|
-
for (const [name, def] of Object.entries(
|
|
135
|
-
section as Record<string, unknown>,
|
|
136
|
-
)) {
|
|
137
|
-
const fields = extractFields(def);
|
|
138
|
-
if (fields.length > 0) {
|
|
139
|
-
map.set(name, { fields });
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function extractFields(node: unknown): SchemaFieldInfo[] {
|
|
145
|
-
if (!node || typeof node !== "object") return [];
|
|
146
|
-
const obj = node as Record<string, unknown>;
|
|
147
|
-
const children = obj.children as unknown[] | undefined;
|
|
148
|
-
if (!children) return [];
|
|
149
|
-
|
|
150
|
-
const fields: SchemaFieldInfo[] = [];
|
|
151
|
-
for (const child of children) {
|
|
152
|
-
const childObj = child as Record<string, unknown>;
|
|
153
|
-
if (childObj.$name && childObj.$type) {
|
|
154
|
-
fields.push({
|
|
155
|
-
name: childObj.$name as string,
|
|
156
|
-
type: childObj.$type as string,
|
|
157
|
-
minOccurs: childObj.$minOccurs as string | undefined,
|
|
158
|
-
maxOccurs: childObj.$maxOccurs as string | undefined,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
const nested = extractFields(child);
|
|
162
|
-
fields.push(...nested);
|
|
163
|
-
}
|
|
164
|
-
return fields;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function pascalCase(str: string): string {
|
|
168
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Parses an element descriptor from `client.describe()`,
|
|
173
|
-
* cross-referencing with the schema map for type names and optionality.
|
|
174
|
-
*/
|
|
175
|
-
function parseFieldDescriptor(
|
|
176
|
-
fieldName: string,
|
|
177
|
-
descriptor: unknown,
|
|
178
|
-
collectedTypes: Map<string, ParsedType>,
|
|
179
|
-
collectedEnums: Map<string, ParsedEnum>,
|
|
180
|
-
schemaMap: SchemaMap,
|
|
181
|
-
parentSchemaInfo: SchemaElementInfo | undefined,
|
|
182
|
-
): ParsedField {
|
|
183
|
-
const isArray = fieldName.endsWith("[]");
|
|
184
|
-
const cleanName = isArray ? fieldName.slice(0, -2) : fieldName;
|
|
185
|
-
|
|
186
|
-
const schemaField = parentSchemaInfo?.fields.find(
|
|
187
|
-
(f) => f.name === cleanName,
|
|
188
|
-
);
|
|
189
|
-
const isOptional = schemaField?.minOccurs === "0";
|
|
190
|
-
|
|
191
|
-
if (typeof descriptor === "string") {
|
|
192
|
-
const enumMatch = descriptor.match(/^(\w+)\|[^|]+\|(.+)$/);
|
|
193
|
-
if (enumMatch) {
|
|
194
|
-
const enumName = enumMatch[1];
|
|
195
|
-
const values = enumMatch[2].split(",");
|
|
196
|
-
if (!collectedEnums.has(enumName)) {
|
|
197
|
-
collectedEnums.set(enumName, { name: enumName, values });
|
|
198
|
-
}
|
|
199
|
-
return {
|
|
200
|
-
name: cleanName,
|
|
201
|
-
tsType: enumName,
|
|
202
|
-
isArray,
|
|
203
|
-
isOptional,
|
|
204
|
-
precisionRisk: false,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const localName = stripNamespace(descriptor);
|
|
209
|
-
const primitive = resolveXsdPrimitive(localName);
|
|
210
|
-
if (primitive) {
|
|
211
|
-
return {
|
|
212
|
-
name: cleanName,
|
|
213
|
-
tsType: primitive.tsType,
|
|
214
|
-
isArray,
|
|
215
|
-
isOptional,
|
|
216
|
-
precisionRisk: primitive.precisionRisk,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return {
|
|
221
|
-
name: cleanName,
|
|
222
|
-
tsType: localName,
|
|
223
|
-
isArray,
|
|
224
|
-
isOptional,
|
|
225
|
-
precisionRisk: false,
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (typeof descriptor === "object" && descriptor !== null) {
|
|
230
|
-
let typeName: string;
|
|
231
|
-
|
|
232
|
-
if (schemaField?.type) {
|
|
233
|
-
const localTypeName = stripNamespace(schemaField.type);
|
|
234
|
-
typeName = pascalCase(localTypeName);
|
|
235
|
-
} else {
|
|
236
|
-
typeName = pascalCase(cleanName);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (!collectedTypes.has(typeName)) {
|
|
240
|
-
// BUG 1 FIX: insert placeholder BEFORE recursing to prevent
|
|
241
|
-
// infinite recursion on self-referencing types (e.g. TreeNode)
|
|
242
|
-
const placeholder: ParsedType = { name: typeName, fields: [] };
|
|
243
|
-
collectedTypes.set(typeName, placeholder);
|
|
244
|
-
|
|
245
|
-
const nestedSchemaInfo = schemaMap.get(typeName) ?? schemaMap.get(cleanName);
|
|
246
|
-
const fields = parseObjectDescriptor(
|
|
247
|
-
descriptor as Record<string, unknown>,
|
|
248
|
-
collectedTypes,
|
|
249
|
-
collectedEnums,
|
|
250
|
-
schemaMap,
|
|
251
|
-
nestedSchemaInfo,
|
|
252
|
-
);
|
|
253
|
-
placeholder.fields = fields;
|
|
254
|
-
}
|
|
255
|
-
return {
|
|
256
|
-
name: cleanName,
|
|
257
|
-
tsType: typeName,
|
|
258
|
-
isArray,
|
|
259
|
-
isOptional,
|
|
260
|
-
precisionRisk: false,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
return {
|
|
265
|
-
name: cleanName,
|
|
266
|
-
tsType: "unknown",
|
|
267
|
-
isArray,
|
|
268
|
-
isOptional,
|
|
269
|
-
precisionRisk: false,
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
function parseObjectDescriptor(
|
|
274
|
-
obj: Record<string, unknown>,
|
|
275
|
-
collectedTypes: Map<string, ParsedType>,
|
|
276
|
-
collectedEnums: Map<string, ParsedEnum>,
|
|
277
|
-
schemaMap: SchemaMap,
|
|
278
|
-
parentSchemaInfo: SchemaElementInfo | undefined,
|
|
279
|
-
): ParsedField[] {
|
|
280
|
-
const fields: ParsedField[] = [];
|
|
281
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
282
|
-
if (key.startsWith("$") || key === "targetNSAlias" || key === "targetNamespace") {
|
|
283
|
-
continue;
|
|
284
|
-
}
|
|
285
|
-
fields.push(
|
|
286
|
-
parseFieldDescriptor(
|
|
287
|
-
key,
|
|
288
|
-
value,
|
|
289
|
-
collectedTypes,
|
|
290
|
-
collectedEnums,
|
|
291
|
-
schemaMap,
|
|
292
|
-
parentSchemaInfo,
|
|
293
|
-
),
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
return fields;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Picks a unique type name for an operation's input/output.
|
|
301
|
-
* If the base name already exists in collectedTypes, prefixes
|
|
302
|
-
* with the port name to disambiguate (BUG 2 FIX).
|
|
303
|
-
*/
|
|
304
|
-
function uniqueTypeName(
|
|
305
|
-
baseName: string,
|
|
306
|
-
portName: string,
|
|
307
|
-
collectedTypes: Map<string, ParsedType>,
|
|
308
|
-
): string {
|
|
309
|
-
if (!collectedTypes.has(baseName)) {
|
|
310
|
-
return baseName;
|
|
311
|
-
}
|
|
312
|
-
return `${portName}${baseName}`;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Loads a WSDL file (local path or URL) and returns a normalized IR
|
|
317
|
-
* representing all services, ports, operations, and types.
|
|
318
|
-
*/
|
|
319
|
-
export async function parseWsdl(wsdlPath: string): Promise<ParsedWsdl> {
|
|
320
|
-
const client = await soap.createClientAsync(wsdlPath);
|
|
321
|
-
const description = client.describe() as DescribeResult;
|
|
322
|
-
const schemaMap = buildSchemaMap(client);
|
|
323
|
-
const collectedTypes = new Map<string, ParsedType>();
|
|
324
|
-
const collectedEnums = new Map<string, ParsedEnum>();
|
|
325
|
-
const services: ParsedService[] = [];
|
|
326
|
-
|
|
327
|
-
for (const [serviceName, serviceDesc] of Object.entries(description)) {
|
|
328
|
-
const ports: ParsedPort[] = [];
|
|
329
|
-
|
|
330
|
-
for (const [portName, portDesc] of Object.entries(serviceDesc)) {
|
|
331
|
-
const operations: ParsedOperation[] = [];
|
|
332
|
-
|
|
333
|
-
for (const [opName, opDesc] of Object.entries(portDesc)) {
|
|
334
|
-
const opObj = opDesc as Record<string, Record<string, unknown>>;
|
|
335
|
-
const inputDesc = opObj.input ?? {};
|
|
336
|
-
const outputDesc = opObj.output ?? {};
|
|
337
|
-
|
|
338
|
-
// BUG 3 FIX: resolve actual element names from the port's binding
|
|
339
|
-
// instead of guessing based on naming conventions.
|
|
340
|
-
const elementNames = resolveElementNames(client, serviceName, portName, opName);
|
|
341
|
-
const inputElementName = elementNames?.input ?? `${opName}Request`;
|
|
342
|
-
const outputElementName = elementNames?.output ?? `${opName}Response`;
|
|
343
|
-
|
|
344
|
-
// BUG 2 FIX: if the type name already exists (e.g. same op name
|
|
345
|
-
// in a different port), prefix with the port name.
|
|
346
|
-
const inputTypeName = uniqueTypeName(
|
|
347
|
-
pascalCase(inputElementName),
|
|
348
|
-
portName,
|
|
349
|
-
collectedTypes,
|
|
350
|
-
);
|
|
351
|
-
const outputTypeName = uniqueTypeName(
|
|
352
|
-
pascalCase(outputElementName),
|
|
353
|
-
portName,
|
|
354
|
-
collectedTypes,
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
// BUG 3 FIX: look up schema info by the actual element name
|
|
358
|
-
const inputSchemaInfo =
|
|
359
|
-
schemaMap.get(inputElementName) ?? schemaMap.get(inputTypeName);
|
|
360
|
-
const outputSchemaInfo =
|
|
361
|
-
schemaMap.get(outputElementName) ?? schemaMap.get(outputTypeName);
|
|
362
|
-
|
|
363
|
-
const inputFields = parseObjectDescriptor(
|
|
364
|
-
inputDesc,
|
|
365
|
-
collectedTypes,
|
|
366
|
-
collectedEnums,
|
|
367
|
-
schemaMap,
|
|
368
|
-
inputSchemaInfo,
|
|
369
|
-
);
|
|
370
|
-
const outputFields = parseObjectDescriptor(
|
|
371
|
-
outputDesc,
|
|
372
|
-
collectedTypes,
|
|
373
|
-
collectedEnums,
|
|
374
|
-
schemaMap,
|
|
375
|
-
outputSchemaInfo,
|
|
376
|
-
);
|
|
377
|
-
|
|
378
|
-
const inputType: ParsedType = { name: inputTypeName, fields: inputFields };
|
|
379
|
-
const outputType: ParsedType = { name: outputTypeName, fields: outputFields };
|
|
380
|
-
|
|
381
|
-
collectedTypes.set(inputTypeName, inputType);
|
|
382
|
-
collectedTypes.set(outputTypeName, outputType);
|
|
383
|
-
|
|
384
|
-
operations.push({
|
|
385
|
-
name: opName,
|
|
386
|
-
input: inputType,
|
|
387
|
-
output: outputType,
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
ports.push({ name: portName, operations });
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
services.push({ name: serviceName, ports });
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
return {
|
|
398
|
-
services,
|
|
399
|
-
enums: Array.from(collectedEnums.values()),
|
|
400
|
-
types: Array.from(collectedTypes.values()),
|
|
401
|
-
};
|
|
402
|
-
}
|