@@ -44,9 +44,9 @@ public class OpenApiGenerator(ILoggerFactory logFactory, BuildContext context, I
4444 private readonly IFileSystem _writeFileSystem = context . WriteFileSystem ;
4545 private readonly StaticFileContentHashProvider _contentHashProvider = new ( new EmbeddedOrPhysicalFileProvider ( context ) ) ;
4646
47- public LandingNavigationItem CreateNavigation ( OpenApiDocument openApiDocument )
47+ public LandingNavigationItem CreateNavigation ( string apiUrlSuffix , OpenApiDocument openApiDocument )
4848 {
49- var url = $ "{ context . UrlPathPrefix } /api" ;
49+ var url = $ "{ context . UrlPathPrefix } /api/" + apiUrlSuffix ;
5050 var rootNavigation = new LandingNavigationItem ( url ) ;
5151
5252 var ops = openApiDocument . Paths
@@ -62,15 +62,17 @@ public LandingNavigationItem CreateNavigation(OpenApiDocument openApiDocument)
6262 ? anyApi . Node . GetValue < string > ( )
6363 : null ;
6464 var tag = op . Value . Tags ? . FirstOrDefault ( ) ? . Reference . Id ;
65- var classification = openApiDocument . Info . Title == "Elasticsearch Request & Response Specification"
66- ? ClassifyElasticsearchTag ( tag ?? "unknown" )
67- : "unknown" ;
65+ var tagClassification = ( extensions ? . TryGetValue ( "x-tag-group" , out var g ) ?? false ) && g is OpenApiAny anyTagGroup
66+ ? anyTagGroup . Node . GetValue < string > ( )
67+ : openApiDocument . Info . Title == "Elasticsearch Request & Response Specification"
68+ ? ClassifyElasticsearchTag ( tag ?? "unknown" )
69+ : "unknown" ;
6870
6971 var apiString = ns is null
7072 ? api ?? op . Value . Summary ?? Guid . NewGuid ( ) . ToString ( "N" ) : $ "{ ns } .{ api } ";
7173 return new
7274 {
73- Classification = classification ,
75+ Classification = tagClassification ,
7476 Api = apiString ,
7577 Tag = tag ,
7678 pair . Path ,
@@ -158,25 +160,26 @@ group tagGroup by classificationGroup.Key
158160 var hasClassifications = classifications . Count > 1 ;
159161 foreach ( var classification in classifications )
160162 {
161- if ( hasClassifications )
163+ if ( hasClassifications && classification . Name != "common" )
162164 {
163165 var classificationNavigationItem = new ClassificationNavigationItem ( classification , rootNavigation , rootNavigation ) ;
164166 var tagNavigationItems = new List < IApiGroupingNavigationItem < IApiGroupingModel , INavigationItem > > ( ) ;
165167
166- CreateTagNavigationItems ( classification , classificationNavigationItem , classificationNavigationItem , tagNavigationItems ) ;
168+ CreateTagNavigationItems ( apiUrlSuffix , classification , classificationNavigationItem , classificationNavigationItem , tagNavigationItems ) ;
167169 topLevelNavigationItems . Add ( classificationNavigationItem ) ;
168170 // if there is only a single tag item will be added directly to the classificationNavigationItem, otherwise they will be added to the tagNavigationItems
169171 if ( classificationNavigationItem . NavigationItems . Count == 0 )
170172 classificationNavigationItem . NavigationItems = tagNavigationItems ;
171173 }
172174 else
173- CreateTagNavigationItems ( classification , rootNavigation , rootNavigation , topLevelNavigationItems ) ;
175+ CreateTagNavigationItems ( apiUrlSuffix , classification , rootNavigation , rootNavigation , topLevelNavigationItems ) ;
174176 }
175177 rootNavigation . NavigationItems = topLevelNavigationItems ;
176178 return rootNavigation ;
177179 }
178180
179181 private void CreateTagNavigationItems (
182+ string apiUrlSuffix ,
180183 ApiClassification classification ,
181184 IRootNavigationItem < IApiGroupingModel , INavigationItem > rootNavigation ,
182185 IApiGroupingNavigationItem < IApiGroupingModel , INavigationItem > parent ,
@@ -190,13 +193,13 @@ List<IApiGroupingNavigationItem<IApiGroupingModel, INavigationItem>> parentNavig
190193 if ( hasTags )
191194 {
192195 var tagNavigationItem = new TagNavigationItem ( tag , rootNavigation , parent ) ;
193- CreateEndpointNavigationItems ( rootNavigation , tag , tagNavigationItem , endpointNavigationItems ) ;
196+ CreateEndpointNavigationItems ( apiUrlSuffix , rootNavigation , tag , tagNavigationItem , endpointNavigationItems ) ;
194197 parentNavigationItems . Add ( tagNavigationItem ) ;
195198 tagNavigationItem . NavigationItems = endpointNavigationItems ;
196199 }
197200 else
198201 {
199- CreateEndpointNavigationItems ( rootNavigation , tag , parent , endpointNavigationItems ) ;
202+ CreateEndpointNavigationItems ( apiUrlSuffix , rootNavigation , tag , parent , endpointNavigationItems ) ;
200203 if ( parent is ClassificationNavigationItem classificationNavigationItem )
201204 classificationNavigationItem . NavigationItems = endpointNavigationItems ;
202205 else if ( parent is LandingNavigationItem landingNavigationItem )
@@ -206,6 +209,7 @@ List<IApiGroupingNavigationItem<IApiGroupingModel, INavigationItem>> parentNavig
206209 }
207210
208211 private void CreateEndpointNavigationItems (
212+ string apiUrlSuffix ,
209213 IRootNavigationItem < IApiGroupingModel , INavigationItem > rootNavigation ,
210214 ApiTag tag ,
211215 IApiGroupingNavigationItem < IApiGroupingModel , INavigationItem > parentNavigationItem ,
@@ -220,7 +224,7 @@ List<IEndpointOrOperationNavigationItem> endpointNavigationItems
220224 var operationNavigationItems = new List < OperationNavigationItem > ( ) ;
221225 foreach ( var operation in endpoint . Operations )
222226 {
223- var operationNavigationItem = new OperationNavigationItem ( context . UrlPathPrefix , operation , rootNavigation , endpointNavigationItem )
227+ var operationNavigationItem = new OperationNavigationItem ( context . UrlPathPrefix , apiUrlSuffix , operation , rootNavigation , endpointNavigationItem )
224228 {
225229 Hidden = true
226230 } ;
@@ -232,7 +236,7 @@ List<IEndpointOrOperationNavigationItem> endpointNavigationItems
232236 else
233237 {
234238 var operation = endpoint . Operations . First ( ) ;
235- var operationNavigationItem = new OperationNavigationItem ( context . UrlPathPrefix , operation , rootNavigation , parentNavigationItem ) ;
239+ var operationNavigationItem = new OperationNavigationItem ( context . UrlPathPrefix , apiUrlSuffix , operation , rootNavigation , parentNavigationItem ) ;
236240 endpointNavigationItems . Add ( operationNavigationItem ) ;
237241
238242 }
@@ -241,47 +245,53 @@ List<IEndpointOrOperationNavigationItem> endpointNavigationItems
241245
242246 public async Task Generate ( Cancel ctx = default )
243247 {
244- if ( context . Configuration . OpenApiSpecification is null )
248+ if ( context . Configuration . OpenApiSpecifications is null )
245249 return ;
246250
247- var openApiDocument = await OpenApiReader . Create ( context . Configuration . OpenApiSpecification ) ;
248- if ( openApiDocument is null )
249- return ;
251+ foreach ( var ( prefix , path ) in context . Configuration . OpenApiSpecifications )
252+ {
253+ var openApiDocument = await OpenApiReader . Create ( path ) ;
254+ if ( openApiDocument is null )
255+ return ;
250256
251- var navigation = CreateNavigation ( openApiDocument ) ;
252- _logger . LogInformation ( "Generating OpenApiDocument {Title}" , openApiDocument . Info . Title ) ;
257+ var navigation = CreateNavigation ( prefix , openApiDocument ) ;
258+ _logger . LogInformation ( "Generating OpenApiDocument {Title}" , openApiDocument . Info . Title ) ;
253259
254- var navigationRenderer = new IsolatedBuildNavigationHtmlWriter ( context , navigation ) ;
260+ var navigationRenderer = new IsolatedBuildNavigationHtmlWriter ( context , navigation ) ;
255261
262+ var renderContext = new ApiRenderContext ( context , openApiDocument , _contentHashProvider )
263+ {
264+ NavigationHtml = string . Empty ,
265+ CurrentNavigation = navigation ,
266+ MarkdownRenderer = markdownStringRenderer
267+ } ;
268+ _ = await Render ( prefix , navigation , navigation . Index , renderContext , navigationRenderer , ctx ) ;
269+ await RenderNavigationItems ( prefix , renderContext , navigationRenderer , navigation , ctx ) ;
256270
257- var renderContext = new ApiRenderContext ( context , openApiDocument , _contentHashProvider )
258- {
259- NavigationHtml = string . Empty ,
260- CurrentNavigation = navigation ,
261- MarkdownRenderer = markdownStringRenderer
262- } ;
263- _ = await Render ( navigation , navigation . Index , renderContext , navigationRenderer , ctx ) ;
264- await RenderNavigationItems ( navigation ) ;
271+ }
272+ }
265273
266- async Task RenderNavigationItems ( INavigationItem currentNavigation )
274+ private async Task RenderNavigationItems ( string prefix , ApiRenderContext renderContext , IsolatedBuildNavigationHtmlWriter navigationRenderer , INavigationItem currentNavigation , Cancel ctx )
275+ {
276+ if ( currentNavigation is INodeNavigationItem < IApiModel , INavigationItem > node )
267277 {
268- if ( currentNavigation is INodeNavigationItem < IApiModel , INavigationItem > node )
269- {
270- _ = await Render ( node , node . Index , renderContext , navigationRenderer , ctx ) ;
271- foreach ( var child in node . NavigationItems )
272- await RenderNavigationItems ( child ) ;
273- }
278+ _ = await Render ( prefix , node , node . Index , renderContext , navigationRenderer , ctx ) ;
279+ foreach ( var child in node . NavigationItems )
280+ await RenderNavigationItems ( prefix , renderContext , navigationRenderer , child , ctx ) ;
281+ }
274282
275- #pragma warning disable IDE0045
276- else if ( currentNavigation is ILeafNavigationItem < IApiModel > leaf )
277- #pragma warning restore IDE0045
278- _ = await Render ( leaf , leaf . Model , renderContext , navigationRenderer , ctx ) ;
279- else
280- throw new Exception ( $ "Unknown navigation item type { currentNavigation . GetType ( ) } ") ;
283+ else
284+ {
285+ _ = currentNavigation is ILeafNavigationItem < IApiModel > leaf
286+ ? await Render ( prefix , leaf , leaf . Model , renderContext , navigationRenderer , ctx )
287+ : throw new Exception ( $ "Unknown navigation item type { currentNavigation . GetType ( ) } ") ;
281288 }
282289 }
283290
284- private async Task < IFileInfo > Render < T > ( INavigationItem current , T page , ApiRenderContext renderContext , IsolatedBuildNavigationHtmlWriter navigationRenderer , Cancel ctx )
291+ #pragma warning disable IDE0060
292+ private async Task < IFileInfo > Render < T > ( string prefix , INavigationItem current , T page , ApiRenderContext renderContext ,
293+ #pragma warning restore IDE0060
294+ IsolatedBuildNavigationHtmlWriter navigationRenderer , Cancel ctx )
285295 where T : INavigationModel , IPageRenderer < ApiRenderContext >
286296 {
287297 var outputFile = OutputFile ( current ) ;
0 commit comments