private static IEnumerable <string> GetApiVersions(SwaggerDocumentationOptions options)
 => options
 .ApiVersionDescriptionProvider
 .ApiVersionDescriptions
 .Select(x => x.GroupName)
 .OrderBy(x => x)
 .ToList();
 private static string GeneratejQueryCode(
     SwaggerDocumentationOptions options,
     string description,
     OpenApiDocument document)
 => new TypeScriptClientGenerator(document, new TypeScriptClientGeneratorSettings
 {
     ClassName = $"{options.TypeScriptClient.ClassName}{description.FirstLetterToUpperCaseOrConvertNullToEmptyString()}",
     Template  = TypeScriptTemplate.JQueryCallbacks
 }).GenerateFile();
 private static string GenerateCSharpCode(
     SwaggerDocumentationOptions options,
     string description,
     OpenApiDocument document)
 => new CSharpClientGenerator(document, new CSharpClientGeneratorSettings
 {
     ClassName = $"{options.CSharpClient.ClassName}{description.FirstLetterToUpperCaseOrConvertNullToEmptyString()}",
     CSharpGeneratorSettings =
     {
         Namespace = options.CSharpClient.Namespace
     }
 }).GenerateFile(ClientGeneratorOutputType.Full);
        private static IApplicationBuilder MapClient(
            this IApplicationBuilder app,
            SwaggerDocumentationOptions options,
            string language,
            Func <SwaggerDocumentationOptions, string, OpenApiDocument, string> generateCode)
        => app.Map(new PathString($"/clients/{language}"), apiClients =>
        {
            var apiVersions = GetApiVersions(options);

            foreach (var description in apiVersions)
            {
                apiClients.Map(new PathString($"/{description}"), apiClient => apiClient.Run(async context =>
                {
                    var baseUrl  = $"{context.Request.Scheme}://{context.Request.Host}";
                    var document = await OpenApiDocument.FromUrlAsync($"{baseUrl}/docs/{description}/docs.json");

                    await context.Response.WriteAsync(generateCode(options, description, document));
                }));
            }
        });
        private static IApplicationBuilder MapDocs(this IApplicationBuilder app, SwaggerDocumentationOptions options)
        {
            app.Map(new PathString("/docs"), apiDocs =>
            {
                apiDocs.UseSwagger(x =>
                {
                    //x.SerializeAsV2 = true;
                    //x.RouteTemplate = "{documentName}/docs.json";
                    x.RouteTemplate = "swagger/{documentName}/swagger.json";
                    x.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
                    {
                        swaggerDoc.Servers = new List <Microsoft.OpenApi.Models.OpenApiServer> {
                            new Microsoft.OpenApi.Models.OpenApiServer {
                                Url = $"{httpReq.Scheme}://{httpReq.Host.Value}/"
                            }
                        };
                    });
                });

                var apiVersions = options
                                  .ApiVersionDescriptionProvider
                                  .ApiVersionDescriptions
                                  .Select(x => x.GroupName)
                                  .OrderBy(x => x)
                                  .ToList();

                var stringLocalizer = app.ApplicationServices.GetRequiredService <IStringLocalizer <Localization> >();

                foreach (var description in apiVersions)
                {
                    apiDocs.UseReDoc(x =>
                    {
                        x.DocumentTitle       = stringLocalizer[options.DocumentTitleFunc(description)];
                        x.DocumentDescription = stringLocalizer[options.DocumentDescriptionFunc(description)];
                        x.ApplicationName     = stringLocalizer[options.ApplicationNameFunc(description)];
                        x.HeaderTitle         = stringLocalizer[options.HeaderTitleFunc(description)];
                        x.HeaderLink          = stringLocalizer[options.HeaderLinkFunc(description)];
                        x.HeadContent         = options.HeadContentFunc(description);
                        x.FooterVersion       = options.FooterVersion;
                        x.SpecUrl             = $"/docs/{description}/docs.json";
                        x.RoutePrefix         = $"{description}";
                    });
                }

                if (apiVersions.Count > 0)
                {
                    apiDocs.UseReDoc(x =>
                    {
                        x.DocumentTitle       = stringLocalizer[options.DocumentTitleFunc(apiVersions[0])];
                        x.DocumentDescription = stringLocalizer[options.DocumentDescriptionFunc(apiVersions[0])];
                        x.ApplicationName     = stringLocalizer[options.ApplicationNameFunc(apiVersions[0])];
                        x.HeaderTitle         = stringLocalizer[options.HeaderTitleFunc(apiVersions[0])];
                        x.HeaderLink          = stringLocalizer[options.HeaderLinkFunc(apiVersions[0])];
                        x.HeadContent         = options.HeadContentFunc(apiVersions[0]);
                        x.FooterVersion       = options.FooterVersion;
                        x.SpecUrl             = $"/docs/{apiVersions[0]}/docs.json";
                        x.RoutePrefix         = string.Empty;
                    });
                }
            });

            return(app);
        }
        public static IApplicationBuilder UseSwaggerDocumentation(
            this IApplicationBuilder app,
            SwaggerDocumentationOptions options)
        {
            // A bit of a hack to give all the Funcs the default value, but still managing them in one place.
            var defaultValues = new ReDocOptions();

            if (options.ApiVersionDescriptionProvider == null)
            {
                throw new ArgumentNullException(nameof(options.ApiVersionDescriptionProvider));
            }

            if (options.DocumentTitleFunc == null)
            {
                options.DocumentTitleFunc = _ => defaultValues.DocumentTitle;
            }

            if (options.DocumentDescriptionFunc == null)
            {
                options.DocumentDescriptionFunc = _ => defaultValues.DocumentDescription;
            }

            if (options.ApplicationNameFunc == null)
            {
                options.ApplicationNameFunc = _ => defaultValues.ApplicationName;
            }

            if (options.HeaderTitleFunc == null)
            {
                options.HeaderTitleFunc = _ => defaultValues.HeaderTitle;
            }

            if (options.HeaderLinkFunc == null)
            {
                options.HeaderLinkFunc = _ => defaultValues.HeaderLink;
            }

            if (options.HeadContentFunc == null)
            {
                options.HeadContentFunc = _ => defaultValues.HeadContent;
            }

            if (string.IsNullOrWhiteSpace(options.FooterVersion))
            {
                options.FooterVersion = defaultValues.FooterVersion;
            }

            if (string.IsNullOrWhiteSpace(options.CSharpClient.ClassName))
            {
                throw new ArgumentNullException(nameof(options.CSharpClient.ClassName));
            }

            if (string.IsNullOrWhiteSpace(options.CSharpClient.Namespace))
            {
                throw new ArgumentNullException(nameof(options.CSharpClient.Namespace));
            }

            if (string.IsNullOrWhiteSpace(options.TypeScriptClient.ClassName))
            {
                throw new ArgumentNullException(nameof(options.TypeScriptClient.ClassName));
            }

            app
            .MapDocs(options)
            .MapClient(options, "csharp", GenerateCSharpCode)
            .MapClient(options, "jquery", GeneratejQueryCode)
            .MapClient(options, "angular", GenerateAngularCode)
            .MapClient(options, "angularjs", GenerateAngularJsCode);

            return(app);
        }