Skip to content

Commit

Permalink
Parameter mappers (Azure#219)
Browse files Browse the repository at this point in the history
* Parameter mappers prototype

* Create parameter mapper names in transformer step

* Add Azure support

* Regenerate

* Use specific operation parameter interface

* Regenerate

* Update ms-rest-js

* Sort parameter mappers by name

* Regenerate

* Cleanup

* fix up imports

* regenerate

* Remove unnecessary gen code

* regenerate
  • Loading branch information
RikkiGibson authored Jul 20, 2018
1 parent 2f51bc0 commit e66db24
Show file tree
Hide file tree
Showing 101 changed files with 3,433 additions and 5,926 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ npm install -g autorest
# Compatibility
This AutoRest extension generates TypeScript code that is compatible with:
```
"ms-rest-azure-js": "~0.11.101",
"ms-rest-js": "~0.16.366"
"ms-rest-azure-js": "~0.11.104",
"ms-rest-js": "~0.16.372"
```

# Usage
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@
"mocha": "^5.0.4",
"mocha-chrome": "^1.0.3",
"moment": "~2.21.0",
"ms-rest-azure-js": "~0.11.101",
"ms-rest-js": "~0.16.366",
"ms-rest-azure-js": "~0.11.104",
"ms-rest-js": "~0.16.372",
"run-sequence": "*",
"should": "5.2.0",
"shx": "^0.2.2",
Expand Down
1 change: 1 addition & 0 deletions src/azure/CodeGeneratorTSa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public override async Task Generate(CodeModel cm)
await Write(modelIndexTemplate, Path.Combine("models", "index.ts"));
var mapperIndexTemplate = new AzureMapperIndexTemplate { Model = codeModel };
await Write(mapperIndexTemplate, Path.Combine("models", "mappers.ts"));
await Write(new ParameterTemplate {Model = codeModel}, Path.Combine("models", "parameters.ts"));

//MethodGroups
if (codeModel.MethodGroupModels.Any())
Expand Down
32 changes: 31 additions & 1 deletion src/azure/Model/CodeModelTSa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using AutoRest.TypeScript.Model;
using Newtonsoft.Json;
using AutoRest.Core.Utilities;
using AutoRest.TypeScript.DSL;

namespace AutoRest.TypeScript.Azure.Model
{
Expand Down Expand Up @@ -76,7 +77,36 @@ public override string ConstructRuntimeImportForModelIndex()

public override string PackageDependencies()
{
return "\"ms-rest-azure-js\": \"~0.11.101\"";
return "\"ms-rest-azure-js\": \"~0.11.104\"";
}

public string GenerateAzureServiceClientImports()
{
TSBuilder builder = new TSBuilder();

builder.ImportAllAs("msRest", "ms-rest-js");

bool usesAzureOptionsType = OptionalParameterTypeForClientConstructor == "AzureServiceClientOptions";
if (usesAzureOptionsType)
{
builder.ImportAllAs("msRestAzure", "ms-rest-azure-js");
}

builder.ImportAllAs("Models", "./models");
builder.ImportAllAs("Mappers", "./models/mappers");

if (HasMappableParameters)
{
builder.ImportAllAs("Parameters", "./models/parameters");
}

if (MethodGroupModels.Any())
{
builder.ImportAllAs("operations", "./operations");
}
builder.Import(new string[] { ContextName }, $"./{ContextName.ToCamelCase()}");

return builder.ToString();
}
}
}
5 changes: 3 additions & 2 deletions src/azure/PluginTSa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public PluginTSa()
// inherit base settings
Context,

