public void GetOpenApiSchemas_Result_Should_Contain_Schema_For_Function_Classes() { var namingStrategy = new DefaultNamingStrategy(); var filter = new RouteConstraintFilter(); var acceptor = new OpenApiSchemaAcceptor(); var documentHelper = new DocumentHelper(filter, acceptor); var visitorCollection = VisitorCollection.CreateInstance(); var methods = typeof(FakeFunctions).GetMethods().ToList(); var schemas = documentHelper.GetOpenApiSchemas(methods, namingStrategy, visitorCollection); schemas.Should().NotBeNull(); schemas.Count.Should().Be(6); schemas.Should().ContainKey("FakeClassModel"); schemas["FakeClassModel"].Properties.Count.Should().Be(2); schemas["FakeClassModel"].Type.Should().Be("object"); schemas.Should().ContainKey("FakeOtherClassModel"); schemas["FakeOtherClassModel"].Properties.Count.Should().Be(2); schemas["FakeOtherClassModel"].Type.Should().Be("object"); schemas["FakeClassModel"].Properties.Count.Should().Be(2); schemas["FakeClassModel"].Type.Should().Be("object"); schemas.Should().ContainKey("FakeListModel"); schemas["FakeListModel"].Properties.Count.Should().Be(1); schemas["FakeListModel"].Type.Should().Be("object"); schemas.Should().ContainKey("FakeStringModel"); schemas["FakeStringModel"].Properties.Count.Should().Be(2); schemas["FakeStringModel"].Type.Should().Be("object"); schemas.Should().ContainKey("FakeGenericModel_FakeClassModel"); schemas["FakeGenericModel_FakeClassModel"].Properties.Count.Should().Be(2); schemas["FakeGenericModel_FakeClassModel"].Type.Should().Be("object"); schemas["FakeGenericModel_FakeClassModel"].Properties.Should().ContainKey("Name"); schemas["FakeGenericModel_FakeClassModel"].Properties.Should().ContainKey("Value"); schemas["FakeGenericModel_FakeClassModel"].Properties["Value"].Properties.Should().ContainKey("Number"); schemas["FakeGenericModel_FakeClassModel"].Properties["Value"].Properties.Should().ContainKey("Text"); schemas.Should().ContainKey("FakeGenericModel_FakeOtherClassModel"); schemas["FakeGenericModel_FakeOtherClassModel"].Properties.Count.Should().Be(2); schemas["FakeGenericModel_FakeOtherClassModel"].Type.Should().Be("object"); schemas["FakeGenericModel_FakeOtherClassModel"].Properties.Should().ContainKey("Name"); schemas["FakeGenericModel_FakeOtherClassModel"].Properties.Should().ContainKey("Value"); schemas["FakeGenericModel_FakeOtherClassModel"].Properties["Value"].Properties.Should().ContainKey("FirstName"); schemas["FakeGenericModel_FakeOtherClassModel"].Properties["Value"].Properties.Should().ContainKey("LastName"); }
/// <summary> /// Converts <see cref="OpenApiPayloadAttribute"/> to <see cref="OpenApiMediaType"/>. /// </summary> /// <typeparam name="T">Type of payload attribute inheriting <see cref="OpenApiPayloadAttribute"/>.</typeparam> /// <param name="attribute">OpenApi payload attribute.</param> /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance to create the JSON schema from .NET Types.</param> /// <param name="collection"><see cref="VisitorCollection"/> instance.</param> /// <returns><see cref="OpenApiMediaType"/> instance.</returns> public static OpenApiMediaType ToOpenApiMediaType <T>(this T attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null) where T : OpenApiPayloadAttribute { attribute.ThrowIfNullOrDefault(); if (namingStrategy.IsNullOrDefault()) { namingStrategy = new DefaultNamingStrategy(); } if (collection.IsNullOrDefault()) { collection = VisitorCollection.CreateInstance(); } var type = attribute.BodyType; // Generate schema based on the type. var schema = collection.PayloadVisit(type, namingStrategy); // Add deprecated attribute. if (attribute is OpenApiRequestBodyAttribute) { schema.Deprecated = (attribute as OpenApiRequestBodyAttribute).Deprecated; } if (attribute is OpenApiResponseWithBodyAttribute) { schema.Deprecated = (attribute as OpenApiResponseWithBodyAttribute).Deprecated; } // For array and dictionary object, the reference has already been added by the visitor. if (type.IsReferentialType() && !type.IsOpenApiNullable() && !type.IsOpenApiArray() && !type.IsOpenApiDictionary()) { var reference = new OpenApiReference() { Type = ReferenceType.Schema, Id = attribute.BodyType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) }; schema.Reference = reference; } var mediaType = new OpenApiMediaType() { Schema = schema }; return(mediaType); }
public void Init() { this._visitorCollection = VisitorCollection.CreateInstance(); this._visitor = new DictionaryObjectTypeVisitor(this._visitorCollection); this._strategy = new CamelCaseNamingStrategy(); }
/// <inheritdoc /> public virtual VisitorCollection GetVisitorCollection() { var collection = VisitorCollection.CreateInstance(); return(collection); }
/// <summary> /// Generates the OpenAPI document. /// </summary> /// <param name="project">Project path.</param> /// <param name="configuration">Copile configuration.</param> /// <param name="version">OpenAPI version.</param> /// <param name="format">OpenAPI output format.</param> /// <param name="output">Output path.</param> /// <param name="console">Value indicating whether to render the document on console or not.</param> public void Generate( [Option('p', Description = "Project path. Default is current directory")] string project = ".", [Option('c', Description = "Configuration. Default is 'Debug'")] string configuration = "Debug", [Option('t', Description = "Target framework. Default is 'netcoreapp2.1'")] string target = "netcoreapp2.1", [Option('v', Description = "OpenAPI spec version. Value can be either 'v2' or 'v3'. Default is 'v2'")] OpenApiVersionType version = OpenApiVersionType.V2, [Option('f', Description = "OpenAPI output format. Value can be either 'json' or 'yaml'. Default is 'yaml'")] OpenApiFormatType format = OpenApiFormatType.Json, [Option('o', Description = "Generated OpenAPI output location. Default is 'output'")] string output = "output", bool console = false) { var pi = default(ProjectInfo); try { pi = new ProjectInfo(project, configuration, target); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); return; } var req = new Mock <HttpRequest>(); req.SetupGet(p => p.Scheme).Returns("http"); req.SetupGet(p => p.Host).Returns(new HostString("localhost", 7071)); var filter = new RouteConstraintFilter(); var acceptor = new OpenApiSchemaAcceptor(); var namingStrategy = new CamelCaseNamingStrategy(); var collection = VisitorCollection.CreateInstance(); var helper = new DocumentHelper(filter, acceptor); var document = new Document(helper); var swagger = default(string); try { swagger = document.InitialiseDocument() .AddMetadata(pi.OpenApiInfo) .AddServer(req.Object, pi.HostJsonHttpSettings.RoutePrefix) .AddNamingStrategy(namingStrategy) .AddVisitors(collection) .Build(pi.CompiledDllPath) .RenderAsync(version.ToOpenApiSpecVersion(), format.ToOpenApiFormat()) .Result; } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); } if (console) { Console.WriteLine(swagger); } var outputpath = Path.IsPathFullyQualified(output) ? output : $"{pi.CompiledPath}{directorySeparator}{output}"; if (!Directory.Exists(outputpath)) { Directory.CreateDirectory(outputpath); } File.WriteAllText($"{outputpath}{directorySeparator}swagger.{format.ToDisplayName()}", swagger, Encoding.UTF8); }
/// <summary> /// Converts <see cref="OpenApiParameterAttribute"/> to <see cref="OpenApiParameter"/>. /// </summary> /// <param name="attribute"><see cref="OpenApiParameterAttribute"/> instance.</param> /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param> /// <param name="collection"><see cref="VisitorCollection"/> instance.</param> /// <returns><see cref="OpenApiParameter"/> instance.</returns> public static OpenApiParameter ToOpenApiParameter(this OpenApiParameterAttribute attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null) { attribute.ThrowIfNullOrDefault(); if (namingStrategy.IsNullOrDefault()) { namingStrategy = new DefaultNamingStrategy(); } if (collection.IsNullOrDefault()) { collection = VisitorCollection.CreateInstance(); } var type = attribute.Type; var schema = collection.ParameterVisit(type, namingStrategy); var parameter = new OpenApiParameter() { Name = attribute.Name, Description = attribute.Description, Required = attribute.Required, In = attribute.In, Schema = schema }; if (type.IsOpenApiArray()) { if (attribute.In == ParameterLocation.Path) { parameter.Style = ParameterStyle.Simple; parameter.Explode = false; } if (attribute.In == ParameterLocation.Query) { parameter.Style = attribute.CollectionDelimiter == OpenApiParameterCollectionDelimiterType.Comma ? ParameterStyle.Form : (attribute.CollectionDelimiter == OpenApiParameterCollectionDelimiterType.Space ? ParameterStyle.SpaceDelimited : ParameterStyle.PipeDelimited); parameter.Explode = attribute.CollectionDelimiter == OpenApiParameterCollectionDelimiterType.Comma ? attribute.Explode : false; } } if (!string.IsNullOrWhiteSpace(attribute.Summary)) { var summary = new OpenApiString(attribute.Summary); parameter.Extensions.Add("x-ms-summary", summary); } if (attribute.Visibility != OpenApiVisibilityType.Undefined) { var visibility = new OpenApiString(attribute.Visibility.ToDisplayName()); parameter.Extensions.Add("x-ms-visibility", visibility); } return(parameter); }
/// <summary> /// Converts <see cref="OpenApiPayloadAttribute"/> to <see cref="OpenApiMediaType"/>. /// </summary> /// <typeparam name="T">Type of payload attribute inheriting <see cref="OpenApiPayloadAttribute"/>.</typeparam> /// <param name="attribute">OpenApi payload attribute.</param> /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance to create the JSON schema from .NET Types.</param> /// <param name="collection"><see cref="VisitorCollection"/> instance.</param> /// <param name="version">OpenAPI spec version.</param> /// <returns><see cref="OpenApiMediaType"/> instance.</returns> public static OpenApiMediaType ToOpenApiMediaType <T>(this T attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null, OpenApiVersionType version = OpenApiVersionType.V2) where T : OpenApiPayloadAttribute { attribute.ThrowIfNullOrDefault(); if (namingStrategy.IsNullOrDefault()) { namingStrategy = new DefaultNamingStrategy(); } if (collection.IsNullOrDefault()) { collection = VisitorCollection.CreateInstance(); } var type = attribute.BodyType; // Generate schema based on the type. var schema = collection.PayloadVisit(type, namingStrategy); // Add deprecated attribute. if (attribute is OpenApiRequestBodyAttribute) { schema.Deprecated = (attribute as OpenApiRequestBodyAttribute).Deprecated; } if (attribute is OpenApiResponseWithBodyAttribute) { schema.Deprecated = (attribute as OpenApiResponseWithBodyAttribute).Deprecated; } // For array and dictionary object, the reference has already been added by the visitor. if (type.IsReferentialType() && !type.IsOpenApiNullable() && !type.IsOpenApiArray() && !type.IsOpenApiDictionary()) { var reference = new OpenApiReference() { Type = ReferenceType.Schema, Id = attribute.BodyType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy) }; schema.Reference = reference; } var mediaType = new OpenApiMediaType() { Schema = schema }; if (attribute.Example.IsNullOrDefault()) { return(mediaType); } if (!attribute.Example.HasInterface("IOpenApiExample`1")) { return(mediaType); } var example = (dynamic)Activator.CreateInstance(attribute.Example); var examples = (IDictionary <string, OpenApiExample>)example.Build(namingStrategy).Examples; mediaType.Examples = examples; if (version == OpenApiVersionType.V2) { mediaType.Example = examples.First().Value.Value; } return(mediaType); }