@gitbook/react-openapi 0.7.1 → 1.0.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 (118) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/InteractiveSection.d.ts +4 -8
  3. package/dist/InteractiveSection.jsx +60 -0
  4. package/dist/Markdown.d.ts +1 -2
  5. package/dist/Markdown.jsx +5 -0
  6. package/dist/OpenAPICodeSample.d.ts +2 -4
  7. package/dist/OpenAPICodeSample.jsx +141 -0
  8. package/dist/OpenAPIDisclosure.d.ts +12 -0
  9. package/dist/OpenAPIDisclosure.jsx +32 -0
  10. package/dist/OpenAPIDisclosureGroup.d.ts +19 -0
  11. package/dist/OpenAPIDisclosureGroup.jsx +81 -0
  12. package/dist/OpenAPIOperation.d.ts +2 -4
  13. package/dist/OpenAPIOperation.jsx +51 -0
  14. package/dist/OpenAPIOperationContext.d.ts +16 -0
  15. package/dist/OpenAPIOperationContext.jsx +26 -0
  16. package/dist/OpenAPIPath.d.ts +8 -0
  17. package/dist/OpenAPIPath.jsx +54 -0
  18. package/dist/OpenAPIRequestBody.d.ts +4 -5
  19. package/dist/OpenAPIRequestBody.jsx +22 -0
  20. package/dist/OpenAPIResponse.d.ts +4 -4
  21. package/dist/OpenAPIResponse.jsx +39 -0
  22. package/dist/OpenAPIResponseExample.d.ts +2 -4
  23. package/dist/OpenAPIResponseExample.jsx +108 -0
  24. package/dist/OpenAPIResponses.d.ts +3 -4
  25. package/dist/OpenAPIResponses.jsx +35 -0
  26. package/dist/OpenAPISchema.d.ts +11 -8
  27. package/dist/OpenAPISchema.jsx +285 -0
  28. package/dist/OpenAPISchemaName.d.ts +12 -0
  29. package/dist/OpenAPISchemaName.jsx +15 -0
  30. package/dist/OpenAPISecurities.d.ts +2 -4
  31. package/dist/OpenAPISecurities.jsx +55 -0
  32. package/dist/OpenAPIServerURL.d.ts +2 -3
  33. package/dist/OpenAPIServerURL.jsx +67 -0
  34. package/dist/OpenAPIServerURLVariable.d.ts +2 -3
  35. package/dist/OpenAPIServerURLVariable.jsx +8 -0
  36. package/dist/OpenAPISpec.d.ts +3 -4
  37. package/dist/OpenAPISpec.jsx +91 -0
  38. package/dist/OpenAPITabs.d.ts +26 -0
  39. package/dist/OpenAPITabs.jsx +103 -0
  40. package/dist/ScalarApiButton.d.ts +3 -3
  41. package/dist/ScalarApiButton.jsx +51 -0
  42. package/dist/code-samples.d.ts +4 -0
  43. package/dist/code-samples.js +103 -38
  44. package/dist/generateSchemaExample.d.ts +2 -2
  45. package/dist/generateSchemaExample.js +29 -102
  46. package/dist/index.d.ts +3 -2
  47. package/dist/index.js +2 -1
  48. package/dist/resolveOpenAPIOperation.d.ts +11 -0
  49. package/dist/resolveOpenAPIOperation.js +194 -0
  50. package/dist/stringifyOpenAPI.d.ts +4 -0
  51. package/dist/stringifyOpenAPI.js +6 -0
  52. package/dist/tsconfig.build.tsbuildinfo +1 -0
  53. package/dist/types.d.ts +11 -12
  54. package/dist/useSyncedTabsGlobalState.d.ts +1 -0
  55. package/dist/useSyncedTabsGlobalState.js +16 -0
  56. package/dist/utils.d.ts +6 -2
  57. package/dist/utils.js +13 -6
  58. package/package.json +12 -10
  59. package/src/InteractiveSection.tsx +90 -86
  60. package/src/Markdown.tsx +2 -3
  61. package/src/OpenAPICodeSample.tsx +43 -31
  62. package/src/OpenAPIDisclosure.tsx +50 -0
  63. package/src/OpenAPIDisclosureGroup.tsx +136 -0
  64. package/src/OpenAPIOperation.tsx +36 -42
  65. package/src/OpenAPIOperationContext.tsx +45 -0
  66. package/src/OpenAPIPath.tsx +65 -0
  67. package/src/OpenAPIRequestBody.tsx +10 -17
  68. package/src/OpenAPIResponse.tsx +27 -45
  69. package/src/OpenAPIResponseExample.tsx +89 -31
  70. package/src/OpenAPIResponses.tsx +48 -17
  71. package/src/OpenAPISchema.test.ts +1 -1
  72. package/src/OpenAPISchema.tsx +129 -108
  73. package/src/OpenAPISchemaName.tsx +27 -0
  74. package/src/OpenAPISecurities.tsx +45 -24
  75. package/src/OpenAPIServerURL.tsx +17 -10
  76. package/src/OpenAPIServerURLVariable.tsx +2 -4
  77. package/src/OpenAPISpec.tsx +58 -58
  78. package/src/OpenAPITabs.tsx +153 -0
  79. package/src/ScalarApiButton.tsx +84 -7
  80. package/src/code-samples.test.ts +51 -0
  81. package/src/code-samples.ts +95 -31
  82. package/src/generateSchemaExample.ts +26 -153
  83. package/src/index.ts +3 -2
  84. package/src/resolveOpenAPIOperation.test.ts +177 -0
  85. package/src/resolveOpenAPIOperation.ts +164 -0
  86. package/src/stringifyOpenAPI.ts +6 -0
  87. package/src/types.ts +17 -10
  88. package/src/useSyncedTabsGlobalState.ts +23 -0
  89. package/src/utils.ts +14 -7
  90. package/dist/InteractiveSection.js +0 -47
  91. package/dist/Markdown.js +0 -6
  92. package/dist/OpenAPICodeSample.js +0 -110
  93. package/dist/OpenAPIOperation.js +0 -38
  94. package/dist/OpenAPIRequestBody.js +0 -18
  95. package/dist/OpenAPIResponse.js +0 -32
  96. package/dist/OpenAPIResponseExample.js +0 -54
  97. package/dist/OpenAPIResponses.js +0 -18
  98. package/dist/OpenAPISchema.js +0 -235
  99. package/dist/OpenAPISchema.test.d.ts +0 -1
  100. package/dist/OpenAPISchema.test.js +0 -91
  101. package/dist/OpenAPISecurities.js +0 -42
  102. package/dist/OpenAPIServerURL.js +0 -51
  103. package/dist/OpenAPIServerURLVariable.js +0 -10
  104. package/dist/OpenAPISpec.js +0 -70
  105. package/dist/ScalarApiButton.js +0 -14
  106. package/dist/fetchOpenAPIOperation.d.ts +0 -72
  107. package/dist/fetchOpenAPIOperation.js +0 -124
  108. package/dist/fetchOpenAPIOperation.test.d.ts +0 -1
  109. package/dist/fetchOpenAPIOperation.test.js +0 -152
  110. package/dist/resolveOpenAPIPath.d.ts +0 -7
  111. package/dist/resolveOpenAPIPath.js +0 -112
  112. package/dist/resolveOpenAPIPath.test.d.ts +0 -1
  113. package/dist/resolveOpenAPIPath.test.js +0 -39
  114. package/dist/tsconfig.tsbuildinfo +0 -1
  115. package/src/fetchOpenAPIOperation.test.ts +0 -185
  116. package/src/fetchOpenAPIOperation.ts +0 -230
  117. package/src/resolveOpenAPIPath.test.ts +0 -60
  118. package/src/resolveOpenAPIPath.ts +0 -145