// set code model implementations our own implementations
// set code model implementations our own implementations
new Factory<CodeModel, CodeModelTSa>(),
new Factory<Method, MethodTSa>(),
new Factory<CompositeType, CompositeTypeTS>(),
Expand All @@ -25,7 +25,8 @@ public PluginTSa()
new Factory<SequenceType, SequenceTypeTS>(),
new Factory<MethodGroup, MethodGroupTS>(),
new Factory<EnumType, EnumTypeTS>(),
new Factory<PrimaryType, PrimaryTypeTS>()
new Factory<PrimaryType, PrimaryTypeTS>(),
new Factory<Parameter, ParameterTS>()
};
}
}
Expand Down
8 changes: 1 addition & 7 deletions src/azure/Templates/AzureMethodGroupTemplate.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@
@Header(" * ")
*/
@EmptyLine
import * as msRest from "ms-rest-js";
@if (Model.ContainsCompositeOrEnumTypeInParametersOrReturnType())
{
@:import * as Models from "../models";
}
import * as Mappers from "../models/@(Model.MappersModuleName)";
import { @(Model.CodeModelTS.ContextName) } from "../@(Model.CodeModelTS.ContextName.ToCamelCase())";
@(Model.GenerateMethodGroupImports())
@EmptyLine
/** Class representing a @(Model.TypeName). */
export class @(Model.TypeName) {
Expand Down
15 changes: 1 addition & 14 deletions src/azure/Templates/AzureServiceClientTemplate.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,7 @@
@Header(" * ")
*/
@EmptyLine
import * as Models from "./models";
import * as Mappers from "./models/mappers";
import * as msRest from "ms-rest-js";
@{
bool usesAzureOptionsType = Model.OptionalParameterTypeForClientConstructor == "AzureServiceClientOptions";
if (usesAzureOptionsType)
{
@:import * as msRestAzure from "ms-rest-azure-js";
}
}
import { @(Model.ContextName) } from "./@(Model.ContextName.ToCamelCase())";
@if (Model.MethodGroupModels.Any()) {
@:import * as operations from "./operations";
}
@(Model.GenerateAzureServiceClientImports())
@EmptyLine
@{var requiredParameters = Model.Properties.Where(p => p.IsRequired && !p.IsConstant && string.IsNullOrEmpty(p.DefaultValue));}
@{var optionalParameters = Model.Properties.Where(p => (!p.IsRequired || p.IsRequired && !string.IsNullOrEmpty(p.DefaultValue)) && !p.IsConstant && !p.Name.EqualsIgnoreCase("apiVersion"));}
Expand Down
5 changes: 5 additions & 0 deletions src/vanilla/ClientModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,11 @@ private static string CreatePatternConstraintValue(string constraintValue)
return "/" + constraintValue.Replace("/", "\\/") + "/";
}

public static void ConstructParameterMapper(TSObject obj, ParameterTS parameter)
{
MethodTS.GenerateRequestParameter(obj, parameter, parameter.MethodTS.GetParameterTransformations());
}

public static void ConstructRequestBodyMapper(TSValue value, Parameter requestBody)
{
IModelType requestBodyModelType = requestBody.ModelType;
Expand Down
8 changes: 8 additions & 0 deletions src/vanilla/CodeGeneratorTS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ public override async Task Generate(CodeModel cm)
await Write(mapperIndexTemplate, Path.Combine("models", "mappers.ts"));
}

bool serviceHasMappableParameters = codeModel.Methods
.SelectMany(m => m.LogicalParameters)
.Any(p => p.Location != ParameterLocation.Body);
if (serviceHasMappableParameters)
{
await Write(new ParameterTemplate {Model = codeModel}, Path.Combine("models", "parameters.ts"));
}

//MethodGroups
if (codeModel.MethodGroupModels.Any())
{
Expand Down
58 changes: 57 additions & 1 deletion src/vanilla/Model/CodeModelTS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using AutoRest.Core.Utilities;
using AutoRest.Extensions;
using AutoRest.TypeScript.DSL;
using AutoRest.TypeScript;
using Newtonsoft.Json;

namespace AutoRest.TypeScript.Model
Expand Down Expand Up @@ -363,7 +364,7 @@ public virtual string ConstructRuntimeImportForModelIndex()

public virtual string PackageDependencies()
{
return "\"ms-rest-js\": \"~0.16.366\"";
return "\"ms-rest-js\": \"~0.16.372\"";
}

public virtual Method GetSampleMethod()
Expand Down Expand Up @@ -461,6 +462,55 @@ public string GenerateOperationSpecDefinitions(string emptyLine)
return builder.ToString();
}

