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,43 @@ 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 }
52
+ if ( properties ) {
53
+ return (
54
+ < OpenAPIDisclosure context = { context } label = { getDisclosureLabel ( schema ) } >
55
+ < OpenAPISchemaProperties
56
+ properties = { properties }
59
57
circularRefs = { circularRefs }
60
58
context = { context }
61
59
/>
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
- ) ;
60
+ </ OpenAPIDisclosure >
61
+ ) ;
62
+ }
63
+
64
+ const ancestors = new Set ( circularRefs . keys ( ) ) ;
65
+ const alternatives = getSchemaAlternatives ( schema , ancestors ) ;
66
+
67
+ if ( alternatives ) {
68
+ return alternatives . map ( ( schema , index ) => (
69
+ < OpenAPISchemaAlternative
70
+ key = { index }
71
+ schema = { schema }
72
+ circularRefs = { circularRefs }
73
+ context = { context }
74
+ />
75
+ ) ) ;
76
+ }
77
+
78
+ return null ;
74
79
} ) ( ) }
75
80
</ div >
76
81
) ;
@@ -85,18 +90,25 @@ export function OpenAPISchemaProperties(props: {
85
90
circularRefs ?: CircularRefsIds ;
86
91
context : OpenAPIClientContext ;
87
92
} ) {
88
- const { id, properties, circularRefs, context } = props ;
93
+ const {
94
+ id,
95
+ properties,
96
+ circularRefs = new Map < OpenAPIV3 . SchemaObject , string > ( ) ,
97
+ context,
98
+ } = props ;
89
99
90
100
return (
91
101
< 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
- ) ) }
102
+ { properties . map ( ( property , index ) => {
103
+ return (
104
+ < OpenAPISchemaProperty
105
+ key = { index }
106
+ circularRefs = { circularRefs }
107
+ property = { property }
108
+ context = { context }
109
+ />
110
+ ) ;
111
+ } ) }
100
112
</ div >
101
113
) ;
102
114
}
@@ -107,20 +119,36 @@ export function OpenAPISchemaProperties(props: {
107
119
export function OpenAPIRootSchema ( props : {
108
120
schema : OpenAPIV3 . SchemaObject ;
109
121
context : OpenAPIClientContext ;
122
+ circularRefs ?: CircularRefsIds ;
110
123
} ) {
111
- const { schema, context } = props ;
124
+ const {
125
+ schema,
126
+ context,
127
+ circularRefs : parentCircularRefs = new Map < OpenAPIV3 . SchemaObject , string > ( ) ,
128
+ } = props ;
112
129
130
+ const id = useId ( ) ;
113
131
const properties = getSchemaProperties ( schema ) ;
114
132
115
133
if ( properties ?. length ) {
116
- return < OpenAPISchemaProperties properties = { properties } context = { context } /> ;
134
+ const circularRefs = new Map ( parentCircularRefs ) ;
135
+ circularRefs . set ( schema , id ) ;
136
+
137
+ return (
138
+ < OpenAPISchemaProperties
139
+ properties = { properties }
140
+ circularRefs = { circularRefs }
141
+ context = { context }
142
+ />
143
+ ) ;
117
144
}
118
145
119
146
return (
120
147
< OpenAPISchemaProperty
121
148
className = "openapi-schema-root"
122
149
property = { { schema } }
123
150
context = { context }
151
+ circularRefs = { parentCircularRefs }
124
152
/>
125
153
) ;
126
154
}
@@ -136,6 +164,7 @@ function OpenAPISchemaAlternative(props: {
136
164
context : OpenAPIClientContext ;
137
165
} ) {
138
166
const { schema, circularRefs, context } = props ;
167
+
139
168
const description = resolveDescription ( schema ) ;
140
169
const properties = getSchemaProperties ( schema ) ;
141
170
0 commit comments