@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
@@ -1,16 +1,18 @@
1
- import classNames from 'classnames';
2
- import { OpenAPIV3 } from 'openapi-types';
3
- import React, { useId } from 'react';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
+ import clsx from 'clsx';
3
+ import { useId } from 'react';
4
4
 
5
5
  import { InteractiveSection } from './InteractiveSection';
6
6
  import { Markdown } from './Markdown';
7
- import { SYMBOL_REF_RESOLVED } from './resolveOpenAPIPath';
8
- import { OpenAPIClientContext } from './types';
9
- import { noReference } from './utils';
7
+ import type { OpenAPIClientContext } from './types';
8
+ import { checkIsReference, resolveDescription } from './utils';
9
+ import { stringifyOpenAPI } from './stringifyOpenAPI';
10
+ import { OpenAPISchemaName } from './OpenAPISchemaName';
11
+ import { OpenAPIDisclosure } from './OpenAPIDisclosure';
10
12
 
11
13
  type CircularRefsIds = Map<OpenAPIV3.SchemaObject, string>;
12
14
 
13
- interface OpenAPISchemaPropertyEntry {
15
+ export interface OpenAPISchemaPropertyEntry {
14
16
  propertyName?: string;
15
17
  required?: boolean;
16
18
  schema: OpenAPIV3.SchemaObject;
@@ -28,8 +30,6 @@ export function OpenAPISchemaProperty(
28
30
  },
29
31
  ) {
30
32
  const {
31
- propertyName,
32
- required,
33
33
  schema,
34
34
  circularRefs: parentCircularRefs = new Map<OpenAPIV3.SchemaObject, string>(),
35
35
  context,
@@ -47,71 +47,42 @@ export function OpenAPISchemaProperty(
47
47
  ? null
48
48
  : getSchemaAlternatives(schema, new Set(circularRefs.keys()));
49
49
 
50
- const shouldDisplayExample = (schema: OpenAPIV3.SchemaObject): boolean => {
50
+ if ((properties && !!properties.length) || schema.type === 'object') {
51
51
  return (
52
- typeof schema.example === 'string' ||
53
- typeof schema.example === 'number' ||
54
- typeof schema.example === 'boolean'
52
+ <InteractiveSection id={id} className={clsx('openapi-schema', className)}>
53
+ <OpenAPISchemaPresentation {...props} />
54
+ {properties && properties.length > 0 ? (
55
+ <OpenAPIDisclosure context={context}>
56
+ <OpenAPISchemaProperties
57
+ properties={properties}
58
+ circularRefs={circularRefs}
59
+ context={context}
60
+ />
61
+ </OpenAPIDisclosure>
62
+ ) : null}
63
+ </InteractiveSection>
55
64
  );
56
- };
57
- return (
58
- <InteractiveSection
59
- id={id}
60
- className={classNames('openapi-schema', className)}
61
- toggeable={!!properties || !!alternatives}
62
- defaultOpened={!!context.defaultInteractiveOpened}
63
- toggleOpenIcon={context.icons.chevronRight}
64
- toggleCloseIcon={context.icons.chevronDown}
65
- tabs={alternatives?.[0].map((alternative, index) => ({
66
- key: `${index}`,
67
- label: getSchemaTitle(alternative, alternatives[1]),
68
- body: circularRefs.has(alternative) ? (
69
- <OpenAPISchemaCircularRef
70
- id={circularRefs.get(alternative)!}
71
- schema={alternative}
72
- />
73
- ) : (
65
+ }
66
+
67
+ if (alternatives?.[0]?.length) {
68
+ return (
69
+ <InteractiveSection id={id} className={clsx('openapi-schema', className)}>
70
+ <OpenAPISchemaPresentation {...props} />
71
+ {alternatives[0].map((alternative, index) => (
74
72
  <OpenAPISchemaAlternative
73
+ key={`alternative-${index}`}
75
74
  schema={alternative}
76
75
  circularRefs={circularRefs}
77
76
  context={context}
78
77
  />
79
- ),
80
- }))}
81
- header={
82
- <div className={classNames('openapi-schema-presentation')}>
83
- <div className={classNames('openapi-schema-name')}>
84
- {propertyName ? (
85
- <span className={classNames('openapi-schema-propertyname')}>
86
- {propertyName}
87
- </span>
88
- ) : null}
89
- {required ? (
90
- <span className={classNames('openapi-schema-required')}>*</span>
91
- ) : null}
92
- <span className={classNames('openapi-schema-type')}>
93
- {getSchemaTitle(schema)}
94
- </span>
95
- </div>
96
- {schema.description ? (
97
- <Markdown
98
- source={schema.description}
99
- className="openapi-schema-description"
100
- />
101
- ) : null}
102
- {shouldDisplayExample(schema) ? (
103
- <span className="openapi-schema-example">
104
- Example: <code>{JSON.stringify(schema.example)}</code>
105
- </span>
106
- ) : null}
107
- {schema.pattern ? (
108
- <div className="openapi-schema-pattern">
109
- Pattern: <code>{schema.pattern}</code>
110
- </div>
111
- ) : null}
112
- </div>
113
- }
114
- >
78
+ ))}
79
+ </InteractiveSection>
80
+ );
81
+ }
82
+
83
+ return (
84
+ <InteractiveSection id={id} className={clsx('openapi-schema', className)}>
85
+ <OpenAPISchemaPresentation {...props} />
115
86
  {(properties && properties.length > 0) ||
116
87
  (schema.enum && schema.enum.length > 0) ||
117
88
  parentCircularRef ? (
@@ -123,9 +94,6 @@ export function OpenAPISchemaProperty(
123
94
  context={context}
124
95
  />
125
96
  ) : null}
126
- {schema.enum && schema.enum.length > 0 ? (
127
- <OpenAPISchemaEnum enumValues={schema.enum} />
128
- ) : null}
129
97
  {parentCircularRef ? (
130
98
  <OpenAPISchemaCircularRef id={parentCircularRef} schema={schema} />
131
99
  ) : null}
@@ -151,7 +119,7 @@ export function OpenAPISchemaProperties(props: {
151
119
  }
152
120
 
153
121
  return (
154
- <div id={id} className={classNames('openapi-schema-properties')}>
122
+ <div id={id} className="openapi-schema-properties">
155
123
  {properties.map((property) => (
156
124
  <OpenAPISchemaProperty
157
125
  key={property.propertyName}
@@ -200,12 +168,14 @@ function OpenAPISchemaAlternative(props: {
200
168
  const subProperties = getSchemaProperties(schema);
201
169
 
202
170
  return (
203
- <OpenAPISchemaProperties
204
- id={id}
205
- properties={subProperties ?? [{ schema }]}
206
- circularRefs={subProperties ? new Map(circularRefs).set(schema, id) : circularRefs}
207
- context={context}
208
- />
171
+ <OpenAPIDisclosure context={context}>
172
+ <OpenAPISchemaProperties
173
+ id={id}
174
+ properties={subProperties ?? [{ schema }]}
175
+ circularRefs={subProperties ? new Map(circularRefs).set(schema, id) : circularRefs}
176
+ context={context}
177
+ />
178
+ </OpenAPIDisclosure>
209
179
  );
210
180
  }
211
181
 
@@ -231,9 +201,73 @@ export function OpenAPISchemaEnum(props: { enumValues: any[] }) {
231
201
 
232
202
  return (
233
203
  <div className="openapi-schema-enum">
234
- {enumValues.map((value, index) => (
235
- <span key={index} className="openapi-schema-enum-value">{`${value}`}</span>
236
- ))}
204
+ <span>
205
+ Options:{' '}
206
+ {enumValues.map((value, index) => (
207
+ <span key={index} className="openapi-schema-enum-value">
208
+ <code>{`${value}`}</code>
209
+ {index < enumValues.length - 1 ? ', ' : ''}
210
+ </span>
211
+ ))}
212
+ </span>
213
+ </div>
214
+ );
215
+ }
216
+
217
+ export function OpenAPISchemaPresentation(props: OpenAPISchemaPropertyEntry) {
218
+ const { schema, propertyName, required } = props;
219
+
220
+ const shouldDisplayExample = (schema: OpenAPIV3.SchemaObject): boolean => {
221
+ return (
222
+ typeof schema.example === 'string' ||
223
+ typeof schema.example === 'number' ||
224
+ typeof schema.example === 'boolean' ||
225
+ (Array.isArray(schema.example) && schema.example.length > 0) ||
226
+ (typeof schema.example === 'object' &&
227
+ schema.example !== null &&
228
+ Object.keys(schema.example).length > 0)
229
+ );
230
+ };
231
+
232
+ const description = resolveDescription(schema);
233
+
234
+ return (
235
+ <div className="openapi-schema-presentation">
236
+ <OpenAPISchemaName
237
+ type={getSchemaTitle(schema)}
238
+ propertyName={propertyName}
239
+ required={required}
240
+ deprecated={schema.deprecated}
241
+ />
242
+ {schema['x-deprecated-sunset'] ? (
243
+ <div className="openapi-deprecated-sunset openapi-schema-description openapi-markdown">
244
+ Sunset date:{' '}
245
+ <span className="openapi-deprecated-sunset-date">
246
+ {schema['x-deprecated-sunset']}
247
+ </span>
248
+ </div>
249
+ ) : null}
250
+ {description ? (
251
+ <Markdown source={description} className="openapi-schema-description" />
252
+ ) : null}
253
+ {shouldDisplayExample(schema) ? (
254
+ <div className="openapi-schema-example">
255
+ Example:{' '}
256
+ <code>
257
+ {typeof schema.example === 'string'
258
+ ? schema.example
259
+ : stringifyOpenAPI(schema.example)}
260
+ </code>
261
+ </div>
262
+ ) : null}
263
+ {schema.pattern ? (
264
+ <div className="openapi-schema-pattern">
265
+ Pattern: <code>{schema.pattern}</code>
266
+ </div>
267
+ ) : null}
268
+ {schema.enum && schema.enum.length > 0 ? (
269
+ <OpenAPISchemaEnum enumValues={schema.enum} />
270
+ ) : null}
237
271
  </div>
238
272
  );
239
273
  }
@@ -244,9 +278,9 @@ export function OpenAPISchemaEnum(props: { enumValues: any[] }) {
244
278
  function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISchemaPropertyEntry[] {
245
279
  if (schema.allOf) {
246
280
  return schema.allOf.reduce((acc, subSchema) => {
247
- const properties = getSchemaProperties(noReference(subSchema)) ?? [
281
+ const properties = getSchemaProperties(subSchema) ?? [
248
282
  {
249
- schema: noReference(subSchema),
283
+ schema: subSchema,
250
284
  },
251
285
  ];
252
286
  return [...acc, ...properties];
@@ -255,7 +289,7 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
255
289
 
256
290
  // check array AND schema.items as this is sometimes null despite what the type indicates
257
291
  if (schema.type === 'array' && !!schema.items) {
258
- const items = noReference(schema.items);
292
+ const items = schema.items;
259
293
  const itemProperties = getSchemaProperties(items);
260
294
  if (itemProperties) {
261
295
  return itemProperties;
@@ -273,12 +307,7 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
273
307
  const result: OpenAPISchemaPropertyEntry[] = [];
274
308
 
275
309
  if (schema.properties) {
276
- Object.entries(schema.properties).forEach(([propertyName, rawPropertySchema]) => {
277
- const propertySchema = noReference(rawPropertySchema);
278
- if (propertySchema.deprecated) {
279
- return;
280
- }
281
-
310
+ Object.entries(schema.properties).forEach(([propertyName, propertySchema]) => {
282
311
  result.push({
283
312
  propertyName,
284
313
  required: Array.isArray(schema.required)
@@ -290,7 +319,7 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
290
319
  }
291
320
 
292
321
  if (schema.additionalProperties) {
293
- const additionalProperties = noReference(schema.additionalProperties);
322
+ const additionalProperties = schema.additionalProperties;
294
323
 
295
324
  result.push({
296
325
  propertyName: 'Other properties',
@@ -314,17 +343,11 @@ export function getSchemaAlternatives(
314
343
  const downAncestors = new Set(ancestors).add(schema);
315
344
 
316
345
  if (schema.anyOf) {
317
- return [
318
- flattenAlternatives('anyOf', schema.anyOf.map(noReference), downAncestors),
319
- noReference(schema.discriminator),
320
- ];
346
+ return [flattenAlternatives('anyOf', schema.anyOf, downAncestors), schema.discriminator];
321
347
  }
322
348
 
323
349
  if (schema.oneOf) {
324
- return [
325
- flattenAlternatives('oneOf', schema.oneOf.map(noReference), downAncestors),
326
- noReference(schema.discriminator),
327
- ];
350
+ return [flattenAlternatives('oneOf', schema.oneOf, downAncestors), schema.discriminator];
328
351
  }
329
352
 
330
353
  if (schema.allOf) {
@@ -349,7 +372,7 @@ function flattenAlternatives(
349
372
  }, [] as OpenAPIV3.SchemaObject[]);
350
373
  }
351
374
 
352
- function getSchemaTitle(
375
+ export function getSchemaTitle(
353
376
  schema: OpenAPIV3.SchemaObject,
354
377
 
355
378
  /** If the title is inferred in a oneOf with discriminator, we can use it to optimize the title */
@@ -361,9 +384,9 @@ function getSchemaTitle(
361
384
  }
362
385
 
363
386
  // Try using the discriminator
364
- if (discriminator && schema.properties) {
365
- const discriminatorProperty = noReference(schema.properties[discriminator.propertyName]);
366
- if (discriminatorProperty) {
387
+ if (discriminator?.propertyName && schema.properties) {
388
+ const discriminatorProperty = schema.properties[discriminator.propertyName];
389
+ if (discriminatorProperty && !checkIsReference(discriminatorProperty)) {
367
390
  if (discriminatorProperty.enum) {
368
391
  return discriminatorProperty.enum.map((value) => value.toString()).join(' | ');
369
392
  }
@@ -377,12 +400,14 @@ function getSchemaTitle(
377
400
  type = 'enum';
378
401
  // check array AND schema.items as this is sometimes null despite what the type indicates
379
402
  } else if (schema.type === 'array' && !!schema.items) {
380
- type = `array of ${getSchemaTitle(noReference(schema.items))}`;
403
+ type = `${getSchemaTitle(schema.items)}[]`;
404
+ } else if (Array.isArray(schema.type)) {
405
+ type = schema.type.join(' | ');
381
406
  } else if (schema.type || schema.properties) {
382
407
  type = schema.type ?? 'object';
383
408
 
384
409
  if (schema.format) {
385
- type += ` (${schema.format})`;
410
+ type += ` ${schema.format}`;
386
411
  }
387
412
  } else if ('anyOf' in schema) {
388
413
  type = 'any of';
@@ -394,10 +419,6 @@ function getSchemaTitle(
394
419
  type = 'not';
395
420
  }
396
421
 
397
- if (SYMBOL_REF_RESOLVED in schema) {
398
- type = `${schema[SYMBOL_REF_RESOLVED]} (${type})`;
399
- }
400
-
401
422
  if (schema.nullable) {
402
423
  type = `nullable ${type}`;
403
424
  }
@@ -0,0 +1,27 @@
1
+ interface OpenAPISchemaNameProps {
2
+ propertyName?: string | JSX.Element;
3
+ required?: boolean;
4
+ type?: string;
5
+ deprecated?: boolean;
6
+ }
7
+
8
+ /**
9
+ * Display the schema name row.
10
+ * It includes the property name, type, required and deprecated status.
11
+ */
12
+ export function OpenAPISchemaName(props: OpenAPISchemaNameProps): JSX.Element {
13
+ const { type, propertyName, required, deprecated } = props;
14
+
15
+ return (
16
+ <div className="openapi-schema-name">
17
+ {propertyName ? (
18
+ <span data-deprecated={deprecated} className="openapi-schema-propertyname">
19
+ {propertyName}
20
+ </span>
21
+ ) : null}
22
+ {type ? <span className="openapi-schema-type">{type}</span> : null}
23
+ {required ? <span className="openapi-schema-required">required</span> : null}
24
+ {deprecated ? <span className="openapi-deprecated">Deprecated</span> : null}
25
+ </div>
26
+ );
27
+ }
@@ -1,9 +1,9 @@
1
- import * as React from 'react';
2
- import { OpenAPIV3 } from 'openapi-types';
3
- import { OpenAPIClientContext } from './types';
1
+ import type { OpenAPIV3_1 } from '@gitbook/openapi-parser';
2
+ import type { OpenAPIClientContext, OpenAPIOperationData } from './types';
4
3
  import { InteractiveSection } from './InteractiveSection';
5
4
  import { Markdown } from './Markdown';
6
- import { OpenAPIOperationData } from './fetchOpenAPIOperation';
5
+ import { OpenAPISchemaName } from './OpenAPISchemaName';
6
+ import { resolveDescription } from './utils';
7
7
 
8
8
  /**
9
9
  * Present securities authorization that can be used for this operation.
@@ -20,26 +20,29 @@ export function OpenAPISecurities(props: {
20
20
 
21
21
  return (
22
22
  <InteractiveSection
23
- header="Authorization"
24
- className="openapi-securities"
23
+ header="Authorizations"
25
24
  toggeable
26
25
  defaultOpened={false}
27
- toggleCloseIcon={context.icons.chevronDown}
28
- toggleOpenIcon={context.icons.chevronRight}
26
+ toggleIcon={context.icons.chevronRight}
27
+ className="openapi-securities"
29
28
  tabs={securities.map(([key, security]) => {
29
+ const description = resolveDescription(security);
30
30
  return {
31
31
  key: key,
32
32
  label: key,
33
33
  body: (
34
- <>
35
- <p className="openapi-securities-label">{getLabelForType(security)}</p>
36
- {security.description ? (
37
- <Markdown
38
- source={security.description}
39
- className="openapi-securities-description"
40
- />
41
- ) : null}
42
- </>
34
+ <div className="openapi-schema-body">
35
+ <div className="openapi-schema-presentation">
36
+ {getLabelForType(security)}
37
+
38
+ {description ? (
39
+ <Markdown
40
+ source={description}
41
+ className="openapi-securities-description"
42
+ />
43
+ ) : null}
44
+ </div>
45
+ </div>
43
46
  ),
44
47
  };
45
48
  })}
@@ -47,24 +50,42 @@ export function OpenAPISecurities(props: {
47
50
  );
48
51
  }
49
52
 
50
- function getLabelForType(security: OpenAPIV3.SecuritySchemeObject) {
53
+ function getLabelForType(security: OpenAPIV3_1.SecuritySchemeObject) {
51
54
  switch (security.type) {
52
55
  case 'apiKey':
53
- return 'API Key';
56
+ return (
57
+ <OpenAPISchemaName
58
+ propertyName={security.name ?? 'apiKey'}
59
+ type="string"
60
+ required
61
+ />
62
+ );
54
63
  case 'http':
55
64
  if (security.scheme === 'basic') {
56
- return 'Basic Auth';
65
+ return <OpenAPISchemaName propertyName="Authorization" type="string" required />;
57
66
  }
58
67
 
59
68
  if (security.scheme == 'bearer') {
60
- return `Bearer Token ${security.bearerFormat ? `(${security.bearerFormat})` : ''}`;
69
+ const description = resolveDescription(security);
70
+ return (
71
+ <>
72
+ <OpenAPISchemaName propertyName="Authorization" type="string" required />
73
+ {/** Show a default description if none is provided */}
74
+ {!description ? (
75
+ <Markdown
76
+ source={`Bearer authentication header of the form Bearer ${`&lt;token&gt;`}.`}
77
+ className="openapi-securities-description"
78
+ />
79
+ ) : null}
80
+ </>
81
+ );
61
82
  }
62
83
 
63
- return 'HTTP';
84
+ return <OpenAPISchemaName propertyName="HTTP" required />;
64
85
  case 'oauth2':
65
- return 'OAuth2';
86
+ return <OpenAPISchemaName propertyName="OAuth2" required />;
66
87
  case 'openIdConnect':
67
- return 'OpenID Connect';
88
+ return <OpenAPISchemaName propertyName="OpenID Connect" required />;
68
89
  default:
69
90
  // @ts-ignore
70
91
  return security.type;
@@ -1,5 +1,4 @@
1
- import * as React from 'react';
2
- import { OpenAPIV3 } from 'openapi-types';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
3
2
  import { OpenAPIServerURLVariable } from './OpenAPIServerURLVariable';
4
3
 
5
4
  /**
@@ -9,6 +8,10 @@ export function OpenAPIServerURL(props: { servers: OpenAPIV3.ServerObject[] }) {
9
8
  const { servers } = props;
10
9
  const server = servers[0];
11
10
 
11
+ if (!server) {
12
+ return null;
13
+ }
14
+
12
15
  const parts = parseServerURL(server?.url ?? '');
13
16
 
14
17
  return (
@@ -17,16 +20,13 @@ export function OpenAPIServerURL(props: { servers: OpenAPIV3.ServerObject[] }) {
17
20
  if (part.kind === 'text') {
18
21
  return <span key={i}>{part.text}</span>;
19
22
  } else {
20
- if (!server.variables?.[part.name]) {
23
+ const variable = server.variables?.[part.name];
24
+ if (!variable) {
21
25
  return <span key={i}>{`{${part.name}}`}</span>;
22
26
  }
23
27
 
24
28
  return (
25
- <OpenAPIServerURLVariable
26
- key={i}
27
- name={part.name}
28
- variable={server.variables[part.name]}
29
- />
29
+ <OpenAPIServerURLVariable key={i} name={part.name} variable={variable} />
30
30
  );
31
31
  }
32
32
  })}
@@ -39,6 +39,9 @@ export function OpenAPIServerURL(props: { servers: OpenAPIV3.ServerObject[] }) {
39
39
  */
40
40
  export function getServersURL(servers: OpenAPIV3.ServerObject[]): string {
41
41
  const server = servers[0];
42
+ if (!server) {
43
+ return '';
44
+ }
42
45
  const parts = parseServerURL(server?.url ?? '');
43
46
 
44
47
  return parts
@@ -56,10 +59,14 @@ function parseServerURL(url: string) {
56
59
  const parts = url.split(/{([^}]+)}/g);
57
60
  const result: Array<{ kind: 'variable'; name: string } | { kind: 'text'; text: string }> = [];
58
61
  for (let i = 0; i < parts.length; i++) {
62
+ const part = parts[i];
63
+ if (!part) {
64
+ continue;
65
+ }
59
66
  if (i % 2 === 0) {
60
- result.push({ kind: 'text', text: parts[i] });
67
+ result.push({ kind: 'text', text: part });
61
68
  } else {
62
- result.push({ kind: 'variable', name: parts[i] });
69
+ result.push({ kind: 'variable', name: part });
63
70
  }
64
71
  }
65
72
  return result;
@@ -1,8 +1,6 @@
1
1
  'use client';
2
2
 
3
- import * as React from 'react';
4
- import classNames from 'classnames';
5
- import { OpenAPIV3 } from 'openapi-types';
3
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
6
4
 
7
5
  /**
8
6
  * Interactive component to show the value of a server variable and let the user change it.
@@ -12,5 +10,5 @@ export function OpenAPIServerURLVariable(props: {
12
10
  variable: OpenAPIV3.ServerVariableObject;
13
11
  }) {
14
12
  const { variable } = props;
15
- return <span className={classNames('openapi-url-var')}>{variable.default}</span>;
13
+ return <span className="openapi-url-var">{variable.default}</span>;
16
14
  }