@@ -0,0 +1,45 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext, useMemo } from 'react';
4
+ import { useEventCallback } from 'usehooks-ts';
5
+
6
+ interface OpenAPIOperationPointer {
7
+ path: string;
8
+ method: string;
9
+ }
10
+
11
+ interface OpenAPIOperationContextValue {
12
+ onOpenClient: (pointer: OpenAPIOperationPointer) => void;
13
+ }
14
+
15
+ const OpenAPIOperationContext = createContext<OpenAPIOperationContextValue>({
16
+ onOpenClient: () => {},
17
+ });
18
+
19
+ /**
20
+ * Provider for the OpenAPIOperationContext.
21
+ */
22
+ export function OpenAPIOperationContextProvider(
23
+ props: React.PropsWithChildren<Partial<OpenAPIOperationContextValue>>,
24
+ ) {
25
+ const { children } = props;
26
+
27
+ const onOpenClient = useEventCallback((pointer: OpenAPIOperationPointer) => {
28
+ props.onOpenClient?.(pointer);
29
+ });
30
+
31
+ const value = useMemo(() => ({ onOpenClient }), [onOpenClient]);
32
+
33
+ return (
34
+ <OpenAPIOperationContext.Provider value={value}>
35
+ {children}
36
+ </OpenAPIOperationContext.Provider>
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Hook to access the OpenAPIOperationContext.
42
+ */
43
+ export function useOpenAPIOperationContext() {
44
+ return useContext(OpenAPIOperationContext);
45
+ }
@@ -0,0 +1,65 @@
1
+ import { ScalarApiButton } from './ScalarApiButton';
2
+ import type { OpenAPIOperationData, OpenAPIContextProps } from './types';
3
+
4
+ /**
5
+ * Display the path of an operation.
6
+ */
7
+ export function OpenAPIPath(props: {
8
+ data: OpenAPIOperationData;
9
+ context: OpenAPIContextProps;
10
+ }): JSX.Element {
11
+ const { data, context } = props;
12
+ const { method, path } = data;
13
+ const { specUrl } = context;
14
+
15
+ return (
16
+ <div className="openapi-path">
17
+ <div className={`openapi-method openapi-method-${method}`}>{method}</div>
18
+ <div className="openapi-path-title" data-deprecated={data.operation.deprecated}>
19
+ <p>{formatPath(path)}</p>
20
+ </div>
21
+ {data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'] ? null : (
22
+ <ScalarApiButton method={method} path={path} specUrl={specUrl} />
23
+ )}
24
+ </div>
25
+ );
26
+ }
27
+
28
+ // Format the path to highlight placeholders
29
+ function formatPath(path: string) {
30
+ // Matches placeholders like {id}, {userId}, etc.
31
+ const regex = /\{(\w+)\}/g;
32
+
33
+ const parts: (string | JSX.Element)[] = [];
34
+ let lastIndex = 0;
35
+
36
+ // Replace placeholders with <em> tags
37
+ path.replace(regex, (match, key, offset) => {
38
+ parts.push(path.slice(lastIndex, offset));
39
+ parts.push(<em key={key}>{`{${key}}`}</em>);
40
+ lastIndex = offset + match.length;
41
+ return match;
42
+ });
43
+
44
+ // Push remaining text after the last placeholder
45
+ parts.push(path.slice(lastIndex));
46
+
47
+ // Join parts with separators wrapped in <span>
48
+ const formattedPath = parts.reduce(
49
+ (acc, part, index) => {
50
+ if (typeof part === 'string' && index > 0 && part === '/') {
51
+ return [
52
+ ...acc,
53
+ <span className="openapi-path-separator" key={`sep-${index}`}>
54
+ /
55
+ </span>,
56
+ part,
57
+ ];
58
+ }
59
+ return [...acc, part];
60
+ },
61
+ [] as (string | JSX.Element)[],
62
+ );
63
+
64
+ return <span>{formattedPath}</span>;
65
+ }
@@ -1,21 +1,22 @@
1
- import * as React from 'react';
2
-
3
- import { OpenAPIV3 } from 'openapi-types';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
4
2
  import { OpenAPIRootSchema } from './OpenAPISchema';
5
- import { noReference } from './utils';
6
- import { OpenAPIClientContext } from './types';
3
+ import type { OpenAPIClientContext } from './types';
7
4
  import { InteractiveSection } from './InteractiveSection';
8
- import { Markdown } from './Markdown';
5
+ import { checkIsReference } from './utils';
9
6
 
10
7
  /**
11
8
  * Display an interactive request body.
12
9
  */
13
10
  export function OpenAPIRequestBody(props: {
14
- requestBody: OpenAPIV3.RequestBodyObject;
11
+ requestBody: OpenAPIV3.RequestBodyObject | OpenAPIV3.ReferenceObject;
15
12
  context: OpenAPIClientContext;
16
13
  }) {
17
14
  const { requestBody, context } = props;
18
15
 
16
+ if (checkIsReference(requestBody)) {
17
+ return null;
18
+ }
19
+
19
20
  return (
20
21
  <InteractiveSection
21
22
  header="Body"
@@ -27,21 +28,13 @@ export function OpenAPIRequestBody(props: {
27
28
  label: contentType,
28
29
  body: (
29
30
  <OpenAPIRootSchema
30
- schema={noReference(mediaTypeObject.schema) ?? {}}
31
+ schema={mediaTypeObject.schema ?? {}}
31
32
  context={context}
32
33
  />
33
34
  ),
34
35
  };
35
36
  },
36
37
  )}
37
- defaultOpened={context.defaultInteractiveOpened}
38
- >
39
- {requestBody.description ? (
40
- <Markdown
41
- source={requestBody.description}
42
- className="openapi-requestbody-description"
43
- />
44
- ) : null}
45
- </InteractiveSection>
38
+ />
46
39
  );
