1- import type { JSONDocument } from '@gitbook/api' ;
1+ import type { DocumentBlock , JSONDocument } from '@gitbook/api' ;
22import type { GitBookAnyContext } from '@v2/lib/context' ;
33
44import { getNodeText } from './document' ;
@@ -19,58 +19,102 @@ export interface DocumentSection {
1919export async function getDocumentSections (
2020 context : GitBookAnyContext ,
2121 document : JSONDocument
22+ ) : Promise < DocumentSection [ ] > {
23+ return getSectionsFromNodes ( document . nodes , context ) ;
24+ }
25+
26+ /**
27+ * Extract a list of sections from a list of nodes.
28+ */
29+ async function getSectionsFromNodes (
30+ nodes : DocumentBlock [ ] ,
31+ context : GitBookAnyContext
2232) : Promise < DocumentSection [ ] > {
2333 const sections : DocumentSection [ ] = [ ] ;
2434 let depth = 0 ;
2535
26- for ( const block of document . nodes ) {
27- if ( ( block . type === 'heading-1' || block . type === 'heading-2' ) && block . meta ?. id ) {
28- if ( block . type === 'heading-1' ) {
36+ for ( const block of nodes ) {
37+ switch ( block . type ) {
38+ case 'heading-1' : {
39+ const id = block . meta ?. id ;
40+ if ( ! id ) {
41+ continue ;
42+ }
2943 depth = 1 ;
30- }
31- const title = getNodeText ( block ) ;
32- const id = block . meta . id ;
33-
34- sections . push ( {
35- id,
36- title,
37- depth : block . type === 'heading-1' ? 1 : depth > 0 ? 2 : 1 ,
38- } ) ;
39- }
40-
41- if ( ( block . type === 'swagger' || block . type === 'openapi-operation' ) && block . meta ?. id ) {
42- const { data : operation } = await resolveOpenAPIOperationBlock ( {
43- block,
44- context,
45- } ) ;
46- if ( operation ) {
44+ const title = getNodeText ( block ) ;
4745 sections . push ( {
48- id : block . meta . id ,
49- tag : operation . method . toUpperCase ( ) ,
50- title : operation . operation . summary || operation . path ,
46+ id,
47+ title,
5148 depth : 1 ,
52- deprecated : operation . operation . deprecated ,
5349 } ) ;
50+ continue ;
5451 }
55- }
56-
57- if (
58- block . type === 'openapi-schemas' &&
59- ! block . data . grouped &&
60- block . meta ?. id &&
61- block . data . schemas . length === 1
62- ) {
63- const { data } = await resolveOpenAPISchemasBlock ( {
64- block,
65- context,
66- } ) ;
67- const schema = data ?. schemas [ 0 ] ;
68- if ( schema ) {
52+ case 'heading-2' : {
53+ const id = block . meta ?. id ;
54+ if ( ! id ) {
55+ continue ;
56+ }
57+ const title = getNodeText ( block ) ;
6958 sections . push ( {
70- id : block . meta . id ,
71- title : `The ${ schema . name } object` ,
72- depth : 1 ,
59+ id,
60+ title,
61+ depth : depth > 0 ? 2 : 1 ,
62+ } ) ;
63+ continue ;
64+ }
65+ case 'stepper' : {
66+ const stepNodes = await Promise . all (
67+ block . nodes . map ( async ( step ) => getSectionsFromNodes ( step . nodes , context ) )
68+ ) ;
69+ for ( const stepSections of stepNodes ) {
70+ sections . push ( ...stepSections ) ;
71+ }
72+ continue ;
73+ }
74+ case 'swagger' :
75+ case 'openapi-operation' : {
76+ const id = block . meta ?. id ;
77+ if ( ! id ) {
78+ continue ;
79+ }
80+ const { data : operation } = await resolveOpenAPIOperationBlock ( {
81+ block,
82+ context,
83+ } ) ;
84+ if ( operation ) {
85+ sections . push ( {
86+ id,
87+ tag : operation . method . toUpperCase ( ) ,
88+ title : operation . operation . summary || operation . path ,
89+ depth : 1 ,
90+ deprecated : operation . operation . deprecated ,
91+ } ) ;
92+ }
93+ continue ;
94+ }
95+ case 'openapi-schemas' : {
96+ const id = block . meta ?. id ;
97+ if ( ! id ) {
98+ continue ;
99+ }
100+ if ( block . data . grouped || block . data . schemas . length !== 1 ) {
101+ // Skip grouped schemas, they are not sections
102+ continue ;
103+ }
104+
105+ const { data } = await resolveOpenAPISchemasBlock ( {
106+ block,
107+ context,
73108 } ) ;
109+ const schema = data ?. schemas [ 0 ] ;
110+ if ( schema ) {
111+ sections . push ( {
112+ id,
113+ title : `The ${ schema . name } object` ,
114+ depth : 1 ,
115+ } ) ;
116+ }
117+ continue ;
74118 }
75119 }
76120 }
0 commit comments