From 7b643775629427f70f5ce211e67f163378cb85aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20N=C3=A4geli?= Date: Wed, 16 Oct 2024 21:47:57 +0200 Subject: [PATCH] Fix representation of wildcards --- Modules/OpenApi/Handler/OpenApiConcern.cs | 7 +++- .../OpenApi/Handler/OpenApiConcernBuilder.cs | 35 +++++++++++++++++-- .../Reflection/Operations/OperationBuilder.cs | 23 ++++++++++-- .../Operations/SignatureAnalyzer.cs | 5 +++ Playground/Program.cs | 25 ++++++++++++- 5 files changed, 87 insertions(+), 8 deletions(-) diff --git a/Modules/OpenApi/Handler/OpenApiConcern.cs b/Modules/OpenApi/Handler/OpenApiConcern.cs index 6f6e9b77..9a46e14b 100644 --- a/Modules/OpenApi/Handler/OpenApiConcern.cs +++ b/Modules/OpenApi/Handler/OpenApiConcern.cs @@ -20,17 +20,20 @@ public sealed class OpenApiConcern : IConcern private bool EnableCaching { get; } + private Action PostProcessor { get; } + #endregion #region Initialization - public OpenApiConcern(IHandler parent, Func contentFactory, ApiDiscoveryRegistry discovery, bool enableCaching) + public OpenApiConcern(IHandler parent, Func contentFactory, ApiDiscoveryRegistry discovery, bool enableCaching, Action postProcessor) { Parent = parent; Content = contentFactory(this); Discovery = discovery; EnableCaching = enableCaching; + PostProcessor = postProcessor; } #endregion @@ -119,6 +122,8 @@ private OpenApiDocument Discover(IRequest request, ApiDiscoveryRegistry registry registry.Explore(Content, [], document, schemata); + PostProcessor.Invoke(request, document); + if (EnableCaching) { _Cached = document; diff --git a/Modules/OpenApi/Handler/OpenApiConcernBuilder.cs b/Modules/OpenApi/Handler/OpenApiConcernBuilder.cs index e6ae4103..ded222ef 100644 --- a/Modules/OpenApi/Handler/OpenApiConcernBuilder.cs +++ b/Modules/OpenApi/Handler/OpenApiConcernBuilder.cs @@ -1,12 +1,20 @@ using GenHTTP.Api.Content; +using GenHTTP.Api.Protocol; + using GenHTTP.Modules.OpenApi.Discovery; +using NSwag; + namespace GenHTTP.Modules.OpenApi.Handler; public sealed class OpenApiConcernBuilder : IConcernBuilder { private bool _Caching = true; + private string? _Title, _Version; + + private Action? _PostProcessor; + #region Get-/Setters private ApiDiscoveryRegistry Discovery { get; } @@ -26,13 +34,13 @@ public OpenApiConcernBuilder(ApiDiscoveryRegistry registry) public OpenApiConcernBuilder Title(string title) { - // todo + _Title = title; return this; } public OpenApiConcernBuilder Version(string version) { - // todo + _Version = version; return this; } @@ -42,9 +50,30 @@ public OpenApiConcernBuilder Caching(bool enabled) return this; } + public OpenApiConcernBuilder PostProcessor(Action action) + { + _PostProcessor = action; + return this; + } + public IConcern Build(IHandler parent, Func contentFactory) { - return new OpenApiConcern(parent, contentFactory, Discovery, _Caching); + return new OpenApiConcern(parent, contentFactory, Discovery, _Caching, DoPostProcessing); + } + + private void DoPostProcessing(IRequest request, OpenApiDocument document) + { + if (_Title != null) + { + document.Info.Title = _Title; + } + + if (_Version != null) + { + document.Info.Version = _Version; + } + + _PostProcessor?.Invoke(request, document); } #endregion diff --git a/Modules/Reflection/Operations/OperationBuilder.cs b/Modules/Reflection/Operations/OperationBuilder.cs index c4704861..3df4fce5 100644 --- a/Modules/Reflection/Operations/OperationBuilder.cs +++ b/Modules/Reflection/Operations/OperationBuilder.cs @@ -68,10 +68,27 @@ public static Operation Create(string? definition, MethodInfo method, MethodRegi pathArguments.Add(name); } - var end = forceTrailingSlash ? "/" : "(/|)"; - end = isWildcard ? end : $"{end}$"; + if (forceTrailingSlash) + { + matchBuilder.Append('/'); + nameBuilder.Append('/'); + } + else + { + matchBuilder.Append("(/|)"); + } + + if (isWildcard) + { + nameBuilder.Append("{path}"); + pathArguments.Add("path"); + } + else + { + matchBuilder.Append('$'); + } - var matcher = new Regex($"^/{matchBuilder}{end}", RegexOptions.Compiled); + var matcher = new Regex($"^/{matchBuilder}", RegexOptions.Compiled); path = new OperationPath(nameBuilder.ToString(), matcher, false, isWildcard); } diff --git a/Modules/Reflection/Operations/SignatureAnalyzer.cs b/Modules/Reflection/Operations/SignatureAnalyzer.cs index 7718f291..241a16eb 100644 --- a/Modules/Reflection/Operations/SignatureAnalyzer.cs +++ b/Modules/Reflection/Operations/SignatureAnalyzer.cs @@ -45,6 +45,11 @@ public static Dictionary GetArguments(MethodInfo meth } } + if (pathArguments.Contains("path")) + { + result.Add("path", new OperationArgument("path", typeof(string), OperationArgumentSource.Path)); + } + return result; } diff --git a/Playground/Program.cs b/Playground/Program.cs index dcb14bb8..9be8b122 100644 --- a/Playground/Program.cs +++ b/Playground/Program.cs @@ -1,5 +1,8 @@ -using GenHTTP.Api.Protocol; +using GenHTTP.Api.Content; +using GenHTTP.Api.Protocol; using GenHTTP.Engine; +using GenHTTP.Modules.Basics; +using GenHTTP.Modules.Controllers; using GenHTTP.Modules.Functional; using GenHTTP.Modules.Layouting; using GenHTTP.Modules.OpenApi; @@ -14,8 +17,14 @@ .Title("My API") .Version("1.0.0"); +var inline = Inline.Create() + .Head("bla", () => 42) + .Get("redirect", () => Redirect.To("https://google.de")); + var api = Layout.Create() .AddService("users") + .Add("inline", inline) + .AddController("device") .Add(description); Host.Create() @@ -34,3 +43,17 @@ public class UserService public Stream Avatar(DateTime cannot, short s, byte b, bool b2) { return new MemoryStream(); } } + +public class DeviceController +{ + + // [ControllerAction(RequestMethod.Post)] + public void Register(int id) + { + + } + + [ControllerAction(RequestMethod.Get)] + public IHandlerBuilder Wildcard() => Redirect.To("https://google.de"); + +}