11import * as path from "path" ;
2- import { ComplexTypeElement } from "soap/lib/wsdl/elements" ;
2+ import {
3+ AllElement ,
4+ ChoiceElement ,
5+ ComplexContentElement ,
6+ ComplexTypeElement ,
7+ DefinitionsElement ,
8+ ElementElement ,
9+ ExtensionElement ,
10+ SequenceElement ,
11+ SimpleContentElement ,
12+ SimpleTypeElement ,
13+ } from "soap/lib/wsdl/elements" ;
14+ import { splitQName } from "soap/lib/utils" ;
315import { open_wsdl } from "soap/lib/wsdl/index" ;
416import { Definition , Method , ParsedWsdl , Port , Service } from "./models/parsed-wsdl" ;
517import { changeCase } from "./utils/change-case" ;
@@ -12,13 +24,15 @@ interface ParserOptions {
1224 modelNameSuffix : string ;
1325 maxRecursiveDefinitionName : number ;
1426 caseInsensitiveNames : boolean ;
27+ useWsdlTypeNames : boolean ;
1528}
1629
1730const defaultOptions : ParserOptions = {
1831 modelNamePreffix : "" ,
1932 modelNameSuffix : "" ,
2033 maxRecursiveDefinitionName : 64 ,
2134 caseInsensitiveNames : false ,
35+ useWsdlTypeNames : false ,
2236} ;
2337
2438type VisitedDefinition = {
@@ -53,6 +67,60 @@ function toPrimitiveType(type: string): string {
5367 return NODE_SOAP_PARSED_TYPES [ type ] || "string" ;
5468}
5569
70+ type ElementSchema = ElementElement | ComplexTypeElement | SimpleTypeElement ;
71+
72+ function findElementSchemaType ( definitions : DefinitionsElement , element : ElementSchema ) {
73+ if ( ! ( "$type" in element ) && ! ( "$ref" in element ) ) return element ;
74+ const type = element . $type || element . $ref ;
75+ if ( ! type ) return element ;
76+ const { prefix, name : localName } = splitQName ( type ) ;
77+ const ns = element . schemaXmlns [ prefix ] ?? definitions . xmlns [ prefix ] ?? definitions . xmlns [ element . targetNSAlias ] ;
78+ const schema = definitions . schemas [ ns ] ;
79+ if ( ! schema ) return element ;
80+ const typeElement = schema . complexTypes [ localName ] ?? schema . types [ localName ] ;
81+ return typeElement ;
82+ }
83+
84+ function findPropSchemaType (
85+ definitions : DefinitionsElement ,
86+ parentElement : ElementSchema | undefined ,
87+ propName : string
88+ ) : ElementSchema | undefined {
89+ if ( ! parentElement ?. children ) return undefined ;
90+ for ( const child of parentElement . children ) {
91+ if (
92+ child instanceof ChoiceElement ||
93+ child instanceof SequenceElement ||
94+ child instanceof AllElement ||
95+ child instanceof SimpleContentElement ||
96+ child instanceof ComplexContentElement ||
97+ child instanceof ExtensionElement
98+ ) {
99+ return findPropSchemaType ( definitions , child , propName ) ;
100+ }
101+ if ( child . $name === propName ) {
102+ if (
103+ child instanceof ElementElement ||
104+ child instanceof ComplexTypeElement ||
105+ child instanceof SimpleTypeElement
106+ ) {
107+ return findElementSchemaType ( definitions , child ) ;
108+ }
109+ }
110+ }
111+ return undefined ;
112+ }
113+
114+ function getNameFromSchema ( element : ElementSchema | undefined ) {
115+ if ( ! element ) return undefined ;
116+ if ( "$type" in element || "$ref" in element ) {
117+ const type = element . $type || element . $ref ;
118+ const { name : localName } = splitQName ( type ) ;
119+ return localName ;
120+ }
121+ return element . $name ;
122+ }
123+
56124/**
57125 * parse definition
58126 * @param parsedWsdl context of parsed wsdl
@@ -67,7 +135,9 @@ function parseDefinition(
67135 name : string ,
68136 defParts : { [ propNameType : string ] : any } ,
69137 stack : string [ ] ,
70- visitedDefs : Array < VisitedDefinition >
138+ visitedDefs : Array < VisitedDefinition > ,
139+ definitions : DefinitionsElement ,
140+ schema : ElementSchema | undefined
71141) : Definition {
72142 const defName = changeCase ( name , { pascalCase : true } ) ;
73143
@@ -146,13 +216,17 @@ function parseDefinition(
146216 } ) ;
147217 } else {
148218 try {
219+ const propSchema = findPropSchemaType ( definitions , schema , stripedPropName ) ;
220+ const guessPropName = getNameFromSchema ( propSchema ) ?? stripedPropName ;
149221 const subDefinition = parseDefinition (
150222 parsedWsdl ,
151223 options ,
152- stripedPropName ,
224+ guessPropName ,
153225 type ,
154226 [ ...stack , propName ] ,
155- visitedDefs
227+ visitedDefs ,
228+ definitions ,
229+ propSchema
156230 ) ;
157231 definition . properties . push ( {
158232 kind : "REFERENCE" ,
@@ -205,13 +279,17 @@ function parseDefinition(
205279 } ) ;
206280 } else {
207281 try {
282+ const propSchema = findPropSchemaType ( definitions , schema , propName ) ;
283+ const guessPropName = getNameFromSchema ( propSchema ) ?? propName ;
208284 const subDefinition = parseDefinition (
209285 parsedWsdl ,
210286 options ,
211- propName ,
287+ guessPropName ,
212288 type ,
213289 [ ...stack , propName ] ,
214- visitedDefs
290+ visitedDefs ,
291+ definitions ,
292+ propSchema
215293 ) ;
216294 definition . properties . push ( {
217295 kind : "REFERENCE" ,
@@ -300,6 +378,9 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
300378 const type = parsedWsdl . findDefinition (
301379 inputMessage . element . $type ?? inputMessage . element . $name
302380 ) ;
381+ const schema = mergedOptions . useWsdlTypeNames
382+ ? findElementSchemaType ( wsdl . definitions , inputMessage . element )
383+ : undefined ;
303384 inputDefinition =
304385 type ??
305386 parseDefinition (
@@ -308,7 +389,9 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
308389 typeName ,
309390 inputMessage . parts ,
310391 [ typeName ] ,
311- visitedDefinitions
392+ visitedDefinitions ,
393+ wsdl . definitions ,
394+ schema
312395 ) ;
313396 } else if ( inputMessage . parts ) {
314397 const type = parsedWsdl . findDefinition ( requestParamName ) ;
@@ -320,7 +403,9 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
320403 requestParamName ,
321404 inputMessage . parts ,
322405 [ requestParamName ] ,
323- visitedDefinitions
406+ visitedDefinitions ,
407+ wsdl . definitions ,
408+ undefined
324409 ) ;
325410 } else {
326411 Logger . debug (
@@ -340,6 +425,9 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
340425 // TODO: if `$type` not defined, inline type into function declartion (do not create definition file) - wsimport
341426 const typeName = outputMessage . element . $type ?? outputMessage . element . $name ;
342427 const type = parsedWsdl . findDefinition ( typeName ) ;
428+ const schema = mergedOptions . useWsdlTypeNames
429+ ? findElementSchemaType ( wsdl . definitions , outputMessage . element )
430+ : undefined ;
343431 outputDefinition =
344432 type ??
345433 parseDefinition (
@@ -348,7 +436,9 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
348436 typeName ,
349437 outputMessage . parts ,
350438 [ typeName ] ,
351- visitedDefinitions
439+ visitedDefinitions ,
440+ wsdl . definitions ,
441+ schema
352442 ) ;
353443 } else {
354444 const type = parsedWsdl . findDefinition ( responseParamName ) ;
@@ -360,7 +450,9 @@ export async function parseWsdl(wsdlPath: string, options: Partial<ParserOptions
360450 responseParamName ,
361451 outputMessage . parts ,
362452 [ responseParamName ] ,
363- visitedDefinitions
453+ visitedDefinitions ,
454+ wsdl . definitions ,
455+ undefined
364456 ) ;
365457 }
366458 }
0 commit comments