ShowOpenApiDocumentAsync(HidiOptions options, ILogger logger, CancellationToken cancellationToken = default)
- {
- try
- {
- if (string.IsNullOrEmpty(options.OpenApi) && string.IsNullOrEmpty(options.Csdl))
- {
- throw new ArgumentException("Please input a file path or URL");
- }
-
- var openApiFormat = options.OpenApiFormat ?? (!string.IsNullOrEmpty(options.OpenApi) ? GetOpenApiFormat(options.OpenApi, logger) : OpenApiConstants.Yaml);
- var document = await GetOpenApiAsync(options, openApiFormat, logger, null, cancellationToken).ConfigureAwait(false);
- if (document is not null)
- {
- using (logger.BeginScope("Creating diagram"))
- {
- // If output is null, create a HTML file in the user's temporary directory
- var sourceUrl = (string.IsNullOrEmpty(options.OpenApi), string.IsNullOrEmpty(options.Csdl)) switch
- {
- (false, _) => options.OpenApi!,
- (_, false) => options.Csdl!,
- _ => throw new InvalidOperationException("No input file path or URL provided")
- };
- if (options.Output == null)
- {
- var tempPath = Path.GetTempPath() + "/hidi/";
- if (!File.Exists(tempPath))
- {
- Directory.CreateDirectory(tempPath);
- }
-
- var fileName = Path.GetRandomFileName();
-
- var output = new FileInfo(Path.Combine(tempPath, fileName + ".html"));
- using (var file = new FileStream(output.FullName, FileMode.Create))
- {
- using var writer = new StreamWriter(file);
- WriteTreeDocumentAsHtml(sourceUrl, document, writer);
- }
- logger.LogTrace("Created Html document with diagram ");
-
- // Launch a browser to display the output html file
- using var process = new Process();
- process.StartInfo.FileName = output.FullName;
- process.StartInfo.UseShellExecute = true;
- process.Start();
-
- return output.FullName;
- }
- else // Write diagram as Markdown document to output file
- {
- using var file = new FileStream(options.Output.FullName, FileMode.Create);
- using var writer = new StreamWriter(file);
- WriteTreeDocumentAsMarkdown(sourceUrl, document, writer);
-
- logger.LogTrace("Created markdown document with diagram ");
- return options.Output.FullName;
- }
- }
- }
- }
- catch (TaskCanceledException)
- {
- await Console.Error.WriteLineAsync("CTRL+C pressed, aborting the operation.").ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- throw new InvalidOperationException($"Could not generate the document, reason: {ex.Message}", ex);
- }
- return null;
- }
-
- private static void LogErrors(ILogger logger, ReadResult result)
- {
- var context = result.Diagnostic;
- if (context is { Errors.Count: > 0 })
- {
- using (logger.BeginScope("Detected errors"))
- {
- foreach (var error in context.Errors)
- {
- logger.LogError("Detected error during parsing: {Error}", error.ToString());
- }
- }
- }
- }
-
- private static void LogWarnings(ILogger logger, ReadResult result)
- {
- var context = result.Diagnostic;
- if (context is { Warnings.Count: > 0 })
- {
- using (logger.BeginScope("Detected warnings"))
- {
- foreach (var warning in context.Warnings)
- {
- logger.LogWarning("Detected warning during parsing: {Warning}", warning.ToString());
- }
- }
- }
- }
-
- internal static void WriteTreeDocumentAsMarkdown(string openapiUrl, OpenApiDocument document, StreamWriter writer)
- {
- var rootNode = OpenApiUrlTreeNode.Create(document, "main");
-
- writer.WriteLine("# " + document.Info.Title);
- writer.WriteLine();
- writer.WriteLine("API Description: " + openapiUrl);
-
- writer.WriteLine(@"");
- // write a span for each mermaidcolorscheme
- foreach (var style in OpenApiUrlTreeNode.MermaidNodeStyles)
- {
- writer.WriteLine($"{style.Key.Replace("_", " ", StringComparison.OrdinalIgnoreCase)}");
- }
- writer.WriteLine("
");
- writer.WriteLine();
- writer.WriteLine("```mermaid");
- rootNode.WriteMermaid(writer);
- writer.WriteLine("```");
- }
-
- internal static void WriteTreeDocumentAsHtml(string sourceUrl, OpenApiDocument document, StreamWriter writer, bool asHtmlFile = false)
- {
- var rootNode = OpenApiUrlTreeNode.Create(document, "main");
-
- writer.WriteLine(
- """
-
-
-
-
-
-
-
-
- """);
- writer.WriteLine("" + document?.Info.Title + "
");
- writer.WriteLine();
- writer.WriteLine($"");
-
- writer.WriteLine(@"");
- // write a span for each mermaidcolorscheme
- foreach (var style in OpenApiUrlTreeNode.MermaidNodeStyles)
- {
- writer.WriteLine($"{style.Key.Replace("_", " ", StringComparison.OrdinalIgnoreCase)}");
- }
-
- writer.WriteLine("
");
- writer.WriteLine("
");
- writer.WriteLine("");
- rootNode.WriteMermaid(writer);
- writer.WriteLine("");
-
- // Write script tag to include JS library for rendering markdown
- writer.WriteLine(
- """
-
- """);
- // Write script tag to include JS library for rendering mermaid
- writer.WriteLine(" OpenApiDescriptionOption = new("--openapi", "-d")
- {
- Description = "Input OpenAPI description file path or URL",
- };
- public readonly Option CsdlOption = new("--csdl", "--cs")
- {
- Description = "Input CSDL file path or URL",
- };
- public readonly Option CsdlFilterOption = new("--csdl-filter", "--csf")
- {
- Description = "Comma delimited list of EntitySets or Singletons to filter CSDL on. e.g. tasks,accounts",
- };
- public readonly Option OutputOption = new("--output", "-o")
- {
- Description = "The output file path for the generated file.",
- Arity = ArgumentArity.ZeroOrOne
- };
- public readonly Option OutputFolderOption = new("--output-folder", "--of")
- {
- Description = "The output directory path for the generated files.",
- Arity = ArgumentArity.ZeroOrOne
- };
- public readonly Option CleanOutputOption = new("--clean-output", "--co")
- {
- Description = "Overwrite an existing file",
- };
- public readonly Option VersionOption = new("--version", "-v")
- {
- Description = "OpenAPI specification version",
- };
- public readonly Option MetadataVersionOption = new("--metadata-version", "--mv")
- {
- Description = "Graph metadata version to use.",
- };
- public readonly Option FormatOption = new("--format", "-f")
- {
- Description = "File format",
- };
- public readonly Option TerseOutputOption = new("--terse-output", "--to")
- {
- Description = "Produce terse json output",
- };
- public readonly Option SettingsFileOption = new("--settings-path", "--sp")
- {
- Description = "The configuration file with CSDL conversion settings.",
- };
- public readonly Option LogLevelOption = new("--log-level", "--ll")
- {
- Description = "The log level to use when logging messages to the main output.",
- DefaultValueFactory = (_) => LogLevel.Information,
- };
- public readonly Option FilterByOperationIdsOption = new("--filter-by-operationids", "--op")
- {
- Description = "Filters OpenApiDocument by comma delimited list of OperationId(s) provided",
- };
- public readonly Option FilterByTagsOption = new("--filter-by-tags", "-t")
- {
- Description = "Filters OpenApiDocument by comma delimited list of Tag(s) provided. Also accepts a single regex.",
- };
- public readonly Option FilterByCollectionOption = new("--filter-by-collection", "-c")
- {
- Description = "Filters OpenApiDocument by Postman collection provided. Provide path to collection file.",
- };
- public readonly Option ManifestOption = new("--manifest", "-m")
- {
- Description = "Path to API manifest file to locate and filter an OpenApiDocument",
- };
- public readonly Option InlineLocalOption = new("--inline-local", "--il")
- {
- Description = "Inline local $ref instances",
- };
- public readonly Option InlineExternalOption = new("--inline-external", "--ie")
- {
- Description = "Inline external $ref instances",
- };
-
- public IReadOnlyList