1
+ 'use client' ;
2
+ // This component does not use any client feature but we don't want to
3
+ // render it server-side because it has recursion.
4
+
1
5
import type { OpenAPIV3 } from '@gitbook/openapi-parser' ;
2
6
import { useId } from 'react' ;
3
7
@@ -22,15 +26,10 @@ interface OpenAPISchemaPropertyEntry {
22
26
function OpenAPISchemaProperty ( props : {
23
27
property : OpenAPISchemaPropertyEntry ;
24
28
context : OpenAPIClientContext ;
25
- circularRefs ? : CircularRefsIds ;
29
+ circularRefs : CircularRefsIds ;
26
30
className ?: string ;
27
31
} ) {
28
- const {
29
- property,
30
- circularRefs : parentCircularRefs = new Map < OpenAPIV3 . SchemaObject , string > ( ) ,
31
- context,
32
- className,
33
- } = props ;
32
+ const { circularRefs : parentCircularRefs , context, className, property } = props ;
34
33
35
34
const { schema } = property ;
36
35
@@ -40,37 +39,41 @@ function OpenAPISchemaProperty(props: {
40
39
< div id = { id } className = { clsx ( 'openapi-schema' , className ) } >
41
40
< OpenAPISchemaPresentation property = { property } />
42
41
{ ( ( ) => {
43
- const parentCircularRef = parentCircularRefs . get ( schema ) ;
44
-
42
+ const circularRefId = parentCircularRefs . get ( schema ) ;
45
43
// Avoid recursing infinitely, and instead render a link to the parent schema
46
- if ( parentCircularRef ) {
47
- return < OpenAPISchemaCircularRef id = { parentCircularRef } schema = { schema } /> ;
44
+ if ( circularRefId ) {
45
+ return < OpenAPISchemaCircularRef id = { circularRefId } schema = { schema } /> ;
48
46
}
49
47
50
- const circularRefs = parentCircularRefs . set ( schema , id ) ;
48
+ const circularRefs = new Map ( parentCircularRefs ) ;
49
+ circularRefs . set ( schema , id ) ;
50
+
51
51
const properties = getSchemaProperties ( schema ) ;
52
- const alternatives = getSchemaAlternatives ( schema , new Set ( circularRefs . keys ( ) ) ) ;
53
- return (
54
- < >
55
- { alternatives ?. map ( ( schema , index ) => (
56
- < OpenAPISchemaAlternative
57
- key = { index }
58
- schema = { schema }
59
- circularRefs = { circularRefs }
60
- context = { context }
61
- />
62
- ) ) }
63
- { properties ?. length ? (
64
- < OpenAPIDisclosure context = { context } label = { getDisclosureLabel ( schema ) } >
65
- < OpenAPISchemaProperties
66
- properties = { properties }
67
- circularRefs = { circularRefs }
68
- context = { context }
69
- />
70
- </ OpenAPIDisclosure >
71
- ) : null }
72
- </ >
73
- ) ;
52
+ if ( properties ) {
53
+ return (
54
+ < OpenAPISchemaProperties
55
+ properties = { properties }
56
+ circularRefs = { circularRefs }
57
+ context = { context }
58
+ />
59
+ ) ;
60
+ }
61
+
62
+ const ancestors = new Set ( circularRefs . keys ( ) ) ;
63
+ const alternatives = getSchemaAlternatives ( schema , ancestors ) ;
64
+
65
+ if ( alternatives ) {
66
+ return alternatives . map ( ( schema , index ) => (
67
+ < OpenAPISchemaAlternative
68
+ key = { index }
69
+ schema = { schema }
70
+ circularRefs = { circularRefs }
71
+ context = { context }
72
+ />
73
+ ) ) ;
74
+ }
75
+
76
+ return null ;
74
77
} ) ( ) }
75
78
</ div >
76
79
) ;
@@ -85,18 +88,25 @@ export function OpenAPISchemaProperties(props: {
85
88
circularRefs ?: CircularRefsIds ;
86
89
context : OpenAPIClientContext ;
87
90
} ) {
88
- const { id, properties, circularRefs, context } = props ;
91
+ const {
92
+ id,
93
+ properties,
94
+ circularRefs = new Map < OpenAPIV3 . SchemaObject , string > ( ) ,
95
+ context,
96
+ } = props ;
89
97
90
98
return (
91
99
< div id = { id } className = "openapi-schema-properties" >
92
- { properties . map ( ( property , index ) => (
93
- < OpenAPISchemaProperty
94
- key = { index }
95
- circularRefs = { circularRefs }
96
- property = { property }
97
- context = { context }
98
- />
99
- ) ) }
100
+ { properties . map ( ( property , index ) => {
101
+ return (
102
+ < OpenAPISchemaProperty
103
+ key = { index }
104
+ circularRefs = { circularRefs }
105
+ property = { property }
106
+ context = { context }
107
+ />
108
+ ) ;
109
+ } ) }
100
110
</ div >
101
111
) ;
102
112
}
@@ -107,20 +117,36 @@ export function OpenAPISchemaProperties(props: {
107
117
export function OpenAPIRootSchema ( props : {
108
118
schema : OpenAPIV3 . SchemaObject ;
109
119
context : OpenAPIClientContext ;
120
+ circularRefs ?: CircularRefsIds ;
110
121
} ) {
111
- const { schema, context } = props ;
122
+ const {
123
+ schema,
124
+ context,
125
+ circularRefs : parentCircularRefs = new Map < OpenAPIV3 . SchemaObject , string > ( ) ,
126
+ } = props ;
112
127
128
+ const id = useId ( ) ;
113
129
const properties = getSchemaProperties ( schema ) ;
114
130
115
131
if ( properties ?. length ) {
116
- return < OpenAPISchemaProperties properties = { properties } context = { context } /> ;
132
+ const circularRefs = new Map ( parentCircularRefs ) ;
133
+ circularRefs . set ( schema , id ) ;
134
+
135
+ return (
136
+ < OpenAPISchemaProperties
137
+ properties = { properties }
138
+ circularRefs = { circularRefs }
139
+ context = { context }
140
+ />
141
+ ) ;
117
142
}
118
143
119
144
return (
120
145
< OpenAPISchemaProperty
121
146
className = "openapi-schema-root"
122
147
property = { { schema } }
123
148
context = { context }
149
+ circularRefs = { parentCircularRefs }
124
150
/>
125
151
) ;
126
152
}
@@ -136,6 +162,7 @@ function OpenAPISchemaAlternative(props: {
136
162
context : OpenAPIClientContext ;
137
163
} ) {
138
164
const { schema, circularRefs, context } = props ;
165
+
139
166
const description = resolveDescription ( schema ) ;
140
167
const properties = getSchemaProperties ( schema ) ;
141
168
0 commit comments