@@ -94,7 +94,7 @@ public static async Task TransformOpenApiDocumentAsync(HidiOptions options, ILog
94
94
// Load OpenAPI document
95
95
var document = await GetOpenApiAsync ( options , openApiFormat . GetDisplayName ( ) , logger , options . MetadataVersion , cancellationToken ) . ConfigureAwait ( false ) ;
96
96
97
- if ( options . FilterOptions != null )
97
+ if ( options . FilterOptions != null && document is not null )
98
98
{
99
99
document = ApplyFilters ( options , logger , apiDependency , postmanCollection , document ) ;
100
100
}
@@ -107,7 +107,11 @@ public static async Task TransformOpenApiDocumentAsync(HidiOptions options, ILog
107
107
var walker = new OpenApiWalker ( powerShellFormatter ) ;
108
108
walker . Walk ( document ) ;
109
109
}
110
- await WriteOpenApiAsync ( options , openApiFormat , openApiVersion , document , logger , cancellationToken ) . ConfigureAwait ( false ) ;
110
+ if ( document is not null )
111
+ {
112
+ // Write the OpenAPI document to the output file
113
+ await WriteOpenApiAsync ( options , openApiFormat , openApiVersion , document , logger , cancellationToken ) . ConfigureAwait ( false ) ;
114
+ }
111
115
}
112
116
catch ( TaskCanceledException )
113
117
{
@@ -172,7 +176,7 @@ private static OpenApiDocument ApplyFilters(HidiOptions options, ILogger logger,
172
176
options . FilterOptions . FilterByTags ,
173
177
requestUrls ,
174
178
document ,
175
- logger ) ;
179
+ logger ) ;
176
180
if ( predicate != null )
177
181
{
178
182
var stopwatch = new Stopwatch ( ) ;
@@ -210,6 +214,7 @@ private static async Task WriteOpenApiAsync(HidiOptions options, OpenApiFormat o
210
214
211
215
var stopwatch = new Stopwatch ( ) ;
212
216
stopwatch . Start ( ) ;
217
+
213
218
await document . SerializeAsync ( writer , openApiVersion , cancellationToken ) . ConfigureAwait ( false ) ;
214
219
stopwatch . Stop ( ) ;
215
220
@@ -219,9 +224,9 @@ private static async Task WriteOpenApiAsync(HidiOptions options, OpenApiFormat o
219
224
}
220
225
221
226
// Get OpenAPI document either from OpenAPI or CSDL
222
- private static async Task < OpenApiDocument > GetOpenApiAsync ( HidiOptions options , string format , ILogger logger , string ? metadataVersion = null , CancellationToken cancellationToken = default )
227
+ private static async Task < OpenApiDocument ? > GetOpenApiAsync ( HidiOptions options , string format , ILogger logger , string ? metadataVersion = null , CancellationToken cancellationToken = default )
223
228
{
224
- OpenApiDocument document ;
229
+ OpenApiDocument ? document ;
225
230
Stream stream ;
226
231
227
232
if ( ! string . IsNullOrEmpty ( options . Csdl ) )
@@ -242,7 +247,7 @@ private static async Task<OpenApiDocument> GetOpenApiAsync(HidiOptions options,
242
247
243
248
document = await ConvertCsdlToOpenApiAsync ( filteredStream ?? stream , format , metadataVersion , options . SettingsConfig , cancellationToken ) . ConfigureAwait ( false ) ;
244
249
stopwatch . Stop ( ) ;
245
- logger . LogTrace ( "{Timestamp}ms: Generated OpenAPI with {Paths} paths." , stopwatch . ElapsedMilliseconds , document . Paths . Count ) ;
250
+ logger . LogTrace ( "{Timestamp}ms: Generated OpenAPI with {Paths} paths." , stopwatch . ElapsedMilliseconds , document ? . Paths . Count ) ;
246
251
}
247
252
}
248
253
else if ( ! string . IsNullOrEmpty ( options . OpenApi ) )
@@ -370,7 +375,7 @@ private static MemoryStream ApplyFilterToCsdl(Stream csdlStream, string entitySe
370
375
371
376
if ( result is null ) return null ;
372
377
373
- return result . Diagnostic . Errors . Count == 0 ;
378
+ return result . Diagnostic ? . Errors . Count == 0 ;
374
379
}
375
380
376
381
private static async Task < ReadResult > ParseOpenApiAsync ( string openApiFile , bool inlineExternal , ILogger logger , Stream stream , CancellationToken cancellationToken = default )
@@ -407,7 +412,7 @@ private static async Task<ReadResult> ParseOpenApiAsync(string openApiFile, bool
407
412
/// </summary>
408
413
/// <param name="csdl">The CSDL stream.</param>
409
414
/// <returns>An OpenAPI document.</returns>
410
- public static async Task < OpenApiDocument > ConvertCsdlToOpenApiAsync ( Stream csdl , string format , string ? metadataVersion = null , IConfiguration ? settings = null , CancellationToken token = default )
415
+ public static async Task < OpenApiDocument ? > ConvertCsdlToOpenApiAsync ( Stream csdl , string format , string ? metadataVersion = null , IConfiguration ? settings = null , CancellationToken token = default )
411
416
{
412
417
using var reader = new StreamReader ( csdl ) ;
413
418
var csdlText = await reader . ReadToEndAsync ( token ) . ConfigureAwait ( false ) ;
@@ -425,7 +430,7 @@ public static async Task<OpenApiDocument> ConvertCsdlToOpenApiAsync(Stream csdl,
425
430
/// </summary>
426
431
/// <param name="document"> The converted OpenApiDocument.</param>
427
432
/// <returns> A valid OpenApiDocument instance.</returns>
428
- public static OpenApiDocument FixReferences ( OpenApiDocument document , string format )
433
+ public static OpenApiDocument ? FixReferences ( OpenApiDocument document , string format )
429
434
{
430
435
// This method is only needed because the output of ConvertToOpenApi isn't quite a valid OpenApiDocument instance.
431
436
// So we write it out, and read it back in again to fix it up.
@@ -584,52 +589,54 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl
584
589
585
590
var openApiFormat = options . OpenApiFormat ?? ( ! string . IsNullOrEmpty ( options . OpenApi ) ? GetOpenApiFormat ( options . OpenApi , logger ) : OpenApiFormat . Yaml ) ;
586
591
var document = await GetOpenApiAsync ( options , openApiFormat . GetDisplayName ( ) , logger , null , cancellationToken ) . ConfigureAwait ( false ) ;
587
-
588
- using ( logger . BeginScope ( "Creating diagram" ) )
592
+ if ( document is not null )
589
593
{
590
- // If output is null, create a HTML file in the user's temporary directory
591
- var sourceUrl = ( string . IsNullOrEmpty ( options . OpenApi ) , string . IsNullOrEmpty ( options . Csdl ) ) switch {
592
- ( false , _ ) => options . OpenApi ! ,
593
- ( _, false ) => options . Csdl ! ,
594
- _ => throw new InvalidOperationException ( "No input file path or URL provided" )
595
- } ;
596
- if ( options . Output == null )
594
+ using ( logger . BeginScope ( "Creating diagram" ) )
597
595
{
598
- var tempPath = Path . GetTempPath ( ) + "/hidi/" ;
599
- if ( ! File . Exists ( tempPath ) )
596
+ // If output is null, create a HTML file in the user's temporary directory
597
+ var sourceUrl = ( string . IsNullOrEmpty ( options . OpenApi ) , string . IsNullOrEmpty ( options . Csdl ) ) switch
600
598
{
601
- Directory . CreateDirectory ( tempPath ) ;
602
- }
603
-
604
- var fileName = Path . GetRandomFileName ( ) ;
605
-
606
- var output = new FileInfo ( Path . Combine ( tempPath , fileName + ".html" ) ) ;
607
- using ( var file = new FileStream ( output . FullName , FileMode . Create ) )
599
+ ( false , _ ) => options . OpenApi ! ,
600
+ ( _, false ) => options . Csdl ! ,
601
+ _ => throw new InvalidOperationException ( "No input file path or URL provided" )
602
+ } ;
603
+ if ( options . Output == null )
608
604
{
609
- using var writer = new StreamWriter ( file ) ;
610
- WriteTreeDocumentAsHtml ( sourceUrl , document , writer ) ;
605
+ var tempPath = Path . GetTempPath ( ) + "/hidi/" ;
606
+ if ( ! File . Exists ( tempPath ) )
607
+ {
608
+ Directory . CreateDirectory ( tempPath ) ;
609
+ }
610
+
611
+ var fileName = Path . GetRandomFileName ( ) ;
612
+
613
+ var output = new FileInfo ( Path . Combine ( tempPath , fileName + ".html" ) ) ;
614
+ using ( var file = new FileStream ( output . FullName , FileMode . Create ) )
615
+ {
616
+ using var writer = new StreamWriter ( file ) ;
617
+ WriteTreeDocumentAsHtml ( sourceUrl , document , writer ) ;
618
+ }
619
+ logger . LogTrace ( "Created Html document with diagram " ) ;
620
+
621
+ // Launch a browser to display the output html file
622
+ using var process = new Process ( ) ;
623
+ process . StartInfo . FileName = output . FullName ;
624
+ process . StartInfo . UseShellExecute = true ;
625
+ process . Start ( ) ;
626
+
627
+ return output . FullName ;
611
628
}
612
- logger . LogTrace ( "Created Html document with diagram " ) ;
613
-
614
- // Launch a browser to display the output html file
615
- using var process = new Process ( ) ;
616
- process . StartInfo . FileName = output . FullName ;
617
- process . StartInfo . UseShellExecute = true ;
618
- process . Start ( ) ;
619
-
620
- return output . FullName ;
621
- }
622
- else // Write diagram as Markdown document to output file
623
- {
624
- using ( var file = new FileStream ( options . Output . FullName , FileMode . Create ) )
629
+ else // Write diagram as Markdown document to output file
625
630
{
631
+ using var file = new FileStream ( options . Output . FullName , FileMode . Create ) ;
626
632
using var writer = new StreamWriter ( file ) ;
627
633
WriteTreeDocumentAsMarkdown ( sourceUrl , document , writer ) ;
634
+
635
+ logger . LogTrace ( "Created markdown document with diagram " ) ;
636
+ return options . Output . FullName ;
628
637
}
629
- logger . LogTrace ( "Created markdown document with diagram " ) ;
630
- return options . Output . FullName ;
631
638
}
632
- }
639
+ }
633
640
}
634
641
catch ( TaskCanceledException )
635
642
{
@@ -645,7 +652,7 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl
645
652
private static void LogErrors ( ILogger logger , ReadResult result )
646
653
{
647
654
var context = result . Diagnostic ;
648
- if ( context . Errors . Count != 0 )
655
+ if ( context is not null && context . Errors . Count != 0 )
649
656
{
650
657
using ( logger . BeginScope ( "Detected errors" ) )
651
658
{
@@ -697,7 +704,7 @@ internal static void WriteTreeDocumentAsHtml(string sourceUrl, OpenApiDocument d
697
704
</style>
698
705
<body>
699
706
""" ) ;
700
- writer . WriteLine ( "<h1>" + document . Info . Title + "</h1>" ) ;
707
+ writer . WriteLine ( "<h1>" + document ? . Info . Title + "</h1>" ) ;
701
708
writer . WriteLine ( ) ;
702
709
writer . WriteLine ( $ "<h3> API Description: <a href='{ sourceUrl } '>{ sourceUrl } </a></h3>") ;
703
710
@@ -751,7 +758,7 @@ internal static async Task PluginManifestAsync(HidiOptions options, ILogger logg
751
758
752
759
cancellationToken . ThrowIfCancellationRequested ( ) ;
753
760
754
- if ( options . FilterOptions != null )
761
+ if ( options . FilterOptions != null && document is not null )
755
762
{
756
763
document = ApplyFilters ( options , logger , apiDependency , null , document ) ;
757
764
}
@@ -765,24 +772,31 @@ internal static async Task PluginManifestAsync(HidiOptions options, ILogger logg
765
772
// Write OpenAPI to Output folder
766
773
options . Output = new ( Path . Combine ( options . OutputFolder , "openapi.json" ) ) ;
767
774
options . TerseOutput = true ;
768
- await WriteOpenApiAsync ( options , OpenApiFormat . Json , OpenApiSpecVersion . OpenApi3_1 , document , logger , cancellationToken ) . ConfigureAwait ( false ) ;
769
-
770
- // Create OpenAIPluginManifest from ApiDependency and OpenAPI document
771
- var manifest = new OpenAIPluginManifest ( document . Info ? . Title ?? "Title" , document . Info ? . Title ?? "Title" , "https://go.microsoft.com/fwlink/?LinkID=288890" , document . Info ? . Contact ? . Email ?? "[email protected] " , document . Info ? . License ? . Url . ToString ( ) ?? "https://placeholderlicenseurl.com" )
772
- {
773
- DescriptionForHuman = document . Info ? . Description ?? "Description placeholder" ,
774
- Api = new ( "openapi" , "./openapi.json" ) ,
775
- Auth = new ManifestNoAuth ( ) ,
776
- } ;
777
- manifest . NameForModel = manifest . NameForHuman ;
778
- manifest . DescriptionForModel = manifest . DescriptionForHuman ;
779
-
780
- // Write OpenAIPluginManifest to Output folder
781
- var manifestFile = new FileInfo ( Path . Combine ( options . OutputFolder , "ai-plugin.json" ) ) ;
782
- using var file = new FileStream ( manifestFile . FullName , FileMode . Create ) ;
783
- using var jsonWriter = new Utf8JsonWriter ( file , new ( ) { Indented = true } ) ;
784
- manifest . Write ( jsonWriter ) ;
785
- await jsonWriter . FlushAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
775
+ if ( document is not null )
776
+ {
777
+ await WriteOpenApiAsync ( options , OpenApiFormat . Json , OpenApiSpecVersion . OpenApi3_1 , document , logger , cancellationToken ) . ConfigureAwait ( false ) ;
778
+
779
+ // Create OpenAIPluginManifest from ApiDependency and OpenAPI document
780
+ var manifest = new OpenAIPluginManifest ( document . Info . Title ?? "Title" ,
781
+ document . Info . Title ?? "Title" ,
782
+ "https://go.microsoft.com/fwlink/?LinkID=288890" ,
783
+ document . Info ? . Contact ? . Email ?? "[email protected] " ,
784
+ document . Info ? . License ? . Url ? . ToString ( ) ?? "https://placeholderlicenseurl.com" )
785
+ {
786
+ DescriptionForHuman = document . Info ? . Description ?? "Description placeholder" ,
787
+ Api = new ( "openapi" , "./openapi.json" ) ,
788
+ Auth = new ManifestNoAuth ( ) ,
789
+ } ;
790
+ manifest . NameForModel = manifest . NameForHuman ;
791
+ manifest . DescriptionForModel = manifest . DescriptionForHuman ;
792
+
793
+ // Write OpenAIPluginManifest to Output folder
794
+ var manifestFile = new FileInfo ( Path . Combine ( options . OutputFolder , "ai-plugin.json" ) ) ;
795
+ using var file = new FileStream ( manifestFile . FullName , FileMode . Create ) ;
796
+ using var jsonWriter = new Utf8JsonWriter ( file , new ( ) { Indented = true } ) ;
797
+ manifest . Write ( jsonWriter ) ;
798
+ await jsonWriter . FlushAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
799
+ }
786
800
}
787
801
}
788
802
}
0 commit comments