wsdl-to-ts
Advanced tools
Comparing version 0.1.1 to 0.1.2
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const soap = require("soap"); | ||
// import { diffLines } from "diff"; | ||
exports.nsEnums = {}; | ||
function wsdlTypeToInterfaceObj(obj) { | ||
class TypeCollector { | ||
constructor(ns) { | ||
this.ns = ns; | ||
this.registered = {}; | ||
this.collected = {}; | ||
} | ||
registerCollected() { | ||
for (const k of Object.keys(this.collected)) { | ||
if (this.collected[k]) { | ||
this.registered[k] = this.collected[k]; | ||
} | ||
else { | ||
delete this.registered[k]; | ||
} | ||
delete this.collected[k]; | ||
} | ||
return this; | ||
} | ||
} | ||
exports.TypeCollector = TypeCollector; | ||
function wsdlTypeToInterfaceObj(obj, typeCollector) { | ||
const r = {}; | ||
@@ -30,3 +51,8 @@ for (const k of Object.keys(obj)) { | ||
if (isArray) { | ||
typeClass = "Array<" + typeClass + ">"; | ||
if (/^[A-Za-z0-9\.]+$/.test(typeClass)) { | ||
typeClass += "[]"; | ||
} | ||
else { | ||
typeClass = "Array<" + typeClass + ">"; | ||
} | ||
} | ||
@@ -36,6 +62,20 @@ r[k2] = "/** " + typeFullName + "(" + typeData + ") */ " + typeClass + ";"; | ||
else { | ||
const to = wsdlTypeToInterfaceObj(v); | ||
const to = wsdlTypeToInterfaceObj(v, typeCollector); | ||
let tr; | ||
if (isArray) { | ||
let s = wsdlTypeToInterfaceString(to).replace(/\n/g, "\n "); | ||
let s = wsdlTypeToInterfaceString(to); | ||
if (typeCollector && typeCollector.ns) { | ||
if (typeCollector.registered.hasOwnProperty(k2) && typeCollector.registered[k2] === s) { | ||
s = typeCollector.ns + ".I" + k2 + ";"; | ||
} | ||
else if (typeCollector.collected.hasOwnProperty(k2)) { | ||
if (typeCollector.collected[k2] !== s) { | ||
typeCollector.collected[k2] = null; | ||
} | ||
} | ||
else { | ||
typeCollector.collected[k2] = s; | ||
} | ||
} | ||
s = s.replace(/\n/g, "\n "); | ||
if (s.startsWith("/**")) { | ||
@@ -46,3 +86,9 @@ const i = s.indexOf("*/") + 2; | ||
else { | ||
s = "Array<" + s.trim().replace(/;$/, "") + ">;"; | ||
s = s.trim().replace(/;$/, ""); | ||
if (/^[A-Za-z0-9\.]+$/.test(s)) { | ||
s += "[];"; | ||
} | ||
else { | ||
s = "Array<" + s + ">;"; | ||
} | ||
} | ||
@@ -53,2 +99,16 @@ tr = s; | ||
tr = to; | ||
if (typeCollector && typeCollector.ns) { | ||
const ss = wsdlTypeToInterfaceString(to); | ||
if (typeCollector.registered.hasOwnProperty(k2) && typeCollector.registered[k2] === ss) { | ||
tr = typeCollector.ns + ".I" + k2 + ";"; | ||
} | ||
else if (typeCollector.collected.hasOwnProperty(k2)) { | ||
if (typeCollector.collected[k2] !== ss) { | ||
typeCollector.collected[k2] = null; | ||
} | ||
} | ||
else { | ||
typeCollector.collected[k2] = ss; | ||
} | ||
} | ||
} | ||
@@ -85,4 +145,4 @@ r[k2] = tr; | ||
} | ||
function wsdlTypeToInterface(obj) { | ||
return wsdlTypeToInterfaceString(wsdlTypeToInterfaceObj(obj)); | ||
function wsdlTypeToInterface(obj, typeCollector) { | ||
return wsdlTypeToInterfaceString(wsdlTypeToInterfaceObj(obj, typeCollector)); | ||
} | ||
@@ -104,2 +164,3 @@ function wsdl2ts(wsdlUri) { | ||
methods: {}, | ||
namespaces: {}, | ||
types: {}, | ||
@@ -110,2 +171,3 @@ }; | ||
for (const port of Object.keys(d[service])) { | ||
const collector = new TypeCollector(port + "Types"); | ||
// console.log("-- %s.%s", service, port); | ||
@@ -116,2 +178,3 @@ if (!r.types[service]) { | ||
r.files[service] = {}; | ||
r.namespaces[service] = {}; | ||
} | ||
@@ -122,9 +185,42 @@ if (!r.types[service][port]) { | ||
r.files[service][port] = service + "/" + port; | ||
r.namespaces[service][port] = {}; | ||
} | ||
for (let maxi = 0; maxi < 32; maxi++) { | ||
for (const method of Object.keys(d[service][port])) { | ||
// console.log("---- %s", method); | ||
wsdlTypeToInterface(d[service][port][method].input || {}, collector); | ||
wsdlTypeToInterface(d[service][port][method].output || {}, collector); | ||
} | ||
const reg = cloneObj(collector.registered); | ||
collector.registerCollected(); | ||
const regKeys0 = Object.keys(collector.registered); | ||
const regKeys1 = Object.keys(reg); | ||
if (regKeys0.length === regKeys1.length) { | ||
let noChange = true; | ||
for (const rk of regKeys0) { | ||
if (collector.registered[rk] !== reg[rk]) { | ||
noChange = false; | ||
break; | ||
} | ||
} | ||
if (noChange) { | ||
break; | ||
} | ||
} | ||
if (maxi === 31) { | ||
console.warn("wsdl-to-ts: Aborted nested interface changes"); | ||
} | ||
} | ||
const collectedKeys = Object.keys(collector.registered); | ||
if (collectedKeys.length) { | ||
const ns = r.namespaces[service][port][collector.ns] = {}; | ||
for (const k of collectedKeys) { | ||
ns[k] = "export interface I" + k + " " + collector.registered[k]; | ||
} | ||
} | ||
for (const method of Object.keys(d[service][port])) { | ||
// console.log("---- %s", method); | ||
r.types[service][port]["I" + method + "Input"] = | ||
wsdlTypeToInterface(d[service][port][method].input || {}); | ||
wsdlTypeToInterface(d[service][port][method].input || {}, collector); | ||
r.types[service][port]["I" + method + "Output"] = | ||
wsdlTypeToInterface(d[service][port][method].output || {}); | ||
wsdlTypeToInterface(d[service][port][method].output || {}, collector); | ||
r.methods[service][port][method] = | ||
@@ -167,2 +263,3 @@ "(input: I" + method + "Input, " + | ||
methods: cloneObj(a.methods), | ||
namespaces: cloneObj(a.namespaces), | ||
types: cloneObj(a.types), | ||
@@ -176,2 +273,3 @@ }; | ||
x.types[service] = cloneObj(b.types[service]); | ||
x.namespaces[service] = cloneObj(b.namespaces[service]); | ||
} | ||
@@ -184,2 +282,3 @@ else { | ||
x.types[service][port] = cloneObj(b.types[service][port]); | ||
x.namespaces[service][port] = cloneObj(b.namespaces[service][port]); | ||
} | ||
@@ -194,2 +293,12 @@ else { | ||
} | ||
for (const ns of Object.keys(b.namespaces[service][port])) { | ||
if (!x.namespaces[service][port].hasOwnProperty(ns)) { | ||
x.namespaces[service][port][ns] = cloneObj(b.namespaces[service][port][ns]); | ||
} | ||
else { | ||
for (const nsi of Object.keys(b.namespaces[service][port][ns])) { | ||
x.namespaces[service][port][ns][nsi] = b.namespaces[service][port][ns][nsi]; | ||
} | ||
} | ||
} | ||
} | ||
@@ -222,2 +331,13 @@ } | ||
} | ||
if (a.namespaces[service] && a.namespaces[service][port]) { | ||
for (const ns of Object.keys(a.namespaces[service][port])) { | ||
const ms = []; | ||
for (const nsi of Object.keys(a.namespaces[service][port][ns])) { | ||
ms.push(a.namespaces[service][port][ns][nsi].replace(/\n/g, "\n ")); | ||
} | ||
if (ms.length) { | ||
d.data.push("export namespace " + ns + " {\n " + ms.join("\n ") + "\n}"); | ||
} | ||
} | ||
} | ||
r.push(d); | ||
@@ -224,0 +344,0 @@ } |
{ | ||
"name": "wsdl-to-ts", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "Build TypeScript typings for SOAP WSDL", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
#!/usr/bin/env node | ||
/* tslint:disable:no-var-requires */ | ||
import { rename, writeFile } from "fs"; | ||
@@ -4,0 +6,0 @@ import * as minimist from "minimist"; |
import * as soap from "soap"; | ||
// import { diffLines } from "diff"; | ||
@@ -18,5 +19,29 @@ export const nsEnums: { [k: string]: boolean } = {}; | ||
types: ITwoDown<{ [k: string]: string }>; | ||
namespaces: ITwoDown<{ [k: string]: { [k: string]: string } }>; | ||
} | ||
function wsdlTypeToInterfaceObj(obj: IInterfaceObject): { [k: string]: any } { | ||
export class TypeCollector { | ||
public readonly registered: { [k: string]: string }; | ||
public readonly collected: { [k: string]: string }; | ||
constructor(public readonly ns: string) { | ||
this.registered = {}; | ||
this.collected = {}; | ||
} | ||
public registerCollected() { | ||
for (const k of Object.keys(this.collected)) { | ||
if (this.collected[k]) { | ||
this.registered[k] = this.collected[k]; | ||
} else { | ||
delete this.registered[k]; | ||
} | ||
delete this.collected[k]; | ||
} | ||
return this; | ||
} | ||
} | ||
function wsdlTypeToInterfaceObj(obj: IInterfaceObject, typeCollector?: TypeCollector): { [k: string]: any } { | ||
const r: { [k: string]: any } = {}; | ||
@@ -47,10 +72,26 @@ for (const k of Object.keys(obj)) { | ||
if (isArray) { | ||
typeClass = "Array<" + typeClass + ">"; | ||
if (/^[A-Za-z0-9\.]+$/.test(typeClass)) { | ||
typeClass += "[]"; | ||
} else { | ||
typeClass = "Array<" + typeClass + ">"; | ||
} | ||
} | ||
r[k2] = "/** " + typeFullName + "(" + typeData + ") */ " + typeClass + ";"; | ||
} else { | ||
const to = wsdlTypeToInterfaceObj(v as IInterfaceObject); | ||
const to = wsdlTypeToInterfaceObj(v as IInterfaceObject, typeCollector); | ||
let tr: { [k: string]: any } | string; | ||
if (isArray) { | ||
let s = wsdlTypeToInterfaceString(to).replace(/\n/g, "\n "); | ||
let s = wsdlTypeToInterfaceString(to); | ||
if (typeCollector && typeCollector.ns) { | ||
if (typeCollector.registered.hasOwnProperty(k2) && typeCollector.registered[k2] === s) { | ||
s = typeCollector.ns + ".I" + k2 + ";"; | ||
} else if (typeCollector.collected.hasOwnProperty(k2)) { | ||
if (typeCollector.collected[k2] !== s) { | ||
typeCollector.collected[k2] = null; | ||
} | ||
} else { | ||
typeCollector.collected[k2] = s; | ||
} | ||
} | ||
s = s.replace(/\n/g, "\n "); | ||
@@ -61,3 +102,8 @@ if (s.startsWith("/**")) { | ||
} else { | ||
s = "Array<" + s.trim().replace(/;$/, "") + ">;"; | ||
s = s.trim().replace(/;$/, ""); | ||
if (/^[A-Za-z0-9\.]+$/.test(s)) { | ||
s += "[];"; | ||
} else { | ||
s = "Array<" + s + ">;"; | ||
} | ||
} | ||
@@ -68,2 +114,14 @@ | ||
tr = to; | ||
if (typeCollector && typeCollector.ns) { | ||
const ss = wsdlTypeToInterfaceString(to); | ||
if (typeCollector.registered.hasOwnProperty(k2) && typeCollector.registered[k2] === ss) { | ||
tr = typeCollector.ns + ".I" + k2 + ";"; | ||
} else if (typeCollector.collected.hasOwnProperty(k2)) { | ||
if (typeCollector.collected[k2] !== ss) { | ||
typeCollector.collected[k2] = null; | ||
} | ||
} else { | ||
typeCollector.collected[k2] = ss; | ||
} | ||
} | ||
} | ||
@@ -100,4 +158,4 @@ r[k2] = tr; | ||
function wsdlTypeToInterface(obj: { [k: string]: any }): string { | ||
return wsdlTypeToInterfaceString(wsdlTypeToInterfaceObj(obj)); | ||
function wsdlTypeToInterface(obj: { [k: string]: any }, typeCollector?: TypeCollector): string { | ||
return wsdlTypeToInterfaceString(wsdlTypeToInterfaceObj(obj, typeCollector)); | ||
} | ||
@@ -119,2 +177,3 @@ | ||
methods: {}, | ||
namespaces: {}, | ||
types: {}, | ||
@@ -126,3 +185,5 @@ }; | ||
for (const port of Object.keys(d[service])) { | ||
const collector = new TypeCollector(port + "Types"); | ||
// console.log("-- %s.%s", service, port); | ||
if (!r.types[service]) { | ||
@@ -132,2 +193,3 @@ r.types[service] = {}; | ||
r.files[service] = {}; | ||
r.namespaces[service] = {}; | ||
} | ||
@@ -138,9 +200,48 @@ if (!r.types[service][port]) { | ||
r.files[service][port] = service + "/" + port; | ||
r.namespaces[service][port] = {}; | ||
} | ||
for (let maxi = 0; maxi < 32; maxi++) { | ||
for (const method of Object.keys(d[service][port])) { | ||
// console.log("---- %s", method); | ||
wsdlTypeToInterface(d[service][port][method].input || {}, collector); | ||
wsdlTypeToInterface(d[service][port][method].output || {}, collector); | ||
} | ||
const reg = cloneObj(collector.registered); | ||
collector.registerCollected(); | ||
const regKeys0: string[] = Object.keys(collector.registered); | ||
const regKeys1: string[] = Object.keys(reg); | ||
if (regKeys0.length === regKeys1.length) { | ||
let noChange = true; | ||
for (const rk of regKeys0) { | ||
if (collector.registered[rk] !== reg[rk]) { | ||
noChange = false; | ||
break; | ||
} | ||
} | ||
if (noChange) { | ||
break; | ||
} | ||
} | ||
if (maxi === 31) { | ||
console.warn("wsdl-to-ts: Aborted nested interface changes"); | ||
} | ||
} | ||
const collectedKeys: string[] = Object.keys(collector.registered); | ||
if (collectedKeys.length) { | ||
const ns: { [k: string]: string } = r.namespaces[service][port][collector.ns] = {}; | ||
for (const k of collectedKeys) { | ||
ns[k] = "export interface I" + k + " " + collector.registered[k]; | ||
} | ||
} | ||
for (const method of Object.keys(d[service][port])) { | ||
// console.log("---- %s", method); | ||
r.types[service][port]["I" + method + "Input"] = | ||
wsdlTypeToInterface(d[service][port][method].input || {}); | ||
wsdlTypeToInterface(d[service][port][method].input || {}, collector); | ||
r.types[service][port]["I" + method + "Output"] = | ||
wsdlTypeToInterface(d[service][port][method].output || {}); | ||
wsdlTypeToInterface(d[service][port][method].output || {}, collector); | ||
r.methods[service][port][method] = | ||
@@ -183,2 +284,3 @@ "(input: I" + method + "Input, " + | ||
methods: cloneObj(a.methods), | ||
namespaces: cloneObj(a.namespaces), | ||
types: cloneObj(a.types), | ||
@@ -192,2 +294,3 @@ }; | ||
x.types[service] = cloneObj(b.types[service]); | ||
x.namespaces[service] = cloneObj(b.namespaces[service]); | ||
} else { | ||
@@ -199,2 +302,3 @@ for (const port of Object.keys(b.files[service])) { | ||
x.types[service][port] = cloneObj(b.types[service][port]); | ||
x.namespaces[service][port] = cloneObj(b.namespaces[service][port]); | ||
} else { | ||
@@ -208,2 +312,11 @@ x.files[service][port] = b.files[service][port]; | ||
} | ||
for (const ns of Object.keys(b.namespaces[service][port])) { | ||
if (!x.namespaces[service][port].hasOwnProperty(ns)) { | ||
x.namespaces[service][port][ns] = cloneObj(b.namespaces[service][port][ns]); | ||
} else { | ||
for (const nsi of Object.keys(b.namespaces[service][port][ns])) { | ||
x.namespaces[service][port][ns][nsi] = b.namespaces[service][port][ns][nsi]; | ||
} | ||
} | ||
} | ||
} | ||
@@ -236,2 +349,13 @@ } | ||
} | ||
if (a.namespaces[service] && a.namespaces[service][port]) { | ||
for (const ns of Object.keys(a.namespaces[service][port])) { | ||
const ms: string[] = []; | ||
for (const nsi of Object.keys(a.namespaces[service][port][ns])) { | ||
ms.push(a.namespaces[service][port][ns][nsi].replace(/\n/g, "\n ")); | ||
} | ||
if (ms.length) { | ||
d.data.push("export namespace " + ns + " {\n " + ms.join("\n ") + "\n}"); | ||
} | ||
} | ||
} | ||
r.push(d); | ||
@@ -238,0 +362,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
58635
928