Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-generate nodes namespace #352

Merged
merged 12 commits into from
Sep 7, 2023
2 changes: 1 addition & 1 deletion src/ApiGenerator/Configuration/CodeConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public static class CodeConfiguration
{
private static readonly Glob[] OperationsToInclude =
{
// e.g. new Glob("nodes.*"),
new("dangling_indices.*"),
new("ingest.*"),
new("nodes.*"),
new("snapshot.*"),
new("tasks.*")
};
Expand Down

This file was deleted.

3 changes: 2 additions & 1 deletion src/ApiGenerator/Domain/ApiQueryParametersPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ IEndpointOverrides overrides
value.QueryStringKey = queryStringKey;

if (!renameLookup.TryGetValue(queryStringKey, out var preferredName)) preferredName = queryStringKey;
value.ClsName = CreateCSharpName(preferredName, endpointName);

value.ClsName ??= CreateCSharpName(preferredName, endpointName);

if (skipList.Contains(queryStringKey)) value.Skip = true;

Expand Down
64 changes: 26 additions & 38 deletions src/ApiGenerator/Domain/RestApiSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class EnumDescription

public class RestApiSpec
{
public IDictionary<string, ApiEndpoint> Endpoints { get; set; }
public ImmutableSortedDictionary<string, ApiEndpoint> Endpoints { get; set; }

public ImmutableSortedDictionary<string, ReadOnlyCollection<ApiEndpoint>> EndpointsPerNamespaceLowLevel =>
Endpoints.Values.GroupBy(e=>e.CsharpNames.Namespace)
Expand All @@ -63,44 +63,32 @@ public IEnumerable<EnumDescription> EnumsInTheSpec
{
if (_enumDescriptions != null) return _enumDescriptions;

string CreateName(string name, string methodName, string @namespace)
{
if (
name.ToLowerInvariant().Contains("metric")
||(name.ToLowerInvariant() == "status")
||(name.ToLowerInvariant() == "format")
)
{
if (methodName.StartsWith(@namespace))
return methodName + name;
else
return @namespace + methodName + name;
}
var urlParameterEnums = Endpoints
.Values
.SelectMany(e => e.Url.Params.Values)
.Where(p => p.Options != null && p.Options.Any())
.Select(p => new EnumDescription
{
Name = p.ClsName,
Options = p.Options
})
.ToList();

return name;
}

var urlParameterEnums = (
from e in Endpoints.Values
from para in e.Url.Params.Values
where para.Options != null && para.Options.Any()
let name = CreateName(para.ClsName, e.CsharpNames.MethodName, e.CsharpNames.Namespace)
where name != "Time"
select new EnumDescription
{
Name = name,
Options = para.Options
}).ToList();

var urlPartEnums = (
from e in Endpoints.Values
from part in e.Url.Parts
where part.Options != null && part.Options.Any()
select new EnumDescription
{
Name = CreateName(part.Name.ToPascalCase(), e.CsharpNames.MethodName, e.CsharpNames.Namespace),
Options = part.Options
}).ToList();
var urlPartEnums = Endpoints
.Values
.SelectMany(e => e.Url.Parts, (e, part) => new { e, part })
.Where(p => p.part.Options != null && p.part.Options.Any())
.Select(p =>
{
var ns = p.e.CsharpNames.Namespace;
var m = p.e.CsharpNames.MethodName;
return new EnumDescription
{
Name = (!m.StartsWith(ns) ? ns : string.Empty) + m + p.part.Name.ToPascalCase(),
Options = p.part.Options
};
}).
ToList();

_enumDescriptions = urlPartEnums
.Concat(urlParameterEnums)
Expand Down
26 changes: 14 additions & 12 deletions src/ApiGenerator/Domain/Specification/ApiEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,44 +62,46 @@ public class ApiEndpoint

public IEndpointOverrides Overrides { get; internal set; }

public RequestInterface RequestInterface => new RequestInterface
{
private IEnumerable<QueryParameters> ParamsToGenerate => Url.Params.Values.Where(p => !p.Skip).OrderBy(p => p.ClsName);

public RequestInterface RequestInterface => new()
{
CsharpNames = CsharpNames,
UrlParts = Url.Parts,
PartialParameters =
Body == null ? Enumerable.Empty<QueryParameters>().ToList() : Url.Params.Values.Where(p => p.RenderPartial && !p.Skip).ToList(),
Body == null ? Enumerable.Empty<QueryParameters>().ToList() : ParamsToGenerate.Where(p => p.RenderPartial).ToList(),
OfficialDocumentationLink = OfficialDocumentationLink?.Url
};

public RequestPartialImplementation RequestPartialImplementation => new RequestPartialImplementation
{
public RequestPartialImplementation RequestPartialImplementation => new()
{
CsharpNames = CsharpNames,
OfficialDocumentationLink = OfficialDocumentationLink?.Url,
Stability = Stability,
Paths = Url.Paths,
Parts = Url.Parts,
Params = Url.Params.Values.Where(p => !p.Skip).ToList(),
Params = ParamsToGenerate.ToList(),
Constructors = Constructor.RequestConstructors(CsharpNames, Url, inheritsFromPlainRequestBase: true).ToList(),
GenericConstructors = Constructor.RequestConstructors(CsharpNames, Url, inheritsFromPlainRequestBase: false).ToList(),
HasBody = Body != null,
};

public DescriptorPartialImplementation DescriptorPartialImplementation => new DescriptorPartialImplementation
{
public DescriptorPartialImplementation DescriptorPartialImplementation => new()
{
CsharpNames = CsharpNames,
OfficialDocumentationLink = OfficialDocumentationLink?.Url,
Constructors = Constructor.DescriptorConstructors(CsharpNames, Url).ToList(),
Paths = Url.Paths,
Parts = Url.Parts,
Params = Url.Params.Values.Where(p => !p.Skip).ToList(),
Params = ParamsToGenerate.ToList(),
HasBody = Body != null,
};

public RequestParameterImplementation RequestParameterImplementation => new RequestParameterImplementation
{
public RequestParameterImplementation RequestParameterImplementation => new()
{
CsharpNames = CsharpNames,
OfficialDocumentationLink = OfficialDocumentationLink?.Url,
Params = Url.Params.Values.Where(p => !p.Skip).ToList(),
Params = ParamsToGenerate.ToList(),
HttpMethod = PreferredHttpMethod
};

Expand Down
10 changes: 7 additions & 3 deletions src/ApiGenerator/Domain/Specification/UrlInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;

namespace ApiGenerator.Domain.Specification
Expand All @@ -42,7 +43,7 @@ public class UrlInformation

public IDictionary<string, UrlPart> OriginalParts { get; set; }

private IReadOnlyCollection<DeprecatedPath> DeprecatedPaths { get; set; }
public IList<DeprecatedPath> DeprecatedPaths { get; set; } = new List<DeprecatedPath>();

private List<UrlPath> _paths;
public IReadOnlyCollection<UrlPath> Paths
Expand Down Expand Up @@ -113,7 +114,11 @@ public IReadOnlyCollection<UrlPath> PathsWithDeprecations
}


public IReadOnlyCollection<UrlPart> Parts => Paths.SelectMany(p => p.Parts).DistinctBy(p => p.Name).ToList();
public IReadOnlyCollection<UrlPart> Parts => Paths
.SelectMany(p => p.Parts)
.DistinctBy(p => p.Name)
.OrderBy(p => p.Name)
.ToList();

public bool IsPartless => !Parts.Any();

Expand All @@ -135,6 +140,5 @@ public bool TryGetDocumentApiPath(out UrlPath path)
path = new UrlPath(mostVerbosePath.Path, OriginalParts, mostVerbosePath.Parts);
return true;
}

}
}
65 changes: 53 additions & 12 deletions src/ApiGenerator/Generator/ApiEndpointFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
using ApiGenerator.Domain.Code;
using ApiGenerator.Domain.Specification;
using NJsonSchema;
using NJsonSchema.References;
using NSwag;

namespace ApiGenerator.Generator
Expand All @@ -55,16 +56,37 @@ public static ApiEndpoint From(string name, List<(string HttpPath, OpenApiPathIt

foreach (var (httpPath, path, _, operation) in variants.DistinctBy(v => v.HttpPath))
{
urlInfo.OriginalPaths.Add(httpPath);
if (!operation.IsDeprecated)
urlInfo.OriginalPaths.Add(httpPath);
else
{
urlInfo.DeprecatedPaths.Add(new DeprecatedPath
{
Path = httpPath,
Version = operation.GetExtension("x-version-deprecated") as string,
Description = operation.GetExtension("x-deprecation-message") as string
});
}

var pathParams = path.Parameters
.Concat(operation.Parameters)
.Where(p => p.Kind == OpenApiParameterKind.Path)
.ToList();

foreach (var overloadedParam in pathParams.Where(p => p.Schema.XOverloadedParam() != null))
{
urlInfo.OriginalPaths.Add(httpPath.Replace(
$"{{{overloadedParam.Name}}}",
$"{{{overloadedParam.Schema.XOverloadedParam()}}}"
));
}

var paramNames = pathParams.Select(p => p.Name);
if (requiredPathParams != null)
if (requiredPathParams != null)
requiredPathParams.IntersectWith(paramNames);
else
requiredPathParams = new HashSet<string>(paramNames);

allPathParams.AddRange(pathParams);
}

Expand All @@ -84,15 +106,7 @@ public static ApiEndpoint From(string name, List<(string HttpPath, OpenApiPathIt
urlInfo.Params = variants.SelectMany(v => v.Path.Parameters.Concat(v.Operation.Parameters))
.Where(p => p.Kind == OpenApiParameterKind.Query)
.DistinctBy(p => p.Name)
.ToImmutableSortedDictionary(p => p.Name,
p => new QueryParameters
{
Type = GetOpenSearchType(p.Schema),
Description = p.Description,
Options = GetEnumOptions(p.Schema),
Deprecated = GetDeprecation(p.Schema),
VersionAdded = p.Schema.XVersionAdded()
});
.ToImmutableSortedDictionary(p => p.Name, BuildQueryParam);

var endpoint = new ApiEndpoint
{
Expand Down Expand Up @@ -138,6 +152,25 @@ private static void PatchRequestParameters(ApiEndpoint endpoint) =>
endpoint.Url.Params = ApiQueryParametersPatcher.Patch(endpoint.Name, endpoint.Url.Params, endpoint.Overrides)
?? throw new ArgumentNullException("ApiQueryParametersPatcher.Patch(endpoint.Name, endpoint.Url.Params, endpoint.Overrides)");

private static QueryParameters BuildQueryParam(OpenApiParameter p)
{
var param = new QueryParameters
{
Type = GetOpenSearchType(p.Schema),
Description = p.Description,
Options = GetEnumOptions(p.Schema),
Deprecated = GetDeprecation(p.Schema),
VersionAdded = p.Schema.XVersionAdded(),
};

if (param.Type == "enum" && p.Schema.HasReference)
{
param.ClsName = ((IJsonReference)p.Schema).ReferencePath.Split('/').Last();
}

return param;
}

private static string GetOpenSearchType(JsonSchema schema)
{
schema = schema.ActualSchema;
Expand All @@ -155,7 +188,9 @@ private static string GetOpenSearchType(JsonSchema schema)
}

private static IEnumerable<string> GetEnumOptions(JsonSchema schema) =>
schema.ActualSchema.Enumeration?.Select(e => e.ToString()) ?? Enumerable.Empty<string>();
schema.ActualSchema.XEnumOptions()
?? schema.ActualSchema.Enumeration?.Select(e => e.ToString())
?? Enumerable.Empty<string>();

private static QueryParameterDeprecation GetDeprecation(IJsonExtensionObject schema) =>
(schema.XDeprecationMessage(), schema.XVersionDeprecated()) switch
Expand Down Expand Up @@ -186,6 +221,12 @@ private static string XVersionAdded(this IJsonExtensionObject schema) =>
private static string XDataType(this IJsonExtensionObject schema) =>
schema.GetExtension("x-data-type") as string;

private static string XOverloadedParam(this IJsonExtensionObject schema) =>
schema.GetExtension("x-overloaded-param") as string;

private static IEnumerable<string> XEnumOptions(this IJsonExtensionObject schema) =>
schema.GetExtension("x-enum-options") is object[] opts ? opts.Cast<string>() : null;

private static object GetExtension(this IJsonExtensionObject schema, string key) =>
schema.ExtensionData?.TryGetValue(key, out var value) ?? false ? value : null;
}
Expand Down
2 changes: 2 additions & 0 deletions src/ApiGenerator/Generator/ApiGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
using ApiGenerator.Configuration;
using ApiGenerator.Domain;
using ApiGenerator.Generator.Razor;
using NJsonSchema;
using NSwag;
using ShellProgressBar;

Expand Down Expand Up @@ -92,6 +93,7 @@ await DoGenerate(
public static async Task<RestApiSpec> CreateRestApiSpecModel(CancellationToken token = default)
{
var document = await OpenApiYamlDocument.FromFileAsync(GeneratorLocations.OpenApiSpecFile, token);
JsonSchemaReferenceUtilities.UpdateSchemaReferencePaths(document);

var endpoints = document.Paths
.Select(kv => new { HttpPath = kv.Key, PathItem = kv.Value })
Expand Down
Loading
Loading