47
40
  }
@@ -1,72 +1,54 @@
1
- import * as React from 'react';
2
- import classNames from 'classnames';
3
- import { OpenAPIV3 } from 'openapi-types';
4
- import { OpenAPIRootSchema, OpenAPISchemaProperties } from './OpenAPISchema';
5
- import { noReference } from './utils';
6
- import { OpenAPIClientContext } from './types';
7
- import { InteractiveSection } from './InteractiveSection';
8
- import { Markdown } from './Markdown';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
+ import { OpenAPISchemaProperties } from './OpenAPISchema';
3
+ import { resolveDescription } from './utils';
4
+ import type { OpenAPIClientContext } from './types';
5
+ import { OpenAPIDisclosure } from './OpenAPIDisclosure';
9
6
 
10
7
  /**
11
8
  * Display an interactive response body.
12
9
  */
13
10
  export function OpenAPIResponse(props: {
14
11
  response: OpenAPIV3.ResponseObject;
12
+ mediaType: OpenAPIV3.MediaTypeObject;
15
13
  context: OpenAPIClientContext;
16
14
  }) {
17
- const { response, context } = props;
18
- const content = Object.entries(response.content ?? {});
15
+ const { response, context, mediaType } = props;
19
16
  const headers = Object.entries(response.headers ?? {}).map(
20
- ([name, header]) => [name, noReference(header) ?? {}] as const,
17
+ ([name, header]) => [name, header ?? {}] as const,
21
18
  );
19
+ const content = Object.entries(mediaType.schema ?? {});
22
20
 
23
- if (content.length === 0 && !response.description && headers.length === 0) {
21
+ const description = resolveDescription(response);
22
+
23
+ if (content.length === 0 && !description && headers.length === 0) {
24
24
  return null;
25
25
  }
26
26
 
27
27
  return (
28
- <>
29
- {response.description ? (
30
- <Markdown source={response.description} className="openapi-response-description" />
31
- ) : null}
32
-
28
+ <div className="openapi-response-body">
33
29
  {headers.length > 0 ? (
34
- <InteractiveSection
35
- toggeable
36
- defaultOpened={!!context.defaultInteractiveOpened}
37
- toggleCloseIcon={context.icons.chevronDown}
38
- toggleOpenIcon={context.icons.chevronRight}
39
- header="Headers"
40
- className={classNames('openapi-responseheaders')}
41
- >
30
+ <OpenAPIDisclosure context={context} label={'Headers'}>
42
31
  <OpenAPISchemaProperties
43
32
  properties={headers.map(([name, header]) => ({
44
33
  propertyName: name,
45
- schema: noReference(header.schema) ?? {},
34
+ schema: header.schema ?? {},
46
35
  required: header.required,
47
36
  }))}
48
37
  context={context}
49
38
  />
50
- </InteractiveSection>
39
+ </OpenAPIDisclosure>
51
40
  ) : null}
52
- {content.length > 0 ? (
53
- <InteractiveSection
54
- header="Body"
55
- className={classNames('openapi-responsebody')}
56
- tabs={content.map(([contentType, mediaType]) => {
57
- return {
58
- key: contentType,
59
- label: contentType,
60
- body: (
61
- <OpenAPIRootSchema
62
- schema={noReference(mediaType.schema) ?? {}}
63
- context={context}
64
- />
65
- ),
66
- };
67
- })}
41
+ <div className="openapi-responsebody">
42
+ <OpenAPISchemaProperties
43
+ id={`response-${context.blockKey}`}
44
+ properties={[
45
+ {
46
+ schema: mediaType.schema ?? {},
47
+ },
48
+ ]}
49
+ context={context}
68
50
  />
69
- ) : null}
70
- </>
51
+ </div>
52
+ </div>
71
53
  );
72
54
  }
@@ -1,9 +1,10 @@
1
- import * as React from 'react';
2
- import { InteractiveSection } from './InteractiveSection';
3
- import { OpenAPIOperationData } from './fetchOpenAPIOperation';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
4
2
  import { generateSchemaExample } from './generateSchemaExample';
5
- import { OpenAPIContextProps } from './types';
6
- import { createStateKey, noReference } from './utils';
3
+ import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
4
+ import { checkIsReference, createStateKey, resolveDescription } from './utils';
5
+ import { stringifyOpenAPI } from './stringifyOpenAPI';
6
+ import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
7
+ import { InteractiveSection } from './InteractiveSection';
7
8
 
8
9
  /**
9
10
  * Display an example of the response content.
@@ -38,50 +39,107 @@ export function OpenAPIResponseExample(props: {
38
39
  });
39
40
 
40
41
  const examples = responses
41
- .map((response) => {
42
- const responseObject = noReference(response[1]);
43
-
44
- const schema = noReference(
45
- (
46
- responseObject.content?.['application/json'] ??
47
- responseObject.content?.[Object.keys(responseObject.content)[0]]
48
- )?.schema,
49
- );
42
+ .map(([key, value]) => {
43
+ const responseObject = value;
44
+ const mediaTypeObject = (() => {
45
+ if (!responseObject.content) {
46
+ return null;
47
+ }
48
+ const key = Object.keys(responseObject.content)[0];
49
+ return (
50
+ responseObject.content['application/json'] ??
51
+ (key ? responseObject.content[key] : null)
52
+ );
53
+ })();
50
54
 
51
- if (!schema) {
52
- return null;
55
+ if (!mediaTypeObject) {
56
+ return {
57
+ key: key,
58
+ label: key,
59
+ description: resolveDescription(responseObject),
60
+ body: <OpenAPIEmptyResponseExample />,
61
+ };
53
62
  }
54
63
 
55
- const example = generateSchemaExample(schema);
56
- if (example === undefined) {
57
- return null;
58
- }
64
+ const example = handleUnresolvedReference(
65
+ (() => {
66
+ const { examples, example } = mediaTypeObject;
67
+ if (examples) {
68
+ const key = Object.keys(examples)[0];
69
+ if (key) {
70
+ // @TODO handle multiple examples
71
+ const firstExample = examples[key];
72
+ if (firstExample) {
73
+ return firstExample;
74
+ }
75
+ }
76
+ }
77
+
78
+ if (example) {
79
+ return { value: example };
80
+ }
81
+
82
+ const schema = mediaTypeObject.schema;
83
+ if (!schema) {
84
+ return null;
85
+ }
86
+
87
+ return { value: generateSchemaExample(schema) };
88
+ })(),
89
+ );
59
90
 
60
91
  return {
61
- key: `${response[0]}`,
62
- label: `${response[0]}`,
63
- body: (
92
+ key: key,
93
+ label: key,
94
+ description: resolveDescription(responseObject),
95
+ body: example?.value ? (
64
96
  <context.CodeBlock
65
97
  code={
66
- typeof example === 'string' ? example : JSON.stringify(example, null, 2)
98
+ typeof example.value === 'string'
99
+ ? example.value
100
+ : stringifyOpenAPI(example.value, null, 2)
67
101
  }
68
102
  syntax="json"
69
103
  />
104
+ ) : (
105
+ <OpenAPIEmptyResponseExample />
70
106
  ),
71
107
  };
72
108
  })
73
- .filter((val): val is { key: string; label: string; body: any } => Boolean(val));
109
+ .filter((val): val is { key: string; label: string; body: any; description: string } =>
110
+ Boolean(val),
111
+ );
74
112
 
75
113
  if (examples.length === 0) {
76
114
  return null;
77
115
  }
78
116
 
79
117
  return (
80
- <InteractiveSection
81
- stateKey={createStateKey('response', context.blockKey)}
82
- header="Response"
83
- className="openapi-response-example"
84
- tabs={examples}
85
- />
118
+ <OpenAPITabs stateKey={createStateKey('response-example')} items={examples}>
119
+ <InteractiveSection header={<OpenAPITabsList />} className="openapi-response-example">
120
+ <OpenAPITabsPanels />
121
+ </InteractiveSection>
122
+ </OpenAPITabs>
86
123
  );
87
124
  }
125
+
126
+ function OpenAPIEmptyResponseExample() {
127
+ return (
128
+ <pre className="openapi-response-example-empty">
129
+ <p>No body</p>
130
+ </pre>
131
+ );
132
+ }
133
+
134
+ function handleUnresolvedReference(
135
+ input: OpenAPIV3.ExampleObject | null,
136
+ ): OpenAPIV3.ExampleObject | null {
137
+ const isReference = checkIsReference(input?.value);
138
+
139
+ if (isReference) {
140
+ // If we find a reference that wasn't resolved or needed to be resolved externally, render out the URL
141
+ return { value: input.value.$ref };
142
+ }
143
+
144
+ return input;
145
+ }
@@ -1,32 +1,63 @@
1
- import * as React from 'react';
2
- import classNames from 'classnames';
3
- import { OpenAPIV3 } from 'openapi-types';
4
- import { createStateKey, noReference } from './utils';
1
+ import type { OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
5
2
  import { OpenAPIResponse } from './OpenAPIResponse';
6
3
  import { OpenAPIClientContext } from './types';
7
4
  import { InteractiveSection } from './InteractiveSection';
5
+ import { OpenAPIDisclosureGroup } from './OpenAPIDisclosureGroup';
6
+ import { Markdown } from './Markdown';
8
7
 
9
8
  /**
10
9
  * Display an interactive response body.
11
10
  */
12
11
  export function OpenAPIResponses(props: {
13
- responses: OpenAPIV3.ResponsesObject;
12
+ responses: OpenAPIV3.ResponsesObject | OpenAPIV3_1.ResponsesObject;
14
13
  context: OpenAPIClientContext;
15
14
  }) {
16
15
  const { responses, context } = props;
17
16
 
18
17
  return (
19
- <InteractiveSection
20
- stateKey={createStateKey('response', context.blockKey)}
21
- header="Response"
22
- className={classNames('openapi-responses')}
23
- tabs={Object.entries(responses).map(([statusCode, response]) => {
24
- return {
25
- key: statusCode,
26
- label: statusCode,
27
- body: <OpenAPIResponse response={noReference(response)} context={context} />,
28
- };
29
- })}
30
- />
18
+ <InteractiveSection header="Responses" className="openapi-responses">
19
+ <OpenAPIDisclosureGroup
20
+ allowsMultipleExpanded
21
+ icon={context.icons.chevronRight}
22
+ groups={Object.entries(responses).map(
23
+ ([statusCode, response]: [string, OpenAPIV3.ResponseObject]) => {
24
+ const content = Object.entries(response.content ?? {});
25
+ const description = response.description;
26
+
27
+ return {
28
+ id: statusCode,
29
+ label: (
30
+ <div
31
+ className="openapi-response-tab-content"
32
+ key={`response-${statusCode}`}
33
+ >
34
+ <span className="openapi-response-statuscode">
35
+ {statusCode}
36
+ </span>
37
+ {description ? (
38
+ <Markdown
39
+ source={description}
40
+ className="openapi-response-description"
41
+ />
42
+ ) : null}
43
+ </div>
44
+ ),
45
+ tabs: content.map(([contentType, mediaType]) => ({
46
+ id: contentType,
47
+ label: contentType,
48
+ body: (
49
+ <OpenAPIResponse
50
+ key={`$response-${statusCode}-${contentType}`}
51
+ response={response}
52
+ mediaType={mediaType}
53
+ context={context}
54
+ />
55
+ ),
56
+ })),
57
+ };
58
+ },
59
+ )}
60
+ />
61
+ </InteractiveSection>
31
62
  );
32
63
  }
@@ -1,6 +1,6 @@
1
1
  import { it, describe, expect } from 'bun:test';
2
2
  import { getSchemaAlternatives } from './OpenAPISchema';
3
- import { OpenAPIV3 } from 'openapi-types';
3
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
4
4
 
5
5
  describe('getSchemaAlternatives', () => {
6
6
  it('should flatten oneOf', () => {