private sealed class ParameterNameComparer : IEqualityComparer<ParameterTS>
{
private ParameterNameComparer() {}
public static ParameterNameComparer Instance { get; } = new ParameterNameComparer();

public bool Equals(ParameterTS x, ParameterTS y)
{
return x.MapperName == y.MapperName;
}

public int GetHashCode(ParameterTS obj)
{
return obj.MapperName.GetHashCode();
}
}

public bool HasMappableParameters =>
MethodTemplateModels
.SelectMany(m => m.LogicalParameters)
.Any(p => p.Location != ParameterLocation.Body);

public string GenerateParameterMappers()
{
TSBuilder builder = new TSBuilder();
IEnumerable<ParameterTS> parameters = Methods
.SelectMany(m => m.LogicalParameters)
.Cast<ParameterTS>()
.Where(p => p.ModelTypeName != "RequestOptionsBase" && p.Location != ParameterLocation.Body)
.OrderBy(p => p.MapperName)
.Distinct(ParameterNameComparer.Instance);

foreach (ParameterTS parameter in parameters)
{
string parameterInterfaceName =
parameter.Location == ParameterLocation.Path ? "msRest.OperationURLParameter" :
parameter.Location == ParameterLocation.Query ? "msRest.OperationQueryParameter" :
"msRest.OperationParameter";

builder.Text("export ");
builder.ConstObjectVariable(
parameter.MapperName,
parameterInterfaceName,
obj => ClientModelExtensions.ConstructParameterMapper(obj, parameter));
builder.Line();
}

return builder.ToString();
}

public string GenerateServiceClientImports()
{
TSBuilder builder = new TSBuilder();
Expand All @@ -471,6 +521,12 @@ public string GenerateServiceClientImports()
}
builder.ImportAllAs("Models", "./models");
builder.ImportAllAs("Mappers", "./models/mappers");

if (HasMappableParameters)
{
builder.ImportAllAs("Parameters", "./models/parameters");
}

if (MethodGroupModels.Any())
{
builder.ImportAllAs("operations", "./operations");
Expand Down
26 changes: 26 additions & 0 deletions src/vanilla/Model/MethodGroupTS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,31 @@ public string GenerateOperationSpecDefinitions(string emptyLine)

return builder.ToString();
}

public bool HasMappableParameters =>
Methods
.SelectMany(m => m.LogicalParameters)
.Any(p => p.Location != ParameterLocation.Body);

public string GenerateMethodGroupImports()
{
TSBuilder builder = new TSBuilder();

builder.ImportAllAs("msRest", "ms-rest-js");
if (ContainsCompositeOrEnumTypeInParametersOrReturnType())
{
builder.ImportAllAs("Models", "../models");
}
builder.ImportAllAs("Mappers", $"../models/{MappersModuleName}");

if (HasMappableParameters)
{
builder.ImportAllAs("Parameters", "../models/parameters");
}

builder.Import(new string[] { CodeModelTS.ContextName }, $"../{CodeModelTS.ContextName.ToCamelCase()}");

return builder.ToString();
}
}
}
51 changes: 28 additions & 23 deletions src/vanilla/Model/MethodTS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ public string ReturnTypeInfo
}
}

private ParameterTransformations GetParameterTransformations()
internal ParameterTransformations GetParameterTransformations()
=> new ParameterTransformations(InputParameterTransformation);

/// <summary>
Expand Down Expand Up @@ -568,25 +568,16 @@ public void GenerateOperationSpec(TSObject operationSpec)
}

Parameter[] logicalParameters = LogicalParameters.ToArray();
ParameterTransformations parameterTransformations = GetParameterTransformations();

GenerateRequestParameters(operationSpec, "urlParameters", parameterTransformations, logicalParameters.Where(p => p.Location == ParameterLocation.Path), AddSkipEncodingProperty);
GenerateRequestParameters(operationSpec, "queryParameters", parameterTransformations, logicalParameters.Where(p => p.Location == ParameterLocation.Query),
(TSObject queryParameterObject, Parameter queryParameter) =>
{
AddSkipEncodingProperty(queryParameterObject, queryParameter);
if (queryParameter.CollectionFormat != CollectionFormat.None)
{
queryParameterObject.TextProperty("collectionFormat", $"msRest.QueryCollectionFormat.{queryParameter.CollectionFormat}");
}
});
GenerateRequestParameters(operationSpec, "headerParameters", parameterTransformations, logicalParameters.Where(p => p.Location == ParameterLocation.Header));
AddParameterRefs(operationSpec, "urlParameters", logicalParameters.Where(p => p.Location == ParameterLocation.Path));
AddParameterRefs(operationSpec, "queryParameters", logicalParameters.Where(p => p.Location == ParameterLocation.Query));
AddParameterRefs(operationSpec, "headerParameters", logicalParameters.Where(p => p.Location == ParameterLocation.Header));

if (Body != null)
{
operationSpec.ObjectProperty("requestBody", requestBodyObject =>
{
GenerateRequestParameterPath(requestBodyObject, Body, parameterTransformations);
GenerateRequestParameterPath(requestBodyObject, Body, GetParameterTransformations());
requestBodyObject.Property("mapper", requestBodyMapper => ClientModelExtensions.ConstructRequestBodyMapper(requestBodyMapper, Body));
});
operationSpec.QuotedStringProperty("contentType", RequestContentType);
Expand All @@ -596,7 +587,7 @@ public void GenerateOperationSpec(TSObject operationSpec)
IEnumerable<Parameter> formDataParameters = logicalParameters.Where(p => p.Location == ParameterLocation.FormData);
if (formDataParameters.Any())
{
GenerateRequestParameters(operationSpec, "formDataParameters", parameterTransformations, formDataParameters);
AddParameterRefs(operationSpec, "formDataParameters", formDataParameters);
operationSpec.QuotedStringProperty("contentType", RequestContentType);
}
}
Expand Down Expand Up @@ -649,20 +640,34 @@ private static void AddSkipEncodingProperty(TSObject parameterObject, Parameter
}
}

private static void GenerateRequestParameters(TSObject operationSpec, string propertyName, ParameterTransformations parameterTransformations, IEnumerable<Parameter> requestParameters, Action<TSObject, Parameter> extraParameterProperties = null)
internal static void GenerateRequestParameter(TSObject parameterObject, ParameterTS requestParameter, ParameterTransformations parameterTransformations)
{
GenerateRequestParameterPath(parameterObject, requestParameter, parameterTransformations);
parameterObject.Property("mapper", mapper => ClientModelExtensions.ConstructMapper(mapper, requestParameter.ModelType, requestParameter.SerializedName, requestParameter, false, false, false));

ParameterLocation location = requestParameter.Location;
if (location == ParameterLocation.Path || location == ParameterLocation.Query)
{
AddSkipEncodingProperty(parameterObject, requestParameter);
}
if (location == ParameterLocation.Query)
{
if (requestParameter.CollectionFormat != CollectionFormat.None)
{
parameterObject.TextProperty("collectionFormat", $"msRest.QueryCollectionFormat.{requestParameter.CollectionFormat}");
}
}
}

private static void AddParameterRefs(TSObject operationSpec, string propertyName, IEnumerable<Parameter> requestParameters)
{
if (requestParameters != null && requestParameters.Any())
{
operationSpec.ArrayProperty(propertyName, parameterArray =>
{
foreach (Parameter requestParameter in requestParameters)
foreach (ParameterTS requestParameter in requestParameters)
{
parameterArray.Object(parameterObject =>
{
GenerateRequestParameterPath(parameterObject, requestParameter, parameterTransformations);
extraParameterProperties?.Invoke(parameterObject, requestParameter);
parameterObject.Property("mapper", mapper => ClientModelExtensions.ConstructMapper(mapper, requestParameter.ModelType, requestParameter.SerializedName, requestParameter, false, false, false));
});
parameterArray.Value(v => v.Text("Parameters." + requestParameter.MapperName));
}
});
}
Expand Down
Loading

0 comments on commit e66db24

Please sign in to comment.