Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wsdl-tsclient",
"version": "1.3.1",
"name": "@teamcodafication/wsdl-tsclient",
"version": "1.3.1-codafication",
"description": "Generate typescript soap client with typescript definitons from WSDL file.",
"main": "dist/src/index.js",
"bin": {
Expand All @@ -16,15 +16,15 @@
"test:node-soap2": "ts-node node_modules/tape/bin/tape ./test/node-soap/**/*.test.ts | tap-spec",
"test:public": "ts-node node_modules/tape/bin/tape ./test/resources-public/**/*.test.ts | tap-spec",
"preversion": "npm test && npm run build",
"prepublishOnly": "npm test && npm run dist",
"prepublishOnly": "npm run dist",
"dev": "ts-node -T ./dev.ts",
"dist": "tsc",
"build": "tsc",
"format": "npx prettier --write ./src"
},
"repository": {
"type": "git",
"url": "git+https://github.com/dderevjanik/wsdl-tsclient.git"
"url": "git+https://github.com/Codafication/wsdl-tsclient.git"
},
"keywords": [
"soap",
Expand Down Expand Up @@ -59,4 +59,4 @@
"ts-morph": "^11.0.0",
"yargs": "^16.2.0"
}
}
}
13 changes: 11 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const conf = yargs(process.argv.slice(2))
})
.option("caseInsensitiveNames", {
type: "boolean",
description: "Case-insensitive name while parsing definition names"
description: "Case-insensitive name while parsing definition names",
})
.option("maxRecursiveDefinitionName", {
type: "number",
Expand All @@ -50,6 +50,11 @@ const conf = yargs(process.argv.slice(2))
.option("no-color", {
type: "boolean",
description: "Logs without colors",
})
.option("skipChangeCase", {
type: "boolean",
default: "false",
description: "Skip change case",
}).argv;

// Logger section
Expand Down Expand Up @@ -93,6 +98,10 @@ if (conf.caseInsensitiveNames) {
options.caseInsensitiveNames = conf.caseInsensitiveNames;
}

if (conf.skipChangeCase) {
options.skipChangeCase = true;
}

Logger.debug("Options");
Logger.debug(JSON.stringify(options, null, 2));

Expand Down Expand Up @@ -135,4 +144,4 @@ if (conf._ === undefined || conf._.length === 0) {
process.exit(1);
}
}
})();
})();
6 changes: 4 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ export interface Options {
modelNameSuffix: string;
caseInsensitiveNames: boolean;
maxRecursiveDefinitionName: number;
skipChangeCase: boolean;
}

export const defaultOptions: Options = {
emitDefinitionsOnly: false,
modelNamePreffix: "",
modelNameSuffix: "",
caseInsensitiveNames: false,
maxRecursiveDefinitionName: 64
maxRecursiveDefinitionName: 64,
skipChangeCase: false,
};

export async function parseAndGenerate(
Expand All @@ -43,4 +45,4 @@ export async function parseAndGenerate(
Logger.debug(`Generator time: ${timeElapsed(process.hrtime(timeGenerateStart))}ms`);

Logger.info(`Generating finished: ${timeElapsed(process.hrtime(timeParseStart))}ms`);
}
}
74 changes: 38 additions & 36 deletions src/parser.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Options } from "./index";
import * as path from "path";
import { ComplexTypeElement } from "soap/lib/wsdl/elements";
import { open_wsdl } from "soap/lib/wsdl/index";
Expand All @@ -7,16 +8,15 @@ import { stripExtension } from "./utils/file";
import { reservedKeywords } from "./utils/javascript";
import { Logger } from "./utils/logger";

interface ParserOptions {
modelNamePreffix: string;
modelNameSuffix: string;
maxRecursiveDefinitionName: number;
}

const defaultOptions: ParserOptions = {
modelNamePreffix: "",
modelNameSuffix: "",
maxRecursiveDefinitionName: 64
const typeMapping: Record<string, string> = {
"xs:string": "string",
"xs:decimal": "number",
"xs:double": "number",
"xs:integer": "number",
"xs:int": "number",
"xs:boolean": "boolean",
"xs:date": "string",
"xs:time": "string",
};

type VisitedDefinition = {
Expand All @@ -39,25 +39,27 @@ function findReferenceDefiniton(visited: Array<VisitedDefinition>, definitionPar
*/
function parseDefinition(
parsedWsdl: ParsedWsdl,
options: ParserOptions,
options: Options,
name: string,
defParts: { [propNameType: string]: any },
stack: string[],
visitedDefs: Array<VisitedDefinition>
): Definition {
const defName = changeCase(name, { pascalCase: true });
const defName = changeCase(name, options.skipChangeCase, { pascalCase: true });
Logger.debug(`Parsing Definition ${stack.join(".")}.${name}`);

let nonCollisionDefName: string;
try {
nonCollisionDefName = parsedWsdl.findNonCollisionDefinitionName(defName);
} catch (err) {
const e = new Error(`Error for finding non-collision definition name for ${stack.join(".")}.${name}`);
e.stack.split('\n').slice(0,2).join('\n') + '\n' + err.stack;
e.stack.split("\n").slice(0, 2).join("\n") + "\n" + err.stack;
throw e;
}
const definition: Definition = {
name: `${options.modelNamePreffix}${changeCase(nonCollisionDefName, { pascalCase: true })}${options.modelNameSuffix}`,
name: `${options.modelNamePreffix}${changeCase(nonCollisionDefName, options.skipChangeCase, {
pascalCase: true,
})}${options.modelNameSuffix}`,
sourceName: name,
docs: [name],
properties: [],
Expand All @@ -68,7 +70,7 @@ function parseDefinition(
visitedDefs.push({ name: definition.name, parts: defParts, definition }); // NOTE: cache reference to this defintion globally (for avoiding circular references)
if (defParts) {
// NOTE: `node-soap` has sometimes problem with parsing wsdl files, it includes `defParts.undefined = undefined`
if (("undefined" in defParts) && (defParts.undefined === undefined)) {
if ("undefined" in defParts && defParts.undefined === undefined) {
// TODO: problem while parsing WSDL, maybe report to node-soap
// TODO: add flag --FailOnWsdlError
Logger.error({
Expand All @@ -92,7 +94,7 @@ function parseDefinition(
name: stripedPropName,
sourceName: propName,
description: type,
type: "string",
type: typeMapping[type] || "string",
isArray: true,
});
} else if (type instanceof ComplexTypeElement) {
Expand All @@ -103,7 +105,7 @@ function parseDefinition(
sourceName: propName,
description: "ComplexType are not supported yet",
type: "any",
isArray: true
isArray: true,
});
Logger.warn(`Cannot parse ComplexType '${stack.join(".")}.${name}' - using 'any' type`);
} else {
Expand Down Expand Up @@ -136,8 +138,10 @@ function parseDefinition(
isArray: true,
});
} catch (err) {
const e = new Error(`Error while parsing Subdefinition for '${stack.join(".")}.${name}'`);
e.stack.split('\n').slice(0,2).join('\n') + '\n' + err.stack;
const e = new Error(
`Error while parsing Subdefinition for '${stack.join(".")}.${name}'`
);
e.stack.split("\n").slice(0, 2).join("\n") + "\n" + err.stack;
throw e;
}
}
Expand All @@ -150,7 +154,7 @@ function parseDefinition(
name: propName,
sourceName: propName,
description: type,
type: "string",
type: typeMapping[type] || "string",
isArray: false,
});
} else if (type instanceof ComplexTypeElement) {
Expand All @@ -161,7 +165,7 @@ function parseDefinition(
sourceName: propName,
description: "ComplexType are not supported yet",
type: "any",
isArray: false
isArray: false,
});
Logger.warn(`Cannot parse ComplexType '${stack.join(".")}.${name}' - using 'any' type`);
} else {
Expand Down Expand Up @@ -196,7 +200,7 @@ function parseDefinition(
});
} catch (err) {
const e = new Error(`Error while parsing Subdefinition for ${stack.join(".")}.${name}`);
e.stack.split('\n').slice(0,2).join('\n') + '\n' + err.stack;
e.stack.split("\n").slice(0, 2).join("\n") + "\n" + err.stack;
throw e;
}
}
Expand All @@ -216,11 +220,7 @@ function parseDefinition(
* Parse WSDL to domain model `ParsedWsdl`
* @param wsdlPath - path or url to wsdl file
*/
export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions>): Promise<ParsedWsdl> {
const mergedOptions: ParserOptions = {
...defaultOptions,
...options
};
export async function parseWsdl(wsdlPath: string, options: Options): Promise<ParsedWsdl> {
return new Promise((resolve, reject) => {
open_wsdl(wsdlPath, function (err, wsdl) {
if (err) {
Expand All @@ -232,7 +232,7 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions

const parsedWsdl = new ParsedWsdl({ maxStack: options.maxRecursiveDefinitionName });
const filename = path.basename(wsdlPath);
parsedWsdl.name = changeCase(stripExtension(filename), {
parsedWsdl.name = changeCase(stripExtension(filename), options.skipChangeCase, {
pascalCase: true,
});
parsedWsdl.wsdlFilename = path.basename(filename);
Expand Down Expand Up @@ -272,7 +272,7 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
? type
: parseDefinition(
parsedWsdl,
mergedOptions,
options,
typeName,
inputMessage.parts,
[typeName],
Expand All @@ -284,14 +284,16 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
? type
: parseDefinition(
parsedWsdl,
mergedOptions,
options,
paramName,
inputMessage.parts,
[paramName],
visitedDefinitions
);
} else {
Logger.debug(`Method '${serviceName}.${portName}.${methodName}' doesn't have any input defined`);
Logger.debug(
`Method '${serviceName}.${portName}.${methodName}' doesn't have any input defined`
);
}
}

Expand All @@ -306,7 +308,7 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
? type
: parseDefinition(
parsedWsdl,
mergedOptions,
options,
typeName,
outputMessage.parts,
[typeName],
Expand All @@ -318,7 +320,7 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
? type
: parseDefinition(
parsedWsdl,
mergedOptions,
options,
paramName,
outputMessage.parts,
[paramName],
Expand All @@ -341,7 +343,7 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
}

const servicePort: Port = {
name: changeCase(portName, { pascalCase: true }),
name: changeCase(portName, options.skipChangeCase, { pascalCase: true }),
sourceName: portName,
methods: portMethods,
};
Expand All @@ -350,7 +352,7 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
} // End of Port cycle

services.push({
name: changeCase(serviceName, { pascalCase: true }),
name: changeCase(serviceName, options.skipChangeCase, { pascalCase: true }),
sourceName: serviceName,
ports: servicePorts,
});
Expand All @@ -362,4 +364,4 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
return resolve(parsedWsdl);
});
});
}
}
9 changes: 4 additions & 5 deletions src/utils/change-case.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import camelcase from "camelcase";

export function changeCase(input: string, options?: camelcase.Options) {
if (!options?.pascalCase) {
return input.replace(/\./g, ""); // need to remove dots in the input string, otherwise, code generation fails
}
export function changeCase(input: string, skip = false, options?: camelcase.Options) {
if (skip) return input;
else if (!options?.pascalCase) return input.replace(/\./g, ""); // need to remove dots in the input string, otherwise, code generation fails
return camelcase(input, options);
}
}