@gitbook/react-openapi 1.4.2 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/index.d.ts +663 -10
  3. package/dist/index.js +3873 -8
  4. package/package.json +11 -7
  5. package/dist/InteractiveSection.d.ts +0 -33
  6. package/dist/InteractiveSection.jsx +0 -61
  7. package/dist/Markdown.d.ts +0 -4
  8. package/dist/Markdown.jsx +0 -5
  9. package/dist/OpenAPICodeSample.d.ts +0 -19
  10. package/dist/OpenAPICodeSample.jsx +0 -230
  11. package/dist/OpenAPICodeSampleInteractive.d.ts +0 -14
  12. package/dist/OpenAPICodeSampleInteractive.jsx +0 -73
  13. package/dist/OpenAPICodeSampleSelector.d.ts +0 -14
  14. package/dist/OpenAPICodeSampleSelector.jsx +0 -44
  15. package/dist/OpenAPICopyButton.d.ts +0 -13
  16. package/dist/OpenAPICopyButton.jsx +0 -35
  17. package/dist/OpenAPIDisclosure.d.ts +0 -11
  18. package/dist/OpenAPIDisclosure.jsx +0 -30
  19. package/dist/OpenAPIDisclosureGroup.d.ts +0 -23
  20. package/dist/OpenAPIDisclosureGroup.jsx +0 -83
  21. package/dist/OpenAPIExample.d.ts +0 -16
  22. package/dist/OpenAPIExample.jsx +0 -36
  23. package/dist/OpenAPIMediaType.d.ts +0 -21
  24. package/dist/OpenAPIMediaType.jsx +0 -61
  25. package/dist/OpenAPIOperation.d.ts +0 -10
  26. package/dist/OpenAPIOperation.jsx +0 -25
  27. package/dist/OpenAPIOperationContext.d.ts +0 -16
  28. package/dist/OpenAPIOperationContext.jsx +0 -26
  29. package/dist/OpenAPIOperationDescription.d.ts +0 -9
  30. package/dist/OpenAPIOperationDescription.jsx +0 -22
  31. package/dist/OpenAPIOperationStability.d.ts +0 -9
  32. package/dist/OpenAPIOperationStability.jsx +0 -27
  33. package/dist/OpenAPIPath.d.ts +0 -18
  34. package/dist/OpenAPIPath.jsx +0 -55
  35. package/dist/OpenAPIPrefillContextProvider.d.ts +0 -22
  36. package/dist/OpenAPIPrefillContextProvider.jsx +0 -19
  37. package/dist/OpenAPIRequestBody.d.ts +0 -11
  38. package/dist/OpenAPIRequestBody.jsx +0 -28
  39. package/dist/OpenAPIRequestBodyHeaderType.d.ts +0 -8
  40. package/dist/OpenAPIRequestBodyHeaderType.jsx +0 -25
  41. package/dist/OpenAPIResponse.d.ts +0 -10
  42. package/dist/OpenAPIResponse.jsx +0 -57
  43. package/dist/OpenAPIResponseExample.d.ts +0 -9
  44. package/dist/OpenAPIResponseExample.jsx +0 -105
  45. package/dist/OpenAPIResponseExampleContent.d.ts +0 -22
  46. package/dist/OpenAPIResponseExampleContent.jsx +0 -60
  47. package/dist/OpenAPIResponses.d.ts +0 -9
  48. package/dist/OpenAPIResponses.jsx +0 -77
  49. package/dist/OpenAPISchema.d.ts +0 -27
  50. package/dist/OpenAPISchema.jsx +0 -400
  51. package/dist/OpenAPISchemaName.d.ts +0 -16
  52. package/dist/OpenAPISchemaName.jsx +0 -43
  53. package/dist/OpenAPISchemaServer.d.ts +0 -12
  54. package/dist/OpenAPISchemaServer.jsx +0 -8
  55. package/dist/OpenAPISecurities.d.ts +0 -9
  56. package/dist/OpenAPISecurities.jsx +0 -114
  57. package/dist/OpenAPISelect.d.ts +0 -22
  58. package/dist/OpenAPISelect.jsx +0 -44
  59. package/dist/OpenAPISpec.d.ts +0 -6
  60. package/dist/OpenAPISpec.jsx +0 -80
  61. package/dist/OpenAPITabs.d.ts +0 -26
  62. package/dist/OpenAPITabs.jsx +0 -109
  63. package/dist/OpenAPIWebhook.d.ts +0 -10
  64. package/dist/OpenAPIWebhook.jsx +0 -23
  65. package/dist/OpenAPIWebhookExample.d.ts +0 -6
  66. package/dist/OpenAPIWebhookExample.jsx +0 -41
  67. package/dist/ScalarApiButton.d.ts +0 -14
  68. package/dist/ScalarApiButton.jsx +0 -81
  69. package/dist/StaticSection.d.ts +0 -13
  70. package/dist/StaticSection.jsx +0 -32
  71. package/dist/code-samples.d.ts +0 -17
  72. package/dist/code-samples.js +0 -427
  73. package/dist/common/OpenAPIColumnSpec.d.ts +0 -6
  74. package/dist/common/OpenAPIColumnSpec.jsx +0 -20
  75. package/dist/common/OpenAPIOperationDescription.d.ts +0 -6
  76. package/dist/common/OpenAPIOperationDescription.jsx +0 -19
  77. package/dist/common/OpenAPIStability.d.ts +0 -4
  78. package/dist/common/OpenAPIStability.jsx +0 -15
  79. package/dist/common/OpenAPISummary.d.ts +0 -6
  80. package/dist/common/OpenAPISummary.jsx +0 -30
  81. package/dist/contentTypeChecks.d.ts +0 -10
  82. package/dist/contentTypeChecks.js +0 -30
  83. package/dist/context.d.ts +0 -75
  84. package/dist/context.js +0 -43
  85. package/dist/decycle.d.ts +0 -2
  86. package/dist/decycle.js +0 -70
  87. package/dist/dereference.d.ts +0 -5
  88. package/dist/dereference.js +0 -68
  89. package/dist/generateSchemaExample.d.ts +0 -45
  90. package/dist/generateSchemaExample.js +0 -342
  91. package/dist/getDisclosureLabel.d.ts +0 -7
  92. package/dist/getDisclosureLabel.js +0 -18
  93. package/dist/getOrCreateStoreByKey.d.ts +0 -10
  94. package/dist/getOrCreateStoreByKey.js +0 -19
  95. package/dist/json2xml.d.ts +0 -4
  96. package/dist/json2xml.js +0 -7
  97. package/dist/resolveOpenAPIOperation.d.ts +0 -11
  98. package/dist/resolveOpenAPIOperation.js +0 -173
  99. package/dist/resolveOpenAPIWebhook.d.ts +0 -11
  100. package/dist/resolveOpenAPIWebhook.js +0 -127
  101. package/dist/schemas/OpenAPISchemaItem.d.ts +0 -7
  102. package/dist/schemas/OpenAPISchemaItem.jsx +0 -16
  103. package/dist/schemas/OpenAPISchemas.d.ts +0 -14
  104. package/dist/schemas/OpenAPISchemas.jsx +0 -59
  105. package/dist/schemas/index.d.ts +0 -2
  106. package/dist/schemas/index.js +0 -2
  107. package/dist/schemas/resolveOpenAPISchemas.d.ts +0 -10
  108. package/dist/schemas/resolveOpenAPISchemas.js +0 -61
  109. package/dist/stringifyOpenAPI.d.ts +0 -4
  110. package/dist/stringifyOpenAPI.js +0 -15
  111. package/dist/translate.d.ts +0 -10
  112. package/dist/translate.jsx +0 -75
  113. package/dist/translations/de.d.ts +0 -43
  114. package/dist/translations/de.js +0 -43
  115. package/dist/translations/en.d.ts +0 -43
  116. package/dist/translations/en.js +0 -43
  117. package/dist/translations/es.d.ts +0 -43
  118. package/dist/translations/es.js +0 -43
  119. package/dist/translations/fr.d.ts +0 -43
  120. package/dist/translations/fr.js +0 -43
  121. package/dist/translations/index.d.ts +0 -395
  122. package/dist/translations/index.js +0 -27
  123. package/dist/translations/ja.d.ts +0 -43
  124. package/dist/translations/ja.js +0 -43
  125. package/dist/translations/nl.d.ts +0 -43
  126. package/dist/translations/nl.js +0 -43
  127. package/dist/translations/no.d.ts +0 -43
  128. package/dist/translations/no.js +0 -43
  129. package/dist/translations/pt-br.d.ts +0 -43
  130. package/dist/translations/pt-br.js +0 -43
  131. package/dist/translations/types.d.ts +0 -5
  132. package/dist/translations/types.js +0 -1
  133. package/dist/translations/zh.d.ts +0 -43
  134. package/dist/translations/zh.js +0 -43
  135. package/dist/tsconfig.build.tsbuildinfo +0 -1
  136. package/dist/types.d.ts +0 -31
  137. package/dist/types.js +0 -1
  138. package/dist/util/example.d.ts +0 -35
  139. package/dist/util/example.jsx +0 -103
  140. package/dist/util/server.d.ts +0 -9
  141. package/dist/util/server.js +0 -44
  142. package/dist/util/tryit-prefill.d.ts +0 -20
  143. package/dist/util/tryit-prefill.js +0 -129
  144. package/dist/utils.d.ts +0 -50
  145. package/dist/utils.js +0 -224
  146. package/src/InteractiveSection.tsx +0 -147
  147. package/src/Markdown.tsx +0 -12
  148. package/src/OpenAPICodeSample.tsx +0 -330
  149. package/src/OpenAPICodeSampleInteractive.tsx +0 -136
  150. package/src/OpenAPICodeSampleSelector.tsx +0 -94
  151. package/src/OpenAPICopyButton.tsx +0 -72
  152. package/src/OpenAPIDisclosure.tsx +0 -46
  153. package/src/OpenAPIDisclosureGroup.tsx +0 -158
  154. package/src/OpenAPIExample.tsx +0 -55
  155. package/src/OpenAPIMediaType.tsx +0 -139
  156. package/src/OpenAPIOperation.tsx +0 -35
  157. package/src/OpenAPIOperationContext.tsx +0 -45
  158. package/src/OpenAPIOperationDescription.tsx +0 -34
  159. package/src/OpenAPIOperationStability.tsx +0 -39
  160. package/src/OpenAPIPath.tsx +0 -90
  161. package/src/OpenAPIPrefillContextProvider.tsx +0 -40
  162. package/src/OpenAPIRequestBody.tsx +0 -54
  163. package/src/OpenAPIRequestBodyHeaderType.tsx +0 -36
  164. package/src/OpenAPIResponse.tsx +0 -82
  165. package/src/OpenAPIResponseExample.tsx +0 -151
  166. package/src/OpenAPIResponseExampleContent.tsx +0 -125
  167. package/src/OpenAPIResponses.tsx +0 -125
  168. package/src/OpenAPISchema.test.ts +0 -172
  169. package/src/OpenAPISchema.tsx +0 -654
  170. package/src/OpenAPISchemaName.tsx +0 -80
  171. package/src/OpenAPISchemaServer.tsx +0 -34
  172. package/src/OpenAPISecurities.tsx +0 -231
  173. package/src/OpenAPISelect.tsx +0 -96
  174. package/src/OpenAPISpec.tsx +0 -138
  175. package/src/OpenAPITabs.tsx +0 -147
  176. package/src/OpenAPIWebhook.tsx +0 -33
  177. package/src/OpenAPIWebhookExample.tsx +0 -60
  178. package/src/ScalarApiButton.tsx +0 -132
  179. package/src/StaticSection.tsx +0 -91
  180. package/src/__snapshots__/json2xml.test.ts.snap +0 -18
  181. package/src/code-samples.test.ts +0 -714
  182. package/src/code-samples.ts +0 -448
  183. package/src/common/OpenAPIColumnSpec.tsx +0 -31
  184. package/src/common/OpenAPIOperationDescription.tsx +0 -31
  185. package/src/common/OpenAPIStability.tsx +0 -23
  186. package/src/common/OpenAPISummary.tsx +0 -45
  187. package/src/contentTypeChecks.ts +0 -39
  188. package/src/context.ts +0 -99
  189. package/src/decycle.ts +0 -68
  190. package/src/dereference.ts +0 -29
  191. package/src/generateSchemaExample.test.ts +0 -1040
  192. package/src/generateSchemaExample.ts +0 -530
  193. package/src/getDisclosureLabel.ts +0 -25
  194. package/src/getOrCreateStoreByKey.ts +0 -33
  195. package/src/index.ts +0 -10
  196. package/src/json2xml.test.ts +0 -46
  197. package/src/json2xml.ts +0 -8
  198. package/src/resolveOpenAPIOperation.test.ts +0 -177
  199. package/src/resolveOpenAPIOperation.ts +0 -151
  200. package/src/resolveOpenAPIWebhook.ts +0 -99
  201. package/src/schemas/OpenAPISchemaItem.tsx +0 -34
  202. package/src/schemas/OpenAPISchemas.tsx +0 -98
  203. package/src/schemas/index.ts +0 -2
  204. package/src/schemas/resolveOpenAPISchemas.test.ts +0 -174
  205. package/src/schemas/resolveOpenAPISchemas.ts +0 -28
  206. package/src/stringifyOpenAPI.ts +0 -25
  207. package/src/translate.tsx +0 -80
  208. package/src/translations/de.ts +0 -43
  209. package/src/translations/en.ts +0 -43
  210. package/src/translations/es.ts +0 -43
  211. package/src/translations/fr.ts +0 -43
  212. package/src/translations/index.ts +0 -33
  213. package/src/translations/ja.ts +0 -43
  214. package/src/translations/nl.ts +0 -43
  215. package/src/translations/no.ts +0 -43
  216. package/src/translations/pt-br.ts +0 -43
  217. package/src/translations/types.ts +0 -7
  218. package/src/translations/zh.ts +0 -43
  219. package/src/types.ts +0 -46
  220. package/src/util/example.tsx +0 -129
  221. package/src/util/server.test.ts +0 -58
  222. package/src/util/server.ts +0 -47
  223. package/src/util/tryit-prefill.test.ts +0 -311
  224. package/src/util/tryit-prefill.ts +0 -160
  225. package/src/utils.ts +0 -255
@@ -1,36 +0,0 @@
1
- 'use client';
2
-
3
- import type { OpenAPIV3 } from '@gitbook/openapi-parser';
4
- import { useSelectState } from './OpenAPISelect';
5
- import { getSchemaTitle } from './utils';
6
-
7
- /**
8
- * Display the type of a request body. It only displays the type if the selected content is an array.
9
- */
10
- export function OpenAPIRequestBodyHeaderType(props: {
11
- requestBody: OpenAPIV3.RequestBodyObject;
12
- stateKey: string;
13
- }) {
14
- const { requestBody, stateKey } = props;
15
- const content = requestBody.content ?? {};
16
- const state = useSelectState(stateKey, Object.keys(content)[0]);
17
-
18
- const selectedContentMediaType = Object.entries(content).find(
19
- ([contentType]) => contentType === state.key
20
- )?.[1];
21
-
22
- // If the selected content is not an array, we don't display the type
23
- if (
24
- !selectedContentMediaType ||
25
- !selectedContentMediaType.schema?.type ||
26
- selectedContentMediaType.schema.type !== 'array'
27
- ) {
28
- return null;
29
- }
30
-
31
- return (
32
- <span className="openapi-requestbody-header-type">
33
- {`${getSchemaTitle(selectedContentMediaType.schema)}`}
34
- </span>
35
- );
36
- }
@@ -1,82 +0,0 @@
1
- import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
- import { OpenAPIDisclosure } from './OpenAPIDisclosure';
3
- import { OpenAPISchemaPresentation } from './OpenAPISchema';
4
- import { OpenAPISchemaProperties } from './OpenAPISchemaServer';
5
- import type { OpenAPIClientContext } from './context';
6
- import { tString } from './translate';
7
- import { parameterToProperty, resolveDescription } from './utils';
8
-
9
- /**
10
- * Display an interactive response body.
11
- */
12
- export function OpenAPIResponse(props: {
13
- response: OpenAPIV3.ResponseObject;
14
- mediaType: OpenAPIV3.MediaTypeObject | null;
15
- context: OpenAPIClientContext;
16
- }) {
17
- const { response, context, mediaType } = props;
18
- const headers = Object.entries(response.headers ?? {}).map(
19
- ([name, header]) => [name, header ?? {}] as const
20
- );
21
- const content = Object.entries(mediaType?.schema ?? {});
22
-
23
- const description = resolveDescription(response);
24
-
25
- if (content.length === 0 && !description && headers.length === 0) {
26
- return null;
27
- }
28
-
29
- return (
30
- <div className="openapi-response-body">
31
- {headers.length > 0 ? (
32
- <OpenAPIDisclosure
33
- header={
34
- <OpenAPISchemaPresentation
35
- context={context}
36
- property={{
37
- propertyName: tString(context.translation, 'headers'),
38
- schema: {
39
- type: 'object',
40
- },
41
- required: null,
42
- }}
43
- />
44
- }
45
- icon={context.icons.plus}
46
- label={(isExpanded) =>
47
- tString(
48
- context.translation,
49
- isExpanded ? 'hide' : 'show',
50
- tString(
51
- context.translation,
52
- headers.length === 1 ? 'header' : 'headers'
53
- )
54
- )
55
- }
56
- >
57
- <OpenAPISchemaProperties
58
- properties={headers.map(([name, header]) =>
59
- parameterToProperty({ name, ...header })
60
- )}
61
- context={context}
62
- />
63
- </OpenAPIDisclosure>
64
- ) : null}
65
- {mediaType?.schema && (
66
- <div className="openapi-responsebody">
67
- <OpenAPISchemaProperties
68
- id={`response-${context.blockKey}`}
69
- properties={[
70
- {
71
- schema: mediaType.schema,
72
- propertyName: tString(context.translation, 'response'),
73
- required: null,
74
- },
75
- ]}
76
- context={context}
77
- />
78
- </div>
79
- )}
80
- </div>
81
- );
82
- }
@@ -1,151 +0,0 @@
1
- import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
- import { Markdown } from './Markdown';
3
- import { OpenAPIEmptyExample, OpenAPIExample } from './OpenAPIExample';
4
- import { OpenAPIMediaTypeContent } from './OpenAPIMediaType';
5
- import { OpenAPIResponseExampleContent } from './OpenAPIResponseExampleContent';
6
- import { type OpenAPIContext, getOpenAPIClientContext } from './context';
7
- import type { OpenAPIOperationData, OpenAPIWebhookData } from './types';
8
- import { getExampleFromReference, getExamples } from './util/example';
9
- import { createStateKey, getStatusCodeDefaultLabel, resolveDescription } from './utils';
10
- import { checkIsReference } from './utils';
11
-
12
- /**
13
- * Display an example of the response content.
14
- */
15
- export function OpenAPIResponseExample(props: {
16
- data: OpenAPIOperationData | OpenAPIWebhookData;
17
- context: OpenAPIContext;
18
- }) {
19
- const { data, context } = props;
20
-
21
- // if there are no responses defined for the operation
22
- if (!data.operation.responses) {
23
- return null;
24
- }
25
-
26
- const responses = Object.entries(data.operation.responses);
27
- // Sort response to get 200, and 2xx first
28
- responses.sort(([a], [b]) => {
29
- if (a === 'default') {
30
- return 1;
31
- }
32
- if (b === 'default') {
33
- return -1;
34
- }
35
- if (a === '200') {
36
- return -1;
37
- }
38
- if (b === '200') {
39
- return 1;
40
- }
41
- return Number(a) - Number(b);
42
- });
43
-
44
- const tabs = responses
45
- .filter(
46
- ([_, responseObject]) =>
47
- responseObject &&
48
- typeof responseObject === 'object' &&
49
- // Make sure the response is not hidden
50
- !responseObject['x-hideSample']
51
- )
52
- .map(([key, responseObject]) => {
53
- const description = resolveDescription(responseObject);
54
- const label = description ? (
55
- <Markdown key={`response-description-${key}`} source={description} />
56
- ) : (
57
- getStatusCodeDefaultLabel(key, context)
58
- );
59
-
60
- if (checkIsReference(responseObject)) {
61
- return {
62
- key: key,
63
- label,
64
- statusCode: key,
65
- body: (
66
- <OpenAPIExample
67
- example={getExampleFromReference(responseObject, context)}
68
- context={context}
69
- syntax="json"
70
- />
71
- ),
72
- };
73
- }
74
-
75
- if (!responseObject.content || Object.keys(responseObject.content).length === 0) {
76
- return {
77
- key: key,
78
- label,
79
- statusCode: key,
80
- body: <OpenAPIEmptyExample context={context} />,
81
- };
82
- }
83
-
84
- return {
85
- key: key,
86
- label,
87
- statusCode: key,
88
- body: <OpenAPIResponse context={context} content={responseObject.content} />,
89
- };
90
- });
91
-
92
- if (tabs.length === 0) {
93
- return null;
94
- }
95
-
96
- return (
97
- <OpenAPIResponseExampleContent
98
- selectIcon={context.icons.chevronDown}
99
- blockKey={context.blockKey}
100
- items={tabs}
101
- />
102
- );
103
- }
104
-
105
- function OpenAPIResponse(props: {
106
- context: OpenAPIContext;
107
- content: {
108
- [media: string]: OpenAPIV3.MediaTypeObject | null;
109
- };
110
- }) {
111
- const { context, content } = props;
112
-
113
- const entries = Object.entries(content);
114
- const firstEntry = entries[0];
115
-
116
- if (!firstEntry) {
117
- throw new Error('One media type is required');
118
- }
119
-
120
- const tabs = entries.map((entry) => {
121
- const [mediaType, mediaTypeObject] = entry;
122
-
123
- if (!mediaTypeObject) {
124
- return {
125
- key: mediaType,
126
- label: mediaType,
127
- body: <OpenAPIEmptyExample context={context} />,
128
- };
129
- }
130
-
131
- return {
132
- key: mediaType,
133
- label: mediaType,
134
- body: <></>,
135
- examples: getExamples({
136
- mediaTypeObject,
137
- mediaType,
138
- context,
139
- }),
140
- };
141
- });
142
-
143
- return (
144
- <OpenAPIMediaTypeContent
145
- selectIcon={context.icons.chevronDown}
146
- stateKey={createStateKey('response-media-types', context.blockKey)}
147
- items={tabs}
148
- context={getOpenAPIClientContext(context)}
149
- />
150
- );
151
- }
@@ -1,125 +0,0 @@
1
- 'use client';
2
-
3
- import clsx from 'clsx';
4
- import type { Key } from 'react-aria';
5
- import { OpenAPISelect, OpenAPISelectItem, useSelectState } from './OpenAPISelect';
6
- import { StaticSection } from './StaticSection';
7
- import { createStateKey, getStatusCodeClassName } from './utils';
8
-
9
- type OpenAPIResponseExampleItem = OpenAPISelectItem & {
10
- statusCode: string;
11
- body: React.ReactNode;
12
- };
13
-
14
- /**
15
- * Get the state of the response examples select.
16
- */
17
- export function useResponseExamplesState(
18
- blockKey: string | undefined,
19
- initialKey: Key = 'default'
20
- ) {
21
- return useSelectState(getResponseExampleStateKey(blockKey), initialKey);
22
- }
23
-
24
- export function OpenAPIResponseExampleContent(props: {
25
- items: OpenAPIResponseExampleItem[];
26
- blockKey?: string;
27
- selectIcon?: React.ReactNode;
28
- }) {
29
- const { blockKey, items, selectIcon } = props;
30
-
31
- return (
32
- <StaticSection
33
- header={
34
- <OpenAPIResponseExampleHeader
35
- selectIcon={selectIcon}
36
- blockKey={blockKey}
37
- items={items}
38
- />
39
- }
40
- className="openapi-response-examples"
41
- >
42
- <OpenAPIResponseExampleBody blockKey={blockKey} items={items} />
43
- </StaticSection>
44
- );
45
- }
46
-
47
- function OpenAPIResponseExampleHeader(props: {
48
- items: OpenAPIResponseExampleItem[];
49
- blockKey?: string;
50
- selectIcon?: React.ReactNode;
51
- }) {
52
- const { items, blockKey, selectIcon } = props;
53
-
54
- if (items.length === 1) {
55
- const item = items[0];
56
-
57
- if (!item) {
58
- return null;
59
- }
60
-
61
- return (
62
- <span className="openapi-response-examples-statuscode-title">
63
- <OpenAPIResponseExampleItem item={item} />
64
- </span>
65
- );
66
- }
67
-
68
- return (
69
- <OpenAPISelect
70
- items={items}
71
- icon={selectIcon}
72
- stateKey={getResponseExampleStateKey(blockKey)}
73
- placement="bottom start"
74
- >
75
- {items.map((item) => (
76
- <OpenAPISelectItem key={item.key} id={item.key} value={item}>
77
- <OpenAPIResponseExampleItem item={item} />
78
- </OpenAPISelectItem>
79
- ))}
80
- </OpenAPISelect>
81
- );
82
- }
83
-
84
- function OpenAPIResponseExampleItem(props: {
85
- item: OpenAPIResponseExampleItem;
86
- }) {
87
- const { item } = props;
88
- return (
89
- <>
90
- <span
91
- className={clsx(
92
- 'openapi-statuscode',
93
- `openapi-statuscode-${getStatusCodeClassName(item.statusCode)}`,
94
- 'openapi-response-examples-statuscode'
95
- )}
96
- >
97
- {item.statusCode}
98
- </span>
99
- <span className="openapi-response-examples-statuscode-label">{item.label}</span>
100
- </>
101
- );
102
- }
103
-
104
- function OpenAPIResponseExampleBody(props: {
105
- items: OpenAPIResponseExampleItem[];
106
- blockKey?: string;
107
- }) {
108
- const { blockKey, items } = props;
109
- const state = useResponseExamplesState(blockKey, items[0]?.key);
110
-
111
- const selectedItem = items.find((item) => item.key === state.key) ?? items[0];
112
-
113
- if (!selectedItem) {
114
- return null;
115
- }
116
-
117
- return <div className="openapi-response-examples-panel">{selectedItem.body}</div>;
118
- }
119
-
120
- /**
121
- * Return the state key for the response examples.
122
- */
123
- function getResponseExampleStateKey(blockKey: string | undefined) {
124
- return createStateKey('openapi-responses', blockKey);
125
- }
@@ -1,125 +0,0 @@
1
- 'use client';
2
-
3
- import type { OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
4
- import clsx from 'clsx';
5
- import { Markdown } from './Markdown';
6
- import { OpenAPIDisclosureGroup } from './OpenAPIDisclosureGroup';
7
- import { OpenAPIResponse } from './OpenAPIResponse';
8
- import { useResponseExamplesState } from './OpenAPIResponseExampleContent';
9
- import { StaticSection } from './StaticSection';
10
- import type { OpenAPIClientContext } from './context';
11
- import { t } from './translate';
12
- import {
13
- createStateKey,
14
- getStatusCodeClassName,
15
- getStatusCodeDefaultLabel,
16
- resolveDescription,
17
- } from './utils';
18
-
19
- /**
20
- * Display an interactive response body.
21
- */
22
- export function OpenAPIResponses(props: {
23
- responses: OpenAPIV3.ResponsesObject | OpenAPIV3_1.ResponsesObject;
24
- context: OpenAPIClientContext;
25
- }) {
26
- const { responses, context } = props;
27
-
28
- const groups = Object.entries(responses)
29
- .filter(([_, response]) => response && typeof response === 'object')
30
- .map(([statusCode, response]: [string, OpenAPIV3.ResponseObject]) => {
31
- const tabs = (() => {
32
- // If there is no content, but there are headers, we need to show the headers
33
- if (
34
- (!response.content || !Object.keys(response.content).length) &&
35
- response.headers &&
36
- Object.keys(response.headers).length
37
- ) {
38
- return [
39
- {
40
- key: 'default',
41
- label: '',
42
- body: (
43
- <OpenAPIResponse
44
- response={response}
45
- mediaType={{}}
46
- context={context}
47
- />
48
- ),
49
- },
50
- ];
51
- }
52
-
53
- if (!response.content) {
54
- return [
55
- {
56
- key: 'default',
57
- label: '',
58
- body: (
59
- <pre className="openapi-example-empty">
60
- <p>{t(context.translation, 'no_content')}</p>
61
- </pre>
62
- ),
63
- },
64
- ];
65
- }
66
-
67
- return Object.entries(response.content ?? {}).map(([contentType, mediaType]) => ({
68
- key: contentType,
69
- label: contentType,
70
- body: (
71
- <OpenAPIResponse
72
- response={response}
73
- mediaType={mediaType}
74
- context={context}
75
- />
76
- ),
77
- }));
78
- })();
79
-
80
- const description = resolveDescription(response);
81
-
82
- return {
83
- key: statusCode,
84
- label: (
85
- <div className="openapi-response-tab-content">
86
- <span
87
- className={clsx(
88
- 'openapi-statuscode',
89
- `openapi-statuscode-${getStatusCodeClassName(statusCode)}`
90
- )}
91
- >
92
- {statusCode}
93
- </span>
94
- {description ? (
95
- <Markdown
96
- source={description}
97
- className="openapi-response-description"
98
- />
99
- ) : (
100
- getStatusCodeDefaultLabel(statusCode, context)
101
- )}
102
- </div>
103
- ),
104
- tabs,
105
- };
106
- });
107
-
108
- const state = useResponseExamplesState(context.blockKey, groups[0]?.key);
109
-
110
- return (
111
- <StaticSection header={t(context.translation, 'responses')} className="openapi-responses">
112
- <OpenAPIDisclosureGroup
113
- icon={context.icons.chevronRight}
114
- expandedKeys={state.key ? new Set([state.key]) : new Set()}
115
- onExpandedChange={(keys) => {
116
- const key = keys.values().next().value ?? null;
117
- state.setKey(key);
118
- }}
119
- groups={groups}
120
- selectIcon={context.icons.chevronDown}
121
- selectStateKey={createStateKey('response-media-types', context.blockKey)}
122
- />
123
- </StaticSection>
124
- );
125
- }
@@ -1,172 +0,0 @@
1
- import { describe, expect, it } from 'bun:test';
2
- import type { OpenAPIV3 } from '@gitbook/openapi-parser';
3
- import { getSchemaAlternatives } from './OpenAPISchema';
4
-
5
- describe('getSchemaAlternatives', () => {
6
- it('should flatten oneOf', () => {
7
- expect(
8
- getSchemaAlternatives({
9
- oneOf: [
10
- {
11
- oneOf: [
12
- {
13
- type: 'number',
14
- },
15
- {
16
- type: 'boolean',
17
- },
18
- ],
19
- },
20
- {
21
- type: 'string',
22
- },
23
- ],
24
- })
25
- ).toEqual([
26
- {
27
- type: 'number',
28
- },
29
- {
30
- type: 'boolean',
31
- },
32
- {
33
- type: 'string',
34
- },
35
- ]);
36
- });
37
-
38
- it('merges string enum', () => {
39
- expect(
40
- getSchemaAlternatives({
41
- oneOf: [
42
- {
43
- oneOf: [
44
- {
45
- type: 'string',
46
- enum: ['a', 'b'],
47
- },
48
- {
49
- type: 'string',
50
- enum: ['c', 'd'],
51
- nullable: true,
52
- },
53
- ],
54
- },
55
- ],
56
- })
57
- ).toEqual([
58
- {
59
- type: 'string',
60
- enum: ['a', 'b', 'c', 'd'],
61
- nullable: true,
62
- },
63
- ]);
64
- });
65
-
66
- it('merges objects with allOf', () => {
67
- expect(
68
- getSchemaAlternatives({
69
- allOf: [
70
- {
71
- type: 'object',
72
- properties: {
73
- name: {
74
- type: 'string',
75
- },
76
- map: {
77
- type: 'string',
78
- },
79
- description: {
80
- type: 'string',
81
- },
82
- },
83
- required: ['name'],
84
- },
85
- {
86
- type: 'object',
87
- properties: {
88
- externalId: {
89
- type: 'string',
90
- },
91
- },
92
- required: ['map', 'externalId'],
93
- },
94
- ],
95
- })
96
- ).toEqual([
97
- {
98
- type: 'object',
99
- properties: {
100
- name: {
101
- type: 'string',
102
- },
103
- map: {
104
- type: 'string',
105
- },
106
- description: {
107
- type: 'string',
108
- },
109
- externalId: {
110
- type: 'string',
111
- },
112
- },
113
- required: ['name', 'map', 'externalId'],
114
- },
115
- ]);
116
- });
117
-
118
- it('should not flatten oneOf and allOf', () => {
119
- expect(
120
- getSchemaAlternatives({
121
- oneOf: [
122
- {
123
- allOf: [
124
- {
125
- type: 'number',
126
- },
127
- {
128
- type: 'boolean',
129
- },
130
- ],
131
- },
132
- {
133
- type: 'string',
134
- },
135
- ],
136
- })
137
- ).toEqual([
138
- {
139
- allOf: [
140
- {
141
- type: 'number',
142
- },
143
- {
144
- type: 'boolean',
145
- },
146
- ],
147
- },
148
- {
149
- type: 'string',
150
- },
151
- ]);
152
- });
153
-
154
- it('should stop at circular references', () => {
155
- const a: OpenAPIV3.SchemaObject = {
156
- anyOf: [
157
- {
158
- type: 'string',
159
- },
160
- ],
161
- };
162
-
163
- a.anyOf?.push(a);
164
-
165
- expect(getSchemaAlternatives(a)).toEqual([
166
- {
167
- type: 'string',
168
- },
169
- a,
170
- ]);
171
- });
172
- });