Skip to content

Commit

Permalink
Add oneof/anyof support to PowerShell client generator (#6361)
Browse files Browse the repository at this point in the history
* add oneof/anyof support to powershell client gen

* fix tests
  • Loading branch information
wing328 authored May 19, 2020
1 parent 096b8f8 commit 5fe34fb
Show file tree
Hide file tree
Showing 18 changed files with 873 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ public void processOpts() {
}

if (additionalProperties.containsKey("commonVerbs")) {
String[] entries = ((String)additionalProperties.get("commonVerbs")).split(":");
String[] entries = ((String) additionalProperties.get("commonVerbs")).split(":");
for (String entry : entries) {
String[] pair = entry.split("=");
if (pair.length == 2) {
Expand Down Expand Up @@ -617,7 +617,7 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("Out-DebugParameter.mustache", infrastructureFolder + File.separator + "Private" + File.separator, "Out-DebugParameter.ps1"));
supportingFiles.add(new SupportingFile("http_signature_auth.mustache", infrastructureFolder + "Private", apiNamePrefix + "HttpSignatureAuth.ps1"));
supportingFiles.add(new SupportingFile("rsa_provider.mustache", infrastructureFolder + "Private", apiNamePrefix + "RSAEncryptionProvider.cs"));


// en-US
supportingFiles.add(new SupportingFile("about_Org.OpenAPITools.help.txt.mustache", infrastructureFolder + File.separator + "en-US" + File.separator + "about_" + packageName + ".help.txt"));
Expand All @@ -629,7 +629,7 @@ public void processOpts() {
@SuppressWarnings("static-method")
@Override
public String escapeText(String input) {

if (input == null) {
return input;
}
Expand All @@ -646,9 +646,9 @@ public String escapeText(String input) {
.replaceAll("[\\t\\n\\r]", " ")
.replace("\\", "\\\\")
.replace("\"", "\"\""));

}

@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("#>", "#_>").replace("<#", "<_#");
Expand Down Expand Up @@ -857,6 +857,26 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
}
}

// check if return type is oneOf/anyeOf model
for (CodegenOperation op : operationList) {
if (op.returnType != null) {
// look up the model to see if it's anyOf/oneOf
if (modelMaps.containsKey(op.returnType) && modelMaps.get(op.returnType) != null) {
CodegenModel cm = modelMaps.get(op.returnType);

if (cm.oneOf != null && !cm.oneOf.isEmpty()) {
op.vendorExtensions.put("x-ps-return-type-one-of", true);
}

if (cm.anyOf != null && !cm.anyOf.isEmpty()) {
op.vendorExtensions.put("x-ps-return-type-any-of", true);
}
} else {
//LOGGER.error("cannot lookup model " + op.returnType);
}
}
}

return objs;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@ function {{{vendorExtensions.x-powershell-method-name}}} {
-CookieParameters $LocalVarCookieParameters `
-ReturnType "{{#returnType}}{{{.}}}{{/returnType}}"

{{#vendorExtensions.x-ps-return-type-one-of}}
# process oneOf response
$LocalVarResult["Response"] = ConvertFrom-{{apiNamePrefix}}JsonTo{{returnType}} (ConvertTo-Json $LocalVarResult["Response"])

{{/vendorExtensions.x-ps-return-type-one-of}}
{{#vendorExtensions.x-ps-return-type-any-of}}
# process anyOf response
$LocalVarResult["Response"] = ConvertFrom-{{apiNamePrefix}}JsonTo{{returnType}} (ConvertTo-Json $LocalVarResult["Response"])

{{/vendorExtensions.x-ps-return-type-any-of}}
if ($WithHttpInfo.IsPresent) {
return $LocalVarResult
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ function Invoke-{{{apiNamePrefix}}}ApiClient {
$RequestBody = $Body
}

# http signature authentication
{{#hasHttpSignatureMethods}}
# http signature authentication
if ($null -ne $Configuration['ApiKey'] -and $Configuration['ApiKey'].Count -gt 0) {
$httpSignHeaderArgument = @{
Method = $Method
Expand All @@ -104,6 +105,7 @@ function Invoke-{{{apiNamePrefix}}}ApiClient {
}
}

{{/hasHttpSignatureMethods}}
if ($SkipCertificateCheck -eq $true) {
$Response = Invoke-WebRequest -Uri $UriBuilder.Uri `
-Method $Method `
Expand Down
Original file line number Diff line number Diff line change
@@ -1,107 +1,6 @@
{{> partial_header}}
{{#models}}
{{#model}}
<#
.SYNOPSIS

{{#summary}}{{{.}}}{{/summary}}{{^summary}}No summary available.{{/summary}}

.DESCRIPTION

{{#description}}{{{description}}}{{/description}}{{^description}}No description available.{{/description}}

{{#allVars}}
.PARAMETER {{{name}}}
{{#description}}{{{description}}}{{/description}}{{^description}}No description available.{{/description}}

{{/allVars}}
.OUTPUTS

{{{classname}}}<PSCustomObject>
#>

function Initialize-{{{apiNamePrefix}}}{{{classname}}} {
[CmdletBinding()]
Param (
{{#allVars}}
[Parameter(Position = {{vendorExtensions.x-index}}, ValueFromPipelineByPropertyName = $true)]
{{#pattern}}
[ValidatePattern("{{{.}}}")]
{{/pattern}}
{{#isEnum}}
{{#allowableValues}}
[ValidateSet({{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}})]
{{/allowableValues}}
{{/isEnum}}
[{{vendorExtensions.x-powershell-data-type}}]
{{=<% %>=}}
${<%name%>}<%^-last%>,<%/-last%>
<%={{ }}=%>
{{/allVars}}
)

Process {
'Creating PSCustomObject: {{{packageName}}} => {{{apiNamePrefix}}}{{{classname}}}' | Write-Debug
$PSBoundParameters | Out-DebugParameter | Write-Debug
{{#vars}}
{{^isNullable}}
{{#required}}
if (!${{{name}}}) {
throw "invalid value for '{{{name}}}', '{{{name}}}' cannot be null."
}

{{/required}}
{{/isNullable}}
{{#hasValidation}}
{{#maxLength}}
if ({{^required}}!${{{name}}} -and {{/required}}${{{name}}}.length -gt {{{maxLength}}}) {
throw "invalid value for '{{{name}}}', the character length must be smaller than or equal to {{{maxLength}}}."
}

{{/maxLength}}
{{#minLength}}
if ({{^required}}!${{{name}}} -and {{/required}}${{{name}}}.length -lt {{{minLength}}}) {
throw "invalid value for '{{{name}}}', the character length must be great than or equal to {{{minLength}}}."
}

{{/minLength}}
{{#maximum}}
if ({{^required}}!${{{name}}} -and {{/required}}${{{name}}} {{#exclusiveMaximum}}-ge{{/exclusiveMaximum}}{{^exclusiveMaximum}}-gt{{/exclusiveMaximum}} {{{maximum}}}) {
throw "invalid value for '{{{name}}}', must be smaller than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}{{{maximum}}}."
}

{{/maximum}}
{{#minimum}}
if ({{^required}}!${{{name}}} -and {{/required}}${{{name}}} {{#exclusiveMinimum}}-le{{/exclusiveMinimum}}{{^exclusiveMinimum}}-lt{{/exclusiveMinimum}} {{{minimum}}}) {
throw "invalid value for '{{{name}}}', must be greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}{{{minimum}}}."
}

{{/minimum}}
{{#maxItems}}
if ({{^required}}!${{{name}}} -and {{/required}}${{{name}}}.length -gt {{{maxItems}}}) {
throw "invalid value for '{{{name}}}', number of items must be less than or equal to {{{maxItems}}}."
}

{{/maxItems}}
{{#minItems}}
if ({{^required}}!${{{name}}} -and {{/required}}${{{name}}}.length -lt {{{minItems}}}) {
throw "invalid value for '{{{name}}}', number of items must be greater than or equal to {{{minItems}}}."
}

{{/minItems}}
{{/hasValidation}}
{{/vars}}
$PSO = [PSCustomObject]@{
{{=<< >>=}}
<<#allVars>>
"<<baseName>>" = ${<<name>>}
<</allVars>>
<<={{ }}=>>
}

return $PSO
}
}
{{#oneOf}}{{#-first}}{{>model_oneof}}{{/-first}}{{/oneOf}}{{^oneOf}}{{#anyOf}}{{#-first}}{{>model_anyof}}{{/-first}}{{/anyOf}}{{^anyOf}}{{>model_simple}}{{/anyOf}}{{/oneOf}}
{{/model}}
{{/models}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<#
.SYNOPSIS

{{#summary}}{{{.}}}{{/summary}}{{^summary}}No summary available.{{/summary}}

.DESCRIPTION

{{#description}}{{{description}}}{{/description}}{{^description}}No description available.{{/description}}

.PARAMETER Json

JSON object

.OUTPUTS

{{{classname}}}<PSCustomObject>
#>
function ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{classname}}} {
[CmdletBinding()]
Param (
[AllowEmptyString()]
[string]$Json
)
Process {
$match = 0
$matchType = $null
$matchInstance = $null
{{#anyOf}}
if ($match -ne 0) { # no match yet
# try to match {{{.}}} defined in the anyOf schemas
try {
$matchInstance = ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{.}}} $Json

foreach($property in $matchInstance.PsObject.Properties) {
if ($null -ne $property.Value) {
$matchType = "Dog"
$match++
break
}
}
} catch {
# fail to match the schema defined in anyOf, proceed to the next one
}
}

{{/anyOf}}
if ($match -eq 1) {
return [PSCustomObject]@{
"ActualType" = ${matchType}
"ActualInstance" = ${matchInstance}
"anyOfSchemas" = @({{#anyOf}}"{{{.}}}"{{^-last}}, {{/-last}}{{/anyOf}})
}
} else {
throw "Error! The JSON payload doesn't matches any type defined in anyOf schemas ({{{anyOf}}}). JSON Payload: $($Json)"
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<#
.SYNOPSIS

{{#summary}}{{{.}}}{{/summary}}{{^summary}}No summary available.{{/summary}}

.DESCRIPTION

{{#description}}{{{description}}}{{/description}}{{^description}}No description available.{{/description}}

.PARAMETER Json

JSON object

.OUTPUTS

{{{classname}}}<PSCustomObject>
#>
function ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{classname}}} {
[CmdletBinding()]
Param (
[AllowEmptyString()]
[string]$Json
)
Process {
$match = 0
$matchType = $null
$matchInstance = $null
{{#oneOf}}
# try to match {{{.}}} defined in the oneOf schemas
try {
$matchInstance = ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{.}}} $Json

foreach($property in $matchInstance.PsObject.Properties) {
if ($null -ne $property.Value) {
$matchType = "Dog"
$match++
break
}
}
} catch {
# fail to match the schema defined in oneOf, proceed to the next one
}

{{/oneOf}}
if ($match -gt 1) {
throw "Error! The JSON payload matches more than one type defined in oneOf schemas ({{{oneOf}}}). JSON Payload: $($Json)"
} elseif ($match -eq 1) {
return [PSCustomObject]@{
"ActualType" = ${matchType}
"ActualInstance" = ${matchInstance}
"OneOfSchemas" = @({{#oneOf}}"{{{.}}}"{{^-last}}, {{/-last}}{{/oneOf}})
}
} else {
throw "Error! The JSON payload doesn't matches any type defined in oneOf schemas ({{{oneOf}}}). JSON Payload: $($Json)"
}
}
}

Loading

0 comments on commit 5fe34fb

Please sign in to comment.