// [Fact] public void ParseVeryLargeSwaggerPaths() { var opsTerm = new VocabTerm<Operation>(); var pathTerm = new VocabTerm<Path>(); pathTerm.MapAnyObject<Operation>(opsTerm, (s, p) => { return s.AddOperation(p, Guid.NewGuid().ToString()); }); var pathsTerm = new VocabTerm<OpenApiDocument>("paths"); pathsTerm.MapAnyObject<Path>(pathTerm, (s, p) => { return s.AddPath(p); }); var rootTerm = new VocabTerm<OpenApiDocument>(); rootTerm.MapObject<OpenApiDocument>(pathsTerm, (s) => { return s; }); var swaggerDoc = new OpenApiDocument(); var sw = new Stopwatch(); using (var stream = File.OpenRead(@"C:\Users\Darrel\Documents\Swagger\WebSites.json")) { sw.Start(); JsonStreamingParser.ParseStream(stream, swaggerDoc, rootTerm); sw.Stop(); }; _output.WriteLine(swaggerDoc.Paths.Count.ToString()); _output.WriteLine("That took : " + sw.ElapsedMilliseconds); }
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { var path = swaggerDoc.Paths.Where(x => x.Key.Contains("Values")).First().Value; var param = path.Operations.Where(x => x.Key.Equals("Post")).First().Value; //param.Extensions.Add("x-code-samples", new OpenApiExtension { "123456" }); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Please enter a solution prefix"); } else { solutionPrefix = args[0]; } bool generatePaths = false; if (args.Length > 1) { if (args[1] == "generatePaths") { generatePaths = true; } } // Feature flags // True if we use the Autorest Odata extension bool enableOdataExtension = false; // True if we get metadata from Dynamics bool getMetadata = true; // True if we use strings instead of guids primary keys. bool useStringForGuid = true; bool disableCustomErrorClass = true; List <string> defsToKeep = new List <string>(); // start by getting secrets. var builder = new ConfigurationBuilder() .AddEnvironmentVariables(); builder.AddUserSecrets <Program>(); var Configuration = builder.Build(); string csdl; // get the metadata. if (getMetadata) { csdl = GetDynamicsMetadata(Configuration); File.WriteAllText("dynamics-metadata.xml", csdl); } else { csdl = File.ReadAllText("dynamics-metadata.xml"); } // fix the csdl. csdl = csdl.Replace("ConcurrencyMode=\"Fixed\"", ""); IEdmModel model = CsdlReader.Parse(XElement.Parse(csdl).CreateReader()); // fix dates. /* * OpenApiTarget target = OpenApiTarget.Json; * OpenApiWriterSettings settings = new OpenApiWriterSettings * { * BaseUri = new Uri(Configuration["DYNAMICS_ODATA_URI"]) * }; */ string swagger = null; OpenApiConvertSettings openApiSettings = new OpenApiConvertSettings { // configuration }; OpenApiDocument swaggerDocument = model.ConvertToOpenApi(openApiSettings); if (generatePaths) { List <string> paths = new List <string>(); foreach (var path in swaggerDocument.Paths) { string subPath = path.Key.Substring(path.Key.LastIndexOf("/") + 1); if (subPath.Contains("(")) { subPath = subPath.Substring(0, subPath.IndexOf("(")); } string pathSample = path.Key.Substring(1, subPath.Length); if (pathSample != subPath) { paths.Add(path.Key); } } File.WriteAllText("paths-excluded.json", JsonConvert.SerializeObject(paths)); } else { List <string> itemsToRemove = new List <string>(); if (File.Exists("paths-excluded.json")) { string pathsExcluded = File.ReadAllText("paths-excluded.json"); itemsToRemove = JsonConvert.DeserializeObject <List <string> >(pathsExcluded); } List <string> allops = new List <string>(); // fix the operationIds. foreach (var path in swaggerDocument.Paths) { if (itemsToRemove.Contains(path.Key)) { continue; } if (path.Key.Contains("transactioncurrencyid")) { itemsToRemove.Add(path.Key); continue; } if (path.Key.Contains("scheduledprocessexecution")) { itemsToRemove.Add(path.Key); continue; } // determine if this is a get by key, or a get by key with additional . string subPath = ""; string temp = path.Key.Substring(path.Key.LastIndexOf("/") + 1); if (temp.Contains("(")) { temp = temp.Substring(0, temp.IndexOf("(")); string pathSample = path.Key.Substring(1, temp.Length); if (pathSample != temp) { subPath = temp; } subPath += "ByKey"; } OpenApiTag firstTag = null; // operation.Value.Tags.FirstOrDefault(); if (firstTag == null) { firstTag = new OpenApiTag() { Name = temp }; } string prefix = "Unknown"; string firstTagLower = ""; if (firstTag != null) { bool ok2Delete = true; firstTagLower = firstTag.Name.ToLower(); if (firstTagLower.Equals("contacts") || firstTagLower.Equals("accounts") || firstTagLower.Equals("invoices") || firstTagLower.Equals("incidents") || firstTagLower.Equals("sharepointsites") || firstTagLower.Equals("savedqueries") || firstTagLower.Equals("sharepointdocumentlocations")) { ok2Delete = false; } if (!firstTagLower.StartsWith("msdyn") && !firstTagLower.StartsWith("abs_") && firstTagLower.IndexOf(solutionPrefix) != -1) { //Console.Out.WriteLine($"NOT ok to delete {firstTagLower}"); ok2Delete = false; } if (ok2Delete) { //Console.Out.WriteLine($"ok to delete {firstTagLower}"); if (!itemsToRemove.Contains(path.Key)) { itemsToRemove.Add(path.Key); } continue; } if (!allops.Contains(firstTag.Name)) { allops.Add(firstTag.Name); } prefix = firstTagLower; // Capitalize the first character. if (prefix.Length > 0 && prefix.Length > solutionPrefix.Length) { if (prefix.ToUpper().Substring(0, solutionPrefix.Length) == solutionPrefix.ToUpper()) { prefix = prefix.Substring(solutionPrefix.Length); } prefix = prefix.Substring(0, 1).ToUpper() + prefix.Substring(1); } // remove any underscores. prefix = prefix.Replace("_", ""); } foreach (var operation in path.Value.Operations) { if (!firstTagLower.StartsWith("msdyn") && !firstTagLower.StartsWith("abs_") && firstTagLower.IndexOf(solutionPrefix) != -1) { firstTagLower = firstTagLower.Replace($"{solutionPrefix}_", ""); firstTagLower = firstTagLower.Replace(solutionPrefix, ""); operation.Value.Tags.Clear(); operation.Value.Tags.Add(new OpenApiTag() { Name = firstTagLower }); } string suffix = ""; switch (operation.Key) { case OperationType.Post: suffix = "Create"; // for creates we also want to add a header parameter to ensure we get the new object back. OpenApiParameter swaggerParameter = new OpenApiParameter() { Schema = new OpenApiSchema() { Type = "string", Default = new OpenApiString("return=representation") }, Name = "Prefer", Description = "Required in order for the service to return a JSON representation of the object.", In = ParameterLocation.Header }; operation.Value.Parameters.Add(swaggerParameter); break; case OperationType.Patch: suffix = "Update"; if (subPath == "ByKey") { subPath = ""; } break; case OperationType.Put: suffix = "Put"; if (subPath == "ByKey") { subPath = ""; } break; case OperationType.Delete: suffix = "Delete"; if (subPath == "ByKey") { subPath = ""; } break; case OperationType.Get: suffix = "Get"; break; } if (suffix.Length >= solutionPrefix.Length && suffix.ToUpper().Substring(0, solutionPrefix.Length) == solutionPrefix.ToUpper()) { suffix = suffix.Substring(solutionPrefix.Length); } operation.Value.OperationId = prefix + "_" + suffix; if (!firstTag.Name.Contains(subPath)) { operation.Value.OperationId += subPath; } string operationDef = null; // adjustments to response foreach (var response in operation.Value.Responses) { var val = response.Value; if (response.Key == "default") { if (string.IsNullOrEmpty(response.Value.Description)) { response.Value.Description = "OData Error"; } ; if (disableCustomErrorClass && response.Value.Reference != null) { response.Value.Reference = null; } } if (val != null) { bool hasValue = false; foreach (var schema in val.Content) { foreach (var property in schema.Value.Schema.Properties) { if (property.Key.Equals("value")) { hasValue = true; break; } } if (hasValue) { var newSchema = schema.Value.Schema.Properties["value"]; string resultName; string itemName; if (newSchema.Type == "array") { itemName = newSchema.Items.Reference.Id; operationDef = itemName; resultName = $"{itemName}Collection"; } else { itemName = "!ERR"; resultName = "!ERR"; } if (!swaggerDocument.Components.Schemas.ContainsKey(resultName)) { // move the inline schema to defs. swaggerDocument.Components.Schemas.Add(resultName, schema.Value.Schema); //var newSchema = swaggerDocument.Components.Schemas[resultName].Properties["value"]; if (newSchema.Type == "array") { newSchema.Items = new OpenApiSchema() { Reference = new OpenApiReference() { Id = itemName, Type = ReferenceType.Schema }, Type = "none" }; AddSubItems(swaggerDocument, defsToKeep, itemName); } AddSubItems(swaggerDocument, defsToKeep, resultName); } schema.Value.Schema = new OpenApiSchema { Reference = new OpenApiReference() { Id = resultName, Type = ReferenceType.Schema }, Type = "none" }; // val.Reference = new OpenApiReference() { Id = resultName, Type = ReferenceType.Schema, ExternalResource = null }; } else { if (schema.Value.Schema.Reference != null) { operationDef = schema.Value.Schema.Reference.Id; AddSubItems(swaggerDocument, defsToKeep, operationDef); } } } } } // adjustments to operation parameters if (enableOdataExtension) { string[] oDataParameters = { "top", "skip", "search", "filter", "count", "$orderby", "$select", "$expand" }; List <OpenApiParameter> parametersToRemove = new List <OpenApiParameter>(); foreach (var oDataParameter in oDataParameters) { foreach (var parameter in operation.Value.Parameters) { if (parameter.Name == oDataParameter) { parametersToRemove.Add(parameter); } if (parameter.Reference != null && parameter.Reference.Id == oDataParameter) { parametersToRemove.Add(parameter); } } } foreach (var parameter in parametersToRemove) { operation.Value.Parameters.Remove(parameter); } } operation.Value.Extensions.Clear(); if (operationDef != null && enableOdataExtension) { operation.Value.Extensions.Add("x-ms-odata", new OpenApiString($"#/definitions/{operationDef}")); AddSubItems(swaggerDocument, defsToKeep, operationDef); } foreach (var parameter in operation.Value.Parameters) { if (parameter.Reference != null) { if (parameter.Reference.Id == "top" || parameter.Reference.Id == "skip") { parameter.Name = $"${parameter.Reference.Id}"; parameter.Reference = null; parameter.In = ParameterLocation.Query; parameter.Schema = new OpenApiSchema() { Type = "integer" }; } else if (parameter.Reference.Id == "search" || parameter.Reference.Id == "filter") { parameter.Name = $"${parameter.Reference.Id}"; parameter.Reference = null; parameter.In = ParameterLocation.Query; parameter.Schema = new OpenApiSchema() { Type = "string" }; } else if (parameter.Reference.Id == "count") { parameter.Name = $"${parameter.Reference.Id}"; parameter.Reference = null; parameter.In = ParameterLocation.Query; parameter.Schema = new OpenApiSchema() { Type = "boolean" }; } } else { string name = parameter.Name; if (name == null) { name = parameter.Name; } if (name != null) { if (name == "$top" || name == "$skip") { parameter.In = ParameterLocation.Query; parameter.Reference = null; parameter.Schema = new OpenApiSchema() { Type = "integer" }; } if (name == "$search" || name == "$filter") { parameter.In = ParameterLocation.Query; parameter.Reference = null; parameter.Schema = new OpenApiSchema() { Type = "string" }; } if (name == "$orderby" || name == "$select" || name == "$expand") { parameter.In = ParameterLocation.Query; parameter.Reference = null; parameter.Schema = new OpenApiSchema() { Type = "array", Items = new OpenApiSchema() { Type = "string" } }; parameter.Extensions.Add("collectionFormat", new OpenApiString("csv")); } if (name == "$count") { parameter.In = ParameterLocation.Query; parameter.Reference = null; parameter.Schema = new OpenApiSchema() { Type = "boolean" }; } if (name == "If-Match") { parameter.Reference = null; parameter.Schema = new OpenApiSchema() { Type = "string" }; } if (parameter.Extensions != null && parameter.Extensions.ContainsKey("x-ms-docs-key-type")) { parameter.Extensions.Remove("x-ms-docs-key-type"); } if (string.IsNullOrEmpty(parameter.Name)) { parameter.Name = name; } } } // get rid of style if it exists. if (parameter.Style != ParameterStyle.Simple) { parameter.Style = ParameterStyle.Simple; } // get rid of guid type if it exists if (parameter.Schema?.Format != null && useStringForGuid && parameter.Schema.Format == "uuid") { parameter.Schema.Format = null; parameter.Schema.Pattern = null; } // may need to clear unique items here. // align the schema if it exists. if (parameter.Schema != null && parameter.Schema.Items != null) { var schema = parameter.Schema; if (schema.Type == "array" && parameter.Style == null) { // may be a good idea to set collectionFormat to csv here. It is also set below. parameter.Style = ParameterStyle.Simple; } } } } } foreach (var opDelete in itemsToRemove) { swaggerDocument.Paths.Remove(opDelete); } foreach (var path in swaggerDocument.Paths) { foreach (var value in path.Value.Operations) { foreach (var response in value.Value.Responses) { if (response.Value.Reference != null) { var schema = response.Value.Reference; if (!string.IsNullOrEmpty(schema.Id) && (schema.Type.Value.GetDisplayName() == "array" || schema.Type.Value.GetDisplayName() == "object")) { string title = schema.Id; AddSubItems(swaggerDocument, defsToKeep, title); } } } foreach (var parameter in value.Value.Parameters) { if (parameter.Schema != null && parameter.Schema.Reference != null) { var schema = parameter.Schema.Reference; if (!string.IsNullOrEmpty(schema.Id) && (schema.Type.Value.GetDisplayName() == "array" || schema.Type.Value.GetDisplayName() == "object")) { AddSubItems(swaggerDocument, defsToKeep, schema.Id); } } } } } // reverse the items to keep. List <string> defsToRemove = new List <string>(); foreach (var definition in swaggerDocument.Components.Schemas) { if ( !definition.Key.Contains("odata.error") && !definition.Key.Contains("crmbaseentity") && !definition.Key.ToLower().Contains("optionmetadata") && !defsToKeep.Contains(definition.Key)) { defsToRemove.Add(definition.Key); } } foreach (string defToRemove in defsToRemove) { //Console.Out.WriteLine($"Remove: {defToRemove}"); if (!string.IsNullOrEmpty(defToRemove) && swaggerDocument.Components.Schemas.ContainsKey(defToRemove)) { swaggerDocument.Components.Schemas.Remove(defToRemove); } } /* * List<string> responsesToRemove = new List<string>(); * * * foreach (string responseToRemove in responsesToRemove) * { * Console.Out.WriteLine($"Remove Response: {responseToRemove}"); * * if (!string.IsNullOrEmpty(responseToRemove) && swaggerDocument.Components.Responses.ContainsKey(responseToRemove)) * { * swaggerDocument.Components.Responses.Remove(responseToRemove); * } * * * } * */ /* * Cleanup definitions. */ foreach (var definition in swaggerDocument.Components.Schemas) { if (definition.Value.Description == null) { definition.Value.Description = definition.Key; } // consolidate AllOf if (definition.Value.AllOf != null && definition.Value.Type == null) { definition.Value.Type = "object"; } var dictionary = new Dictionary <string, OpenApiSchema>(); MergeSubItems(dictionary, definition.Value); definition.Value.Properties = dictionary; if (definition.Value.AllOf != null) { definition.Value.AllOf.Clear(); } // Clear out the example if it exists if (definition.Value.Example != null) { definition.Value.Example = null; } /* * if (definition.Value.Title != null) * { * definition.Value.Title = null; * } * * if (definition.Value.Enum != null) * { * definition.Value.Enum.Clear(); * } */ if (definition.Value != null && definition.Value.Properties != null) { foreach (var property in definition.Value.Properties) { // convert all dates to datetimeoffset. // special handling of the Dynamics "DATE (YYYY-MM-DD)" fields will need to be done with extensions. if (property.Value.Format != null && property.Value.Format == "date") { property.Value.Format = "date-time"; } if (property.Value.Type == null) { property.Value.Type = "string"; } // fix for doubles if (property.Value != null && property.Value.Format != null && property.Value.Format.Equals("double")) { property.Value.Format = "decimal"; property.Value.Type = "number"; } if (property.Key.Equals("totalamount")) { property.Value.Type = "number"; property.Value.Format = "decimal"; } if (property.Key.Equals("versionnumber")) { // clear oneof. if (property.Value.OneOf != null) { property.Value.OneOf.Clear(); } // force to string. property.Value.Type = "string"; } if (property.Value.Minimum != null) { property.Value.Minimum = null; } if (property.Value.Maximum != null) { property.Value.Maximum = null; } if (property.Value.Pattern != null) { property.Value.Pattern = null; } if (property.Value.Format != null && property.Value.Format == "uuid" && useStringForGuid) { property.Value.Format = null; } } } } // remove extra tags. swaggerDocument.Tags.Clear(); // cleanup parameters. //swaggerDocument.Components.Parameters.Clear(); //************************************** // fix for "odata.error.main" - innererror property. swaggerDocument.Components.Schemas["odata.error.main"].Properties.Remove("innererror"); // fix for two entities that have links to everything else - this causes massive spikes in memory consumption. swaggerDocument.Components.Schemas.Remove("Microsoft.Dynamics.CRM.transactioncurrency"); swaggerDocument.Components.Schemas.Remove("Microsoft.Dynamics.CRM.syncerror"); Dictionary <string, OpenApiSchema> props = new Dictionary <string, OpenApiSchema>(); props.Add("nil", new OpenApiSchema() { Type = "string" }); swaggerDocument.Components.Schemas.Add("Microsoft.Dynamics.CRM.transactioncurrency", new OpenApiSchema() { Properties = props }); swaggerDocument.Components.Schemas.Add("Microsoft.Dynamics.CRM.syncerror", new OpenApiSchema() { Properties = props }); // swagger = swaggerDocument.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0); // ToJson(SchemaType.Swagger2); swagger = swaggerDocument.SerializeAsJson(OpenApiSpecVersion.OpenApi2_0); } File.WriteAllText("dynamics-swagger.json", swagger); }
public static IServiceCollection AddYardarm(this IServiceCollection services, YardarmGenerationSettings settings, OpenApiDocument document) { services.AddDefaultEnrichers(); // Generators services .AddTransient <IReferenceGenerator, NuGetReferenceGenerator>() .AddTransient <ISyntaxTreeGenerator, AssemblyInfoGenerator>() .AddTransient <ISyntaxTreeGenerator, ClientGenerator>() .AddTransient <ISyntaxTreeGenerator, SchemaGenerator>() .AddTransient <ISyntaxTreeGenerator, SecuritySchemeGenerator>() .AddTransient <ISyntaxTreeGenerator, RequestBodyGenerator>() .AddTransient <ISyntaxTreeGenerator, ResponseGenerator>() .AddTransient <ISyntaxTreeGenerator, ResponseSetGenerator>() .AddTransient <ISyntaxTreeGenerator, RequestGenerator>() .AddTransient <ISyntaxTreeGenerator, TagGenerator>() .AddTransient <IDependencyGenerator, StandardDependencyGenerator>(); services.TryAddSingleton <ITypeGeneratorRegistry, TypeGeneratorRegistry>(); services.TryAdd(new ServiceDescriptor(typeof(ITypeGeneratorRegistry <>), typeof(TypeGeneratorRegistry <>), ServiceLifetime.Singleton)); services.TryAddSingleton <ITypeGeneratorFactory <OpenApiSchema>, DefaultSchemaGeneratorFactory>(); services.TryAddSingleton <ITypeGeneratorFactory <OpenApiSecurityScheme>, SecuritySchemeTypeGeneratorFactory>(); services.TryAddSingleton <ITypeGeneratorFactory <OpenApiRequestBody>, RequestBodyTypeGeneratorFactory>(); services.TryAddSingleton <ITypeGeneratorFactory <OpenApiResponse>, ResponseTypeGeneratorFactory>(); services.TryAddSingleton <ITypeGeneratorFactory <OpenApiResponses>, ResponseSetTypeGeneratorFactory>(); services.TryAddSingleton <ITypeGeneratorFactory <OpenApiOperation>, RequestTypeGeneratorFactory>(); services.TryAddSingleton <ITypeGeneratorFactory <OpenApiTag>, TagTypeGeneratorFactory>(); services.TryAddSingleton <ITypeGeneratorFactory <OpenApiUnknownResponse>, UnknownResponseTypeGeneratorFactory>(); services.TryAddSingleton <IAddHeadersMethodGenerator, AddHeadersMethodGenerator>(); services.TryAddSingleton <IBuildContentMethodGenerator, BuildContentMethodGenerator>(); services.TryAddSingleton <IBuildRequestMethodGenerator, BuildRequestMethodGenerator>(); services.TryAddSingleton <IBuildUriMethodGenerator, BuildUriMethodGenerator>(); services.TryAddSingleton <IGetBodyMethodGenerator, GetBodyMethodGenerator>(); services.TryAddSingleton <IOperationMethodGenerator, OperationMethodGenerator>(); services.TryAddSingleton <IMediaTypeSelector, JsonMediaTypeSelector>(); services.TryAddSingleton <IPackageSpecGenerator, DefaultPackageSpecGenerator>(); services.TryAddSingleton(serviceProvider => serviceProvider.GetRequiredService <IPackageSpecGenerator>().Generate()); // Names services.TryAddSingleton <CamelCaseNameFormatter>(); services.TryAddSingleton <PascalCaseNameFormatter>(); services.TryAddSingleton <INameFormatterSelector, DefaultNameFormatterSelector>(); services.TryAddSingleton <IElementTypeNameProvider, DefaultElementTypeNameProvider>(); services.TryAddSingleton <INamespaceProvider, DefaultNamespaceProvider>(); services.TryAddSingleton <IHttpResponseCodeNameProvider, HttpResponseCodeNameProvider>(); services.TryAddSingleton <IRootNamespace, RootNamespace>(); services.TryAddSingleton <IAuthenticationNamespace, AuthenticationNamespace>(); services.TryAddSingleton <IRequestsNamespace, RequestsNamespace>(); services.TryAddSingleton <IResponsesNamespace, ResponsesNamespace>(); services.TryAddSingleton <ISerializationNamespace, SerializationNamespace>(); // Other services .AddLogging() .AddSingleton <GenerationContext>() .AddSingleton(settings) .AddSingleton(document) .AddTransient <NuGetPacker>(); services.TryAddSingleton <IOpenApiElementRegistry, OpenApiElementRegistry>(); return(services); }
/// <summary> /// Create predicate function based on passed query parameters /// </summary> /// <param name="operationIds">Comma delimited list of operationIds or * for all operations.</param> /// <param name="tags">Comma delimited list of tags or a single regex.</param> /// <param name="url">Url path to match with Operation Ids.</param> /// <param name="graphVersion">Version of Microsoft Graph.</param> /// <param name="forceRefresh">Don't read from in-memory cache.</param> /// <returns>A predicate</returns> public static async Task <Func <OpenApiOperation, bool> > CreatePredicate(string operationIds, string tags, string url, OpenApiDocument source, bool forceRefresh = false) { if (url != null && (operationIds != null || tags != null)) { throw new InvalidOperationException("Cannot filter by url and either operationIds and tags at the same time."); } else if (operationIds != null && tags != null) { throw new InvalidOperationException("Cannot filter by operationIds and tags at the same time."); } Func <OpenApiOperation, bool> predicate; if (operationIds != null) { if (operationIds == "*") { predicate = (o) => true; // All operations } else { var operationIdsArray = operationIds.Split(','); predicate = (o) => operationIdsArray.Contains(o.OperationId); } } else if (tags != null) { var tagsArray = tags.Split(','); if (tagsArray.Length == 1) { var regex = new Regex(tagsArray[0]); predicate = (o) => o.Tags.Any(t => regex.IsMatch(t.Name)); } else { predicate = (o) => o.Tags.Any(t => tagsArray.Contains(t.Name)); } } else if (url != null) { /* Extract the respective Operation Id(s) that match the provided url path */ if (!_openApiOperationsTable.Any() || forceRefresh) { _uriTemplateTable = new UriTemplateMatcher(); _openApiOperationsTable = new Dictionary <int, OpenApiOperation[]>(); await PopulateReferenceTablesAync(source); } url = url.Replace('-', '_'); TemplateMatch resultMatch = _uriTemplateTable.Match(new Uri(url.ToLower(), UriKind.RelativeOrAbsolute)); if (resultMatch == null) { throw new ArgumentException("The url supplied could not be found."); } /* Fetch the corresponding Operations Id(s) for the matched url */ OpenApiOperation[] openApiOps = _openApiOperationsTable[int.Parse(resultMatch.Key)]; string[] operationIdsArray = openApiOps.Select(x => x.OperationId).ToArray(); predicate = (o) => operationIdsArray.Contains(o.OperationId); } else { throw new InvalidOperationException("Either operationIds, tags or url need to be specified."); } return(predicate); }
public void GetPathsByBasePathSegmentName(int expectedCount, string basePathSegmentName, OpenApiDocument openApiDocument) { // Act var actual = openApiDocument.GetPathsByBasePathSegmentName(basePathSegmentName); // Assert Assert.NotNull(actual); Assert.Equal(expectedCount, actual.Count); }
/// <summary> /// Validate if a resource has at least one 4xx and a 500 response. /// Supressions: Rule,Path,Operation,ResponseCode /// </summary> public ResponseWithout4xxAnd500Rule(OpenApiDocument contract, Supressions supressions, IOptions <RuleSettings> ruleSettings, OpenApiDocumentCache cache) : base(contract, supressions, ruleSettings, cache, ruleName, Severity.Warning) { }
/// <summary> /// Walks through the <see cref="OpenApiDocument"/> and validates each element. /// </summary> /// <param name="doc"></param> public void Walk(OpenApiDocument doc) { _visitor.Visit(doc); _visitor.Visit(doc.Info); _visitor.Visit(doc.Servers); if (doc.Servers != null) { foreach (var server in doc.Servers) { _visitor.Visit(server); foreach (var variable in server.Variables.Values) { _visitor.Visit(variable); } } } _visitor.Visit(doc.Paths); foreach (var pathItem in doc.Paths.Values) { _visitor.Visit(pathItem); _visitor.Visit(pathItem.Operations); foreach (var operation in pathItem.Operations.Values) { _visitor.Visit(operation); if (operation.Parameters != null) { _visitor.Visit(operation.Parameters); foreach (var parameter in operation.Parameters) { _visitor.Visit(parameter); } } if (operation.RequestBody != null) { _visitor.Visit(operation.RequestBody); if (operation.RequestBody.Content != null) { WalkContent(operation.RequestBody.Content); } } if (operation.Responses != null) { _visitor.Visit(operation.Responses); foreach (var response in operation.Responses.Values) { _visitor.Visit(response); WalkContent(response.Content); if (response.Links != null) { _visitor.Visit(response.Links); foreach (var link in response.Links.Values) { _visitor.Visit(link); } } } } } } }
public void Apply(OpenApiDocument model, DocumentFilterContext context) { Filter(model, context); }
/// <summary> /// Reads the stream input and parses it into an Open API document. /// </summary> /// <param name="input">Stream containing OpenAPI description to parse.</param> /// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param> /// <returns>Instance of newly created OpenApiDocument</returns> public OpenApiDocument Read(Stream input, out OpenApiDiagnostic diagnostic) { ParsingContext context; YamlDocument yamlDocument; diagnostic = new OpenApiDiagnostic(); // Parse the YAML/JSON try { yamlDocument = LoadYamlDocument(input); } catch (SyntaxErrorException ex) { diagnostic.Errors.Add(new OpenApiReaderError(ex)); return(new OpenApiDocument()); } context = new ParsingContext { ExtensionParsers = _settings.ExtensionParsers }; OpenApiDocument document = null; try { // Parse the OpenAPI Document document = context.Parse(yamlDocument, diagnostic); // Resolve References if requested switch (_settings.ReferenceResolution) { case ReferenceResolutionSetting.ResolveAllReferences: throw new ArgumentException(Properties.SRResource.CannotResolveRemoteReferencesSynchronously); case ReferenceResolutionSetting.ResolveLocalReferences: var resolver = new OpenApiReferenceResolver(document); var walker = new OpenApiWalker(resolver); walker.Walk(document); foreach (var item in resolver.Errors) { diagnostic.Errors.Add(item); } break; case ReferenceResolutionSetting.DoNotResolveReferences: break; } } catch (OpenApiException ex) { diagnostic.Errors.Add(new OpenApiError(ex)); } // Validate the document var errors = document.Validate(_settings.RuleSet); foreach (var item in errors) { diagnostic.Errors.Add(item); } return(document); }
public void When_parent_parameters_have_same_kind_then_they_are_included() { //// Arrange var swagger = @"{ ""swagger"" : ""2.0"", ""info"" : { ""version"" : ""1.0.2"", ""title"" : ""Test API"" }, ""host"" : ""localhost:8080"", ""basePath"" : ""/"", ""tags"" : [ { ""name"" : ""api"" } ], ""schemes"" : [ ""http"" ], ""paths"" : { ""/removeElement"" : { ""parameters"": [ { ""name"": ""SecureToken"", ""in"": ""header"", ""description"": ""cookie"", ""required"": true, ""type"": ""string"" } ], ""delete"" : { ""tags"" : [ ""api"" ], ""summary"" : ""Removes elements"", ""description"" : ""Removes elements"", ""operationId"" : ""removeElement"", ""consumes"" : [ ""application/json"" ], ""produces"" : [ ""application/json"" ], ""parameters"" : [ { ""name"" : ""X-User"", ""in"" : ""header"", ""description"" : ""User identifier"", ""required"" : true, ""type"" : ""string"" }, { ""name"" : ""elementId"", ""in"" : ""query"", ""description"" : ""The ids of existing elements that should be removed"", ""required"" : false, ""type"" : ""array"", ""items"" : { ""type"" : ""integer"", ""format"" : ""int64"" }, } ], ""responses"" : { ""default"" : { ""description"" : ""successful operation"" } } } } }, ""definitions"" : { } } "; var document = OpenApiDocument.FromJsonAsync(swagger).Result; //// Act var generator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings()); var code = generator.GenerateFile(); //// Assert Assert.Contains("RemoveElementAsync(string x_User, System.Collections.Generic.IEnumerable<long> elementId, string secureToken)", code); }
public void Deep_object_properties_are_correctly_named() { //// Arrange var swagger = @"{ 'openapi' : '3.0', 'info' : { 'version' : '1.0.2', 'title' : 'Test API' }, 'paths': { '/journeys': { 'get': { 'tags': [ 'CheckIn' ], 'summary': 'Retrieve journeys', 'operationId': 'retrieveJourneys', 'description': '', 'parameters': [ { 'name': 'lastName', 'in': 'query', 'schema': { 'type': 'string' } }, { 'name': 'eTicketNumber', 'in': 'query', 'schema': { 'type': 'string' } }, { 'name': 'options', 'in': 'query', 'style': 'deepObject', 'explode': true, 'schema': { '$ref': '#/components/schemas/Options' } } ], 'responses': {} } } }, 'components':{ 'schemas': { 'Options': { 'type':'object', 'properties': { 'optionalOrder.id': { 'schema': { 'type': 'string' } }, 'optionalFrequentFlyerCard.id':{ 'schema': { 'type': 'string' } }, 'optionalDepartureDate':{ 'schema': { 'type': 'string' } }, 'optionalOriginLocationCode':{ 'schema': { 'type': 'string' } } } } } } }"; var document = OpenApiDocument.FromJsonAsync(swagger, "", SchemaType.OpenApi3).Result; //// Act var generator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings()); var code = generator.GenerateFile(); //// Assert Assert.Contains("options[optionalOrder.id]=", code); Assert.Contains("options.OptionalOrderId", code); }
public void When_swagger_contains_optional_parameters_then_they_are_rendered_in_CSharp() { //// Arrange var swagger = @"{ ""paths"":{ ""/journeys"":{ ""get"":{ ""tags"":[ ""CheckIn"" ], ""summary"":""Retrieve journeys"", ""operationId"":""retrieveJourneys"", ""description"":"""", ""parameters"":[ { ""$ref"":""#/parameters/lastName"" }, { ""$ref"":""#/parameters/optionalOrderId"" }, { ""$ref"":""#/parameters/eTicketNumber"" }, { ""$ref"":""#/parameters/optionalFrequentFlyerCardId"" }, { ""$ref"":""#/parameters/optionalDepartureDate"" }, { ""$ref"":""#/parameters/optionalOriginLocationCode"" } ], ""responses"": {} } } }, ""parameters"":{ ""lastName"":{ ""name"":""lastName"", ""type"":""string"", ""required"":true }, ""optionalOrderId"":{ ""name"":""optionalOrderId"", ""type"":""string"", ""required"":false }, ""eTicketNumber"":{ ""name"":""eTicketNumber"", ""type"":""string"", ""required"":false }, ""optionalFrequentFlyerCardId"":{ ""name"":""optionalFrequentFlyerCardId"", ""type"":""string"", ""required"":false }, ""optionalDepartureDate"":{ ""name"":""optionalDepartureDate"", ""type"":""string"", ""required"":false }, ""optionalOriginLocationCode"":{ ""name"":""optionalOriginLocationCode"", ""type"":""string"", ""required"":false } } }"; var document = OpenApiDocument.FromJsonAsync(swagger).Result; //// Act var generator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings()); var code = generator.GenerateFile(); //// Assert Assert.Contains("lastName", code); Assert.Contains("optionalOrderId", code); }
public ContentResult GetV1OpenApi() { OpenApiDocument document = CreateDocument("v1"); return(CreateContent(document)); }
/// <inheritdoc /> public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { if (swaggerDoc == null) { throw new ArgumentNullException(nameof(swaggerDoc)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } swaggerDoc.Components.Parameters.Add(ApiHeaders.InstanceIdHeader, new OpenApiParameter { In = ParameterLocation.Header, Name = ApiHeaders.InstanceIdHeader, Description = "The instance ID being accessed", Required = true, Style = ParameterStyle.Simple, Schema = new OpenApiSchema { Type = "integer" } }); var productHeaderSchema = new OpenApiSchema { Type = "string", Format = "productheader" }; swaggerDoc.Components.Parameters.Add(ApiHeaders.ApiVersionHeader, new OpenApiParameter { In = ParameterLocation.Header, Name = ApiHeaders.ApiVersionHeader, Description = "The API version being used in the form \"Tgstation.Server.Api/[API version]\"", Required = true, Style = ParameterStyle.Simple, Example = new OpenApiString($"Tgstation.Server.Api/{ApiHeaders.Version}"), Schema = productHeaderSchema }); swaggerDoc.Components.Parameters.Add(HeaderNames.UserAgent, new OpenApiParameter { In = ParameterLocation.Header, Name = HeaderNames.UserAgent, Description = "The user agent of the calling client.", Required = true, Style = ParameterStyle.Simple, Example = new OpenApiString("Your-user-agent/1.0.0.0"), Schema = productHeaderSchema }); string bridgeOperationPath = null; foreach (var path in swaggerDoc.Paths) { foreach (var operation in path.Value.Operations.Select(x => x.Value)) { if (operation.OperationId.Equals("BridgeController.Process", StringComparison.Ordinal)) { bridgeOperationPath = path.Key; continue; } operation.Parameters.Add(new OpenApiParameter { Reference = new OpenApiReference { Type = ReferenceType.Parameter, Id = ApiHeaders.ApiVersionHeader }, }); operation.Parameters.Add(new OpenApiParameter { Reference = new OpenApiReference { Type = ReferenceType.Parameter, Id = HeaderNames.UserAgent } }); } } swaggerDoc.Paths.Remove(bridgeOperationPath); AddDefaultResponses(swaggerDoc); }
public void ParseCompleteSwagger() { var vocab = OpenApiVocab.Create(); var stream = this.GetType().Assembly .GetManifestResourceStream(this.GetType(), "forecast.io.swagger.json"); var swaggerDoc = new OpenApiDocument(); JsonStreamingParser.ParseStream(stream, swaggerDoc, vocab); Assert.Equal("2.0", swaggerDoc.Version); Assert.Equal(1, swaggerDoc.Schemes.Count); Assert.Equal("https", swaggerDoc.Schemes.First()); Assert.Equal(1, swaggerDoc.Paths.Count ); Assert.Equal(swaggerDoc.Paths.Keys.First(), "/forecast/{apiKey}/{latitude},{longitude}"); var path = swaggerDoc.Paths.Values.First(); Assert.Equal(1, path.Operations.Count); var operation = path.Operations.Values.First(); Assert.Equal("Forecast", operation.Id); Assert.False(String.IsNullOrEmpty(swaggerDoc.Info.Description)); Assert.False(String.IsNullOrEmpty(swaggerDoc.Info.Title)); Assert.True(String.IsNullOrEmpty(swaggerDoc.Info.Version)); }
static void AddDefaultResponses(OpenApiDocument document) { var errorMessageContent = new Dictionary <string, OpenApiMediaType> { { ApiHeaders.ApplicationJson, new OpenApiMediaType { Schema = new OpenApiSchema { Reference = new OpenApiReference { Id = nameof(ErrorMessage), Type = ReferenceType.Schema } } } } }; void AddDefaultResponse(HttpStatusCode code, OpenApiResponse concrete) { string responseKey = $"{(int)code}"; document.Components.Responses.Add(responseKey, concrete); var referenceResponse = new OpenApiResponse { Reference = new OpenApiReference { Type = ReferenceType.Response, Id = responseKey } }; foreach (var operation in document.Paths.SelectMany(path => path.Value.Operations)) { operation.Value.Responses.TryAdd(responseKey, referenceResponse); } } AddDefaultResponse(HttpStatusCode.BadRequest, new OpenApiResponse { Description = "A badly formatted request was made. See error message for details.", Content = errorMessageContent, }); AddDefaultResponse(HttpStatusCode.Unauthorized, new OpenApiResponse { Description = "No/invalid token provided." }); AddDefaultResponse(HttpStatusCode.Forbidden, new OpenApiResponse { Description = "User lacks sufficient permissions for the operation." }); AddDefaultResponse(HttpStatusCode.Conflict, new OpenApiResponse { Description = "A data integrity check failed while performing the operation. See error message for details.", Content = errorMessageContent }); AddDefaultResponse(HttpStatusCode.InternalServerError, new OpenApiResponse { Description = "The server encountered an unhandled error. See error message for details.", Content = errorMessageContent }); AddDefaultResponse(HttpStatusCode.ServiceUnavailable, new OpenApiResponse { Description = "The server may be starting up or shutting down." }); AddDefaultResponse(HttpStatusCode.NotImplemented, new OpenApiResponse { Description = "This operation requires POSIX system identites to be implemented. See https://github.com/tgstation/tgstation-server/issues/709", Content = errorMessageContent }); }
/// <summary> /// 生成内容 /// </summary> /// <param name="document">对象</param> /// <param name="content">内容</param> /// <returns></returns> internal static string GeneratorContent(OpenApiDocument document, string content) { var result = Engine.Razor.RunCompile(content, "api", typeof(OpenApiDocument), document); return(result); }
/// <summary> /// Add the default error responses to a given <paramref name="document"/>. /// </summary> /// <param name="document">The <see cref="OpenApiDocument"/> to augment.</param> static void AddDefaultResponses(OpenApiDocument document) { var errorMessageContent = new Dictionary <string, OpenApiMediaType> { { MediaTypeNames.Application.Json, new OpenApiMediaType { Schema = new OpenApiSchema { Reference = new OpenApiReference { Id = nameof(ErrorMessageResponse), Type = ReferenceType.Schema, }, }, } }, }; void AddDefaultResponse(HttpStatusCode code, OpenApiResponse concrete) { string responseKey = $"{(int)code}"; document.Components.Responses.Add(responseKey, concrete); var referenceResponse = new OpenApiResponse { Reference = new OpenApiReference { Type = ReferenceType.Response, Id = responseKey, }, }; foreach (var operation in document.Paths.SelectMany(path => path.Value.Operations)) { operation.Value.Responses.TryAdd(responseKey, referenceResponse); } } AddDefaultResponse(HttpStatusCode.BadRequest, new OpenApiResponse { Description = "A badly formatted request was made. See error message for details.", Content = errorMessageContent, }); AddDefaultResponse(HttpStatusCode.Unauthorized, new OpenApiResponse { Description = "Invalid Authentication header.", }); AddDefaultResponse(HttpStatusCode.Forbidden, new OpenApiResponse { Description = "User lacks sufficient permissions for the operation.", }); AddDefaultResponse(HttpStatusCode.Conflict, new OpenApiResponse { Description = "A data integrity check failed while performing the operation. See error message for details.", Content = errorMessageContent, }); AddDefaultResponse(HttpStatusCode.NotAcceptable, new OpenApiResponse { Description = $"Invalid Accept header, TGS requires `{HeaderNames.Accept}: {MediaTypeNames.Application.Json}`.", Content = errorMessageContent, }); AddDefaultResponse(HttpStatusCode.InternalServerError, new OpenApiResponse { Description = ErrorCode.InternalServerError.Describe(), Content = errorMessageContent, }); AddDefaultResponse(HttpStatusCode.ServiceUnavailable, new OpenApiResponse { Description = "The server may be starting up or shutting down.", }); AddDefaultResponse(HttpStatusCode.NotImplemented, new OpenApiResponse { Description = ErrorCode.RequiresPosixSystemIdentity.Describe(), Content = errorMessageContent, }); }
/// <summary> /// Compares two <see cref="OpenApiDocument"/>s and returns a list of differences. /// </summary> public static List <OpenApiDifference> Compare(OpenApiDocument source, OpenApiDocument target) { var diffs = new List <OpenApiDifference>(); return(diffs); }
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { swaggerDoc.Extensions.Add("X-foo", new OpenApiString("bar")); swaggerDoc.Extensions.Add("X-docName", new OpenApiString(context.DocumentName)); }
/// <summary> /// Remove Paths and Components from OpenApi documentation without accepted roles. /// </summary> /// <param name="openApiDoc"><see cref="OpenApiDocument"/>.</param> /// <param name="paths">Dictionary of openApi paths with <see cref="MethodInfo"/> keys.</param> /// <param name="schemas">Dictionary with openApi schemas with scheme name keys.</param> /// <param name="acceptedRoles">Collection of accepted roles.</param> internal static void RemovePathsAndComponents( OpenApiDocument openApiDoc, IDictionary <(MethodInfo ActionMethodInfo, Type ControllerType), string> paths,
/// <summary> /// Visits <see cref="OpenApiDocument"/> /// </summary> public virtual void Visit(OpenApiDocument doc) { }
/// <summary> /// Create partial document based on provided predicate /// </summary> public static OpenApiDocument CreateFilteredDocument(OpenApiDocument source, string title, string graphVersion, Func <OpenApiOperation, bool> predicate) { var subset = new OpenApiDocument { Info = new OpenApiInfo() { Title = title, Version = graphVersion }, Components = new OpenApiComponents() }; var aadv2Scheme = new OpenApiSecurityScheme() { Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows() { AuthorizationCode = new OpenApiOAuthFlow() { AuthorizationUrl = new Uri(GraphConstants.GraphAuthorizationUrl), TokenUrl = new Uri(GraphConstants.GraphTokenUrl) } }, Reference = new OpenApiReference() { Id = "azureaadv2", Type = ReferenceType.SecurityScheme }, UnresolvedReference = false }; subset.Components.SecuritySchemes.Add("azureaadv2", aadv2Scheme); subset.SecurityRequirements.Add(new OpenApiSecurityRequirement() { { aadv2Scheme, new string[] { } } }); subset.Servers.Add(new OpenApiServer() { Description = "Core", Url = string.Format(GraphConstants.GraphUrl, graphVersion) }); var results = FindOperations(source, predicate); foreach (var result in results) { OpenApiPathItem pathItem; if (subset.Paths == null) { subset.Paths = new OpenApiPaths(); pathItem = new OpenApiPathItem(); subset.Paths.Add(result.CurrentKeys.Path, pathItem); } else { if (!subset.Paths.TryGetValue(result.CurrentKeys.Path, out pathItem)) { pathItem = new OpenApiPathItem(); subset.Paths.Add(result.CurrentKeys.Path, pathItem); } } pathItem.Operations.Add((OperationType)result.CurrentKeys.Operation, result.Operation); } CopyReferences(subset); return(subset); }
public OpenApiValidatorHandler(OpenApiDocument openApiDocument, HttpMessageHandler innerHandler) : base(innerHandler) { _openApiDocument = openApiDocument; }
public static OpenApiDocument CreateFilteredDocument(string title, string version, OpenApiDocument source, Func <OpenApiOperation, bool> predicate) { var subset = new OpenApiDocument { Info = new OpenApiInfo() { Title = title, Version = version }, Components = new OpenApiComponents() }; var aadv2Scheme = new OpenApiSecurityScheme() { Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows() { AuthorizationCode = new OpenApiOAuthFlow() { AuthorizationUrl = new Uri("https://login.microsoftonline.com/common/oauth2/v2.0/authorize"), TokenUrl = new Uri("https://login.microsoftonline.com/common/oauth2/v2.0/token") } }, Reference = new OpenApiReference() { Id = "azureaadv2", Type = ReferenceType.SecurityScheme }, UnresolvedReference = false }; subset.Components.SecuritySchemes.Add("azureaadv2", aadv2Scheme); subset.SecurityRequirements.Add(new OpenApiSecurityRequirement() { { aadv2Scheme, new string[] { } } }); subset.Servers.Add(new OpenApiServer() { Description = "Core", Url = "https://graph.microsoft.com/v1.0/" }); var operationObjects = new List <OpenApiOperation>(); var results = FindOperations(source, predicate); foreach (var result in results) { OpenApiPathItem pathItem = null; if (subset.Paths == null) { subset.Paths = new OpenApiPaths(); pathItem = new OpenApiPathItem(); subset.Paths.Add(result.CurrentKeys.Path, pathItem); } else { if (!subset.Paths.TryGetValue(result.CurrentKeys.Path, out pathItem)) { pathItem = new OpenApiPathItem(); subset.Paths.Add(result.CurrentKeys.Path, pathItem); } } pathItem.Operations.Add((OperationType)result.CurrentKeys.Operation, result.Operation); } return(subset); }
public OpenApiValidatorHandler(OpenApiDocument openApiDocument) : this(openApiDocument, new HttpClientHandler()) { }
private List <Type> GenerateForControllers( OpenApiDocument document, IGrouping <Type, Tuple <ApiDescription, ControllerActionDescriptor> >[] apiGroups, OpenApiSchemaResolver schemaResolver) { var usedControllerTypes = new List <Type>(); var swaggerGenerator = new OpenApiDocumentGenerator(Settings, schemaResolver); var allOperations = new List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> >(); foreach (var controllerApiDescriptionGroup in apiGroups) { var controllerType = controllerApiDescriptionGroup.Key; var hasIgnoreAttribute = controllerType.GetTypeInfo() .GetCustomAttributes() .GetAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name) .Any(); if (!hasIgnoreAttribute) { var operations = new List <Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo> >(); foreach (var item in controllerApiDescriptionGroup) { var apiDescription = item.Item1; var method = item.Item2.MethodInfo; var actionHasIgnoreAttribute = method.GetCustomAttributes().GetAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name).Any(); if (actionHasIgnoreAttribute) { continue; } var path = apiDescription.RelativePath; if (!path.StartsWith("/", StringComparison.Ordinal)) { path = "/" + path; } var controllerActionDescriptor = (ControllerActionDescriptor)apiDescription.ActionDescriptor; var httpMethod = apiDescription.HttpMethod?.ToLowerInvariant() ?? OpenApiOperationMethod.Get; var operationDescription = new OpenApiOperationDescription { Path = path, Method = httpMethod, Operation = new OpenApiOperation { IsDeprecated = IsOperationDeprecated(item.Item1, controllerActionDescriptor, method), OperationId = GetOperationId(document, controllerActionDescriptor, method), Consumes = apiDescription.SupportedRequestFormats .Select(f => f.MediaType) .Distinct() .ToList(), Produces = apiDescription.SupportedResponseTypes .SelectMany(t => t.ApiResponseFormats.Select(f => f.MediaType)) .Distinct() .ToList() } }; operations.Add(new Tuple <OpenApiOperationDescription, ApiDescription, MethodInfo>(operationDescription, apiDescription, method)); } var addedOperations = AddOperationDescriptionsToDocument(document, controllerType, operations, swaggerGenerator, schemaResolver); if (addedOperations.Any()) { usedControllerTypes.Add(controllerApiDescriptionGroup.Key); } allOperations.AddRange(addedOperations); } } UpdateConsumesAndProduces(document, allOperations); return(usedControllerTypes); }
private static TypeScriptClientGenerator CreateGenerator(OpenApiDocument document) { return(new TypeScriptClientGenerator(document, SettingsFactory.TpeScripGeneratorSettings)); }
public ContentResult GetOpenApi() { OpenApiDocument document = CreateDocument(string.Empty); return(CreateContent(document)); }
private static string GetSanitizeTitle(this OpenApiDocument document) => RemoveCharacters( document.Info.Title, "Swagger", " ", ".", "-");
public ContentResult GetV2OpenApi(string data) { OpenApiDocument document = CreateDocument("v2{data}"); return(CreateContent(document)); }
public void ParseSwaggerPaths() { var opsTerm = new VocabTerm<Operation>(); var pathTerm = new VocabTerm<Path>(); pathTerm.MapAnyObject<Operation>(opsTerm, (s, p) => { return s.AddOperation(p, Guid.NewGuid().ToString()); }); var pathsTerm = new VocabTerm<OpenApiDocument>("paths"); pathsTerm.MapAnyObject<Path>(pathTerm,(s,p) => { return s.AddPath(p); }); var rootTerm = new VocabTerm<OpenApiDocument>(); rootTerm.MapObject<OpenApiDocument>(pathsTerm, (s) => { return s; }); var stream = this.GetType().Assembly .GetManifestResourceStream(this.GetType(), "forecast.io.swagger.json"); var swaggerDoc = new OpenApiDocument(); JsonStreamingParser.ParseStream(stream, swaggerDoc, rootTerm); Assert.Equal(1, swaggerDoc.Paths.Count); Assert.Equal(1, swaggerDoc.Paths.First().Value.Operations.Count()); }