@gitbook/react-openapi 1.2.0 → 1.3.0

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 (63) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/OpenAPIDisclosure.d.ts +1 -0
  3. package/dist/OpenAPIDisclosure.jsx +6 -3
  4. package/dist/OpenAPIDisclosureGroup.jsx +17 -16
  5. package/dist/OpenAPIResponse.jsx +18 -2
  6. package/dist/OpenAPIResponseExample.jsx +8 -3
  7. package/dist/OpenAPIResponses.jsx +7 -2
  8. package/dist/OpenAPISchema.d.ts +9 -2
  9. package/dist/OpenAPISchema.jsx +93 -59
  10. package/dist/OpenAPISchemaName.d.ts +1 -1
  11. package/dist/OpenAPISchemaName.jsx +1 -1
  12. package/dist/StaticSection.jsx +1 -1
  13. package/dist/code-samples.js +5 -2
  14. package/dist/generateSchemaExample.js +5 -0
  15. package/dist/getDisclosureLabel.d.ts +7 -0
  16. package/dist/getDisclosureLabel.js +18 -0
  17. package/dist/schemas/OpenAPISchemaItem.d.ts +7 -0
  18. package/dist/schemas/OpenAPISchemaItem.jsx +16 -0
  19. package/dist/schemas/OpenAPISchemas.jsx +3 -9
  20. package/dist/translations/de.d.ts +6 -1
  21. package/dist/translations/de.js +9 -4
  22. package/dist/translations/en.d.ts +6 -1
  23. package/dist/translations/en.js +8 -3
  24. package/dist/translations/es.d.ts +6 -1
  25. package/dist/translations/es.js +9 -4
  26. package/dist/translations/fr.d.ts +6 -1
  27. package/dist/translations/fr.js +10 -5
  28. package/dist/translations/index.d.ts +54 -9
  29. package/dist/translations/ja.d.ts +6 -1
  30. package/dist/translations/ja.js +8 -3
  31. package/dist/translations/nl.d.ts +6 -1
  32. package/dist/translations/nl.js +8 -3
  33. package/dist/translations/no.d.ts +6 -1
  34. package/dist/translations/no.js +9 -4
  35. package/dist/translations/pt-br.d.ts +6 -1
  36. package/dist/translations/pt-br.js +9 -4
  37. package/dist/translations/zh.d.ts +6 -1
  38. package/dist/translations/zh.js +9 -4
  39. package/dist/tsconfig.build.tsbuildinfo +1 -1
  40. package/package.json +1 -1
  41. package/src/OpenAPIDisclosure.tsx +7 -3
  42. package/src/OpenAPIDisclosureGroup.tsx +49 -47
  43. package/src/OpenAPIResponse.tsx +34 -2
  44. package/src/OpenAPIResponseExample.tsx +36 -34
  45. package/src/OpenAPIResponses.tsx +5 -4
  46. package/src/OpenAPISchema.tsx +167 -103
  47. package/src/OpenAPISchemaName.tsx +2 -2
  48. package/src/StaticSection.tsx +1 -1
  49. package/src/code-samples.test.ts +2 -1
  50. package/src/code-samples.ts +5 -2
  51. package/src/generateSchemaExample.ts +8 -0
  52. package/src/getDisclosureLabel.ts +25 -0
  53. package/src/schemas/OpenAPISchemaItem.tsx +34 -0
  54. package/src/schemas/OpenAPISchemas.tsx +7 -13
  55. package/src/translations/de.ts +9 -4
  56. package/src/translations/en.ts +8 -3
  57. package/src/translations/es.ts +9 -4
  58. package/src/translations/fr.ts +10 -5
  59. package/src/translations/ja.ts +8 -3
  60. package/src/translations/nl.ts +8 -3
  61. package/src/translations/no.ts +9 -4
  62. package/src/translations/pt-br.ts +9 -4
  63. package/src/translations/zh.ts +9 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @gitbook/react-openapi
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 326e28e: Design tweaks to code blocks and OpenAPI pages
8
+
9
+ ### Patch Changes
10
+
11
+ - 42ca7e1: Fix openapi CR preview
12
+ - 5e975ab: Fix code highlighting for HTTP
13
+ - 580101d: Fix schemas disclosure label causing client error
14
+ - 20ebecb: Missing top-level required OpenAPI alternatives
15
+ - 80cb52a: Handle OpenAPI alternatives from schema.items
16
+ - cb5598d: Handle invalid OpenAPI Responses
17
+ - c6637b0: Use default value if string number or boolean in generateSchemaExample
18
+ - a3ec264: Fix Python code sample "null vs None"
19
+ - Updated dependencies [d00dc8c]
20
+ - @gitbook/openapi-parser@2.1.4
21
+
22
+ ## 1.2.1
23
+
24
+ ### Patch Changes
25
+
26
+ - ebc39e9: Missing select icon
27
+ - b6b09d4: Fix OpenAPI responses select placement and icon
28
+
3
29
  ## 1.2.0
4
30
 
5
31
  ### Minor Changes
@@ -4,6 +4,7 @@ import type React from 'react';
4
4
  */
5
5
  export declare function OpenAPIDisclosure(props: {
6
6
  icon: React.ReactNode;
7
+ header: React.ReactNode;
7
8
  children: React.ReactNode;
8
9
  label: string | ((isExpanded: boolean) => string);
9
10
  className?: string;
@@ -6,7 +6,7 @@ import { Button, Disclosure, DisclosurePanel } from 'react-aria-components';
6
6
  * Display an interactive OpenAPI disclosure.
7
7
  */
8
8
  export function OpenAPIDisclosure(props) {
9
- var icon = props.icon, children = props.children, label = props.label, className = props.className;
9
+ var icon = props.icon, header = props.header, label = props.label, children = props.children, className = props.className;
10
10
  var _a = useState(false), isExpanded = _a[0], setIsExpanded = _a[1];
11
11
  return (<Disclosure className={clsx('openapi-disclosure', className)} isExpanded={isExpanded} onExpandedChange={setIsExpanded}>
12
12
  <Button slot="trigger" className="openapi-disclosure-trigger" style={function (_a) {
@@ -17,8 +17,11 @@ export function OpenAPIDisclosure(props) {
17
17
  : 'none',
18
18
  });
19
19
  }}>
20
- {icon}
21
- <span>{typeof label === 'function' ? label(isExpanded) : label}</span>
20
+ {header}
21
+ <div className="openapi-disclosure-trigger-label">
22
+ <span>{typeof label === 'function' ? label(isExpanded) : label}</span>
23
+ {icon}
24
+ </div>
22
25
  </Button>
23
26
  <DisclosurePanel className="openapi-disclosure-panel">
24
27
  {isExpanded ? children : null}
@@ -50,29 +50,30 @@ function DisclosureItem(props) {
50
50
  var store = useSelectState(selectStateKey, defaultTab);
51
51
  var selectedTab = ((_d = group.tabs) === null || _d === void 0 ? void 0 : _d.find(function (tab) { return tab.key === store.key; })) || ((_e = group.tabs) === null || _e === void 0 ? void 0 : _e[0]);
52
52
  return (<div className="openapi-disclosure-group" aria-expanded={state.isExpanded}>
53
- <div className="openapi-disclosure-group-header">
54
- <button slot="trigger" ref={triggerRef} {...mergeProps(buttonProps, focusProps)} disabled={isDisabled} style={{
53
+ <div slot="trigger" ref={triggerRef} {...mergeProps(buttonProps, focusProps)} aria-disabled={isDisabled} style={{
55
54
  outline: isFocusVisible
56
55
  ? '2px solid rgb(var(--primary-color-500)/0.4)'
57
56
  : 'none',
58
57
  }} className="openapi-disclosure-group-trigger">
59
- <div className="openapi-disclosure-group-icon">
60
- {icon || (<svg viewBox="0 0 24 24" className="openapi-disclosure-group-icon">
61
- <path d="m8.25 4.5 7.5 7.5-7.5 7.5"/>
62
- </svg>)}
63
- </div>
58
+ <div className="openapi-disclosure-group-icon">
59
+ {icon || (<svg viewBox="0 0 24 24" className="openapi-disclosure-group-icon">
60
+ <path d="m8.25 4.5 7.5 7.5-7.5 7.5"/>
61
+ </svg>)}
62
+ </div>
64
63
 
64
+ <div className="openapi-disclosure-group-label">
65
65
  {group.label}
66
- </button>
67
- {group.tabs ? (<div className="openapi-disclosure-group-mediatype" onClick={function (e) { return e.stopPropagation(); }}>
68
- {((_f = group.tabs) === null || _f === void 0 ? void 0 : _f.length) > 1 ? (<OpenAPISelect icon={selectIcon} stateKey={selectStateKey} onSelectionChange={function () {
66
+
67
+ {group.tabs ? (<div className="openapi-disclosure-group-mediatype" onClick={function (e) { return e.stopPropagation(); }}>
68
+ {((_f = group.tabs) === null || _f === void 0 ? void 0 : _f.length) > 1 ? (<OpenAPISelect icon={selectIcon} stateKey={selectStateKey} onSelectionChange={function () {
69
69
  state.expand();
70
- }} items={group.tabs}>
71
- {group.tabs.map(function (tab) { return (<OpenAPISelectItem key={tab.key} id={tab.key} value={tab}>
72
- {tab.label}
73
- </OpenAPISelectItem>); })}
74
- </OpenAPISelect>) : ((_g = group.tabs[0]) === null || _g === void 0 ? void 0 : _g.label) ? (<span>{group.tabs[0].label}</span>) : null}
75
- </div>) : null}
70
+ }} items={group.tabs} placement="bottom end">
71
+ {group.tabs.map(function (tab) { return (<OpenAPISelectItem key={tab.key} id={tab.key} value={tab}>
72
+ {tab.label}
73
+ </OpenAPISelectItem>); })}
74
+ </OpenAPISelect>) : ((_g = group.tabs[0]) === null || _g === void 0 ? void 0 : _g.label) ? (<span>{group.tabs[0].label}</span>) : null}
75
+ </div>) : null}
76
+ </div>
76
77
  </div>
77
78
 
78
79
  {state.isExpanded && selectedTab && (<div className="openapi-disclosure-group-panel" ref={panelRef} {...panelProps}>
@@ -10,7 +10,9 @@ var __assign = (this && this.__assign) || function () {
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
12
  import { OpenAPIDisclosure } from './OpenAPIDisclosure';
13
+ import { OpenAPISchemaPresentation } from './OpenAPISchema';
13
14
  import { OpenAPISchemaProperties } from './OpenAPISchemaServer';
15
+ import { tString } from './translate';
14
16
  import { parameterToProperty, resolveDescription } from './utils';
15
17
  /**
16
18
  * Display an interactive response body.
@@ -28,14 +30,28 @@ export function OpenAPIResponse(props) {
28
30
  return null;
29
31
  }
30
32
  return (<div className="openapi-response-body">
31
- {headers.length > 0 ? (<OpenAPIDisclosure icon={context.icons.plus} label="Headers">
33
+ {headers.length > 0 ? (<OpenAPIDisclosure header={<OpenAPISchemaPresentation context={context} property={{
34
+ propertyName: tString(context.translation, 'headers'),
35
+ schema: {
36
+ type: 'object',
37
+ },
38
+ required: null,
39
+ }}/>} icon={context.icons.plus} label={function (isExpanded) {
40
+ return tString(context.translation, isExpanded ? 'hide' : 'show', tString(context.translation, headers.length === 1 ? 'header' : 'headers'));
41
+ }}>
32
42
  <OpenAPISchemaProperties properties={headers.map(function (_a) {
33
43
  var name = _a[0], header = _a[1];
34
44
  return parameterToProperty(__assign({ name: name }, header));
35
45
  })} context={context}/>
36
46
  </OpenAPIDisclosure>) : null}
37
47
  {mediaType.schema && (<div className="openapi-responsebody">
38
- <OpenAPISchemaProperties id={"response-".concat(context.blockKey)} properties={[{ schema: mediaType.schema }]} context={context}/>
48
+ <OpenAPISchemaProperties id={"response-".concat(context.blockKey)} properties={[
49
+ {
50
+ schema: mediaType.schema,
51
+ propertyName: tString(context.translation, 'response'),
52
+ required: null,
53
+ },
54
+ ]} context={context}/>
39
55
  </div>)}
40
56
  </div>);
41
57
  }
@@ -4,8 +4,8 @@ import { OpenAPIMediaTypeContent } from './OpenAPIMediaType';
4
4
  import { OpenAPIResponseExampleContent } from './OpenAPIResponseExampleContent';
5
5
  import { getOpenAPIClientContext } from './context';
6
6
  import { getExampleFromReference, getExamples } from './util/example';
7
- import { createStateKey, getStatusCodeDefaultLabel } from './utils';
8
- import { checkIsReference, resolveDescription } from './utils';
7
+ import { createStateKey, getStatusCodeDefaultLabel, resolveDescription } from './utils';
8
+ import { checkIsReference } from './utils';
9
9
  /**
10
10
  * Display an example of the response content.
11
11
  */
@@ -34,7 +34,12 @@ export function OpenAPIResponseExample(props) {
34
34
  }
35
35
  return Number(a) - Number(b);
36
36
  });
37
- var tabs = responses.map(function (_a) {
37
+ var tabs = responses
38
+ .filter(function (_a) {
39
+ var _ = _a[0], responseObject = _a[1];
40
+ return responseObject && typeof responseObject === 'object';
41
+ })
42
+ .map(function (_a) {
38
43
  var key = _a[0], responseObject = _a[1];
39
44
  var description = resolveDescription(responseObject);
40
45
  var label = description ? (<Markdown source={description}/>) : (getStatusCodeDefaultLabel(key, context));
@@ -13,7 +13,12 @@ import { createStateKey, getStatusCodeClassName, getStatusCodeDefaultLabel } fro
13
13
  export function OpenAPIResponses(props) {
14
14
  var _a;
15
15
  var responses = props.responses, context = props.context;
16
- var groups = Object.entries(responses).map(function (_a) {
16
+ var groups = Object.entries(responses)
17
+ .filter(function (_a) {
18
+ var _ = _a[0], response = _a[1];
19
+ return response && typeof response === 'object';
20
+ })
21
+ .map(function (_a) {
17
22
  var statusCode = _a[0], response = _a[1];
18
23
  var tabs = (function () {
19
24
  var _a;
@@ -56,6 +61,6 @@ export function OpenAPIResponses(props) {
56
61
  var _a;
57
62
  var key = (_a = keys.values().next().value) !== null && _a !== void 0 ? _a : null;
58
63
  state.setKey(key);
59
- }} groups={groups} selectStateKey={createStateKey('response-media-types', context.blockKey)}/>
64
+ }} groups={groups} selectIcon={context.icons.chevronDown} selectStateKey={createStateKey('response-media-types', context.blockKey)}/>
60
65
  </StaticSection>);
61
66
  }
@@ -1,8 +1,8 @@
1
1
  import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
2
  import type { OpenAPIClientContext } from './context';
3
3
  export interface OpenAPISchemaPropertyEntry {
4
- propertyName?: string | undefined;
5
- required?: boolean | undefined;
4
+ propertyName?: string;
5
+ required?: boolean | null;
6
6
  schema: OpenAPIV3.SchemaObject;
7
7
  }
8
8
  export declare function OpenAPISchemaPropertiesFromServer(props: {
@@ -14,6 +14,13 @@ export declare function OpenAPIRootSchemaFromServer(props: {
14
14
  schema: string;
15
15
  context: OpenAPIClientContext;
16
16
  }): import("react").JSX.Element;
17
+ /**
18
+ * Render the top row of a schema. e.g: name, type, and required status.
19
+ */
20
+ export declare function OpenAPISchemaPresentation(props: {
21
+ property: OpenAPISchemaPropertyEntry;
22
+ context: OpenAPIClientContext;
23
+ }): import("react").JSX.Element;
17
24
  /**
18
25
  * Get the alternatives to display for a schema.
19
26
  */
@@ -10,6 +10,17 @@ var __assign = (this && this.__assign) || function () {
10
10
  };
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
+ var __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
13
24
  var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
25
  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
26
  if (ar || !(i in from)) {
@@ -26,6 +37,7 @@ import { OpenAPICopyButton } from './OpenAPICopyButton';
26
37
  import { OpenAPIDisclosure } from './OpenAPIDisclosure';
27
38
  import { OpenAPISchemaName } from './OpenAPISchemaName';
28
39
  import { retrocycle } from './decycle';
40
+ import { getDisclosureLabel } from './getDisclosureLabel';
29
41
  import { stringifyOpenAPI } from './stringifyOpenAPI';
30
42
  import { tString } from './translate';
31
43
  import { checkIsReference, resolveDescription, resolveFirstExample } from './utils';
@@ -33,34 +45,42 @@ import { checkIsReference, resolveDescription, resolveFirstExample } from './uti
33
45
  * Render a property of an OpenAPI schema.
34
46
  */
35
47
  function OpenAPISchemaProperty(props) {
36
- var parentCircularRefs = props.circularRefs, context = props.context, className = props.className, property = props.property;
48
+ var parentCircularRefs = props.circularRefs, context = props.context, className = props.className, property = props.property, rest = __rest(props, ["circularRefs", "context", "className", "property"]);
37
49
  var schema = property.schema;
38
50
  var id = useId();
39
- return (<div id={id} className={clsx('openapi-schema', className)}>
40
- <OpenAPISchemaPresentation context={context} property={property}/>
41
- {(function () {
42
- var circularRefId = parentCircularRefs.get(schema);
43
- // Avoid recursing infinitely, and instead render a link to the parent schema
44
- if (circularRefId) {
45
- return <OpenAPISchemaCircularRef id={circularRefId} schema={schema}/>;
46
- }
47
- var circularRefs = new Map(parentCircularRefs);
48
- circularRefs.set(schema, id);
49
- var properties = getSchemaProperties(schema);
50
- if (properties === null || properties === void 0 ? void 0 : properties.length) {
51
- return (<OpenAPIDisclosure icon={context.icons.plus} label={function (isExpanded) {
52
- return getDisclosureLabel({ schema: schema, isExpanded: isExpanded, context: context });
53
- }}>
54
- <OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>
55
- </OpenAPIDisclosure>);
56
- }
57
- var ancestors = new Set(circularRefs.keys());
58
- var alternatives = getSchemaAlternatives(schema, ancestors);
59
- if (alternatives) {
60
- return alternatives.map(function (schema, index) { return (<OpenAPISchemaAlternative key={index} schema={schema} circularRefs={circularRefs} context={context}/>); });
61
- }
62
- return null;
63
- })()}
51
+ var circularRefId = parentCircularRefs.get(schema);
52
+ // Avoid recursing infinitely, and instead render a link to the parent schema
53
+ if (circularRefId) {
54
+ return <OpenAPISchemaCircularRef id={circularRefId} schema={schema}/>;
55
+ }
56
+ var circularRefs = new Map(parentCircularRefs);
57
+ circularRefs.set(schema, id);
58
+ var properties = getSchemaProperties(schema);
59
+ var ancestors = new Set(circularRefs.keys());
60
+ var alternatives = getSchemaAlternatives(schema, ancestors);
61
+ var header = <OpenAPISchemaPresentation context={context} property={property}/>;
62
+ var content = (function () {
63
+ if (properties === null || properties === void 0 ? void 0 : properties.length) {
64
+ return (<OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>);
65
+ }
66
+ if (alternatives) {
67
+ return (<div className="openapi-schema-alternatives">
68
+ {alternatives.map(function (alternativeSchema, index) { return (<div key={index} className="openapi-schema-alternative">
69
+ <OpenAPISchemaAlternative schema={alternativeSchema} circularRefs={circularRefs} context={context}/>
70
+ {index < alternatives.length - 1 ? (<OpenAPISchemaAlternativeSeparator schema={schema} context={context}/>) : null}
71
+ </div>); })}
72
+ </div>);
73
+ }
74
+ return null;
75
+ })();
76
+ if (properties === null || properties === void 0 ? void 0 : properties.length) {
77
+ return (<OpenAPIDisclosure icon={context.icons.plus} className={clsx('openapi-schema', className)} header={header} label={function (isExpanded) { return getDisclosureLabel({ schema: schema, isExpanded: isExpanded, context: context }); }} {...rest}>
78
+ {content}
79
+ </OpenAPIDisclosure>);
80
+ }
81
+ return (<div id={id} {...rest} className={clsx('openapi-schema', className)}>
82
+ {header}
83
+ {content}
64
84
  </div>);
65
85
  }
66
86
  /**
@@ -70,7 +90,7 @@ function OpenAPISchemaProperties(props) {
70
90
  var id = props.id, properties = props.properties, _a = props.circularRefs, circularRefs = _a === void 0 ? new Map() : _a, context = props.context;
71
91
  return (<div id={id} className="openapi-schema-properties">
72
92
  {properties.map(function (property, index) {
73
- return (<OpenAPISchemaProperty key={index} circularRefs={circularRefs} property={property} context={context}/>);
93
+ return (<OpenAPISchemaProperty key={index} circularRefs={circularRefs} property={property} context={context} style={{ animationDelay: "".concat(index * 0.02, "s") }}/>);
74
94
  })}
75
95
  </div>);
76
96
  }
@@ -105,14 +125,24 @@ export function OpenAPIRootSchemaFromServer(props) {
105
125
  */
106
126
  function OpenAPISchemaAlternative(props) {
107
127
  var schema = props.schema, circularRefs = props.circularRefs, context = props.context;
108
- var description = resolveDescription(schema);
109
128
  var properties = getSchemaProperties(schema);
110
- return (<>
111
- {description ? (<Markdown source={description} className="openapi-schema-description"/>) : null}
112
- <OpenAPIDisclosure icon={context.icons.plus} label={function (isExpanded) { return getDisclosureLabel({ schema: schema, isExpanded: isExpanded, context: context }); }}>
113
- {(properties === null || properties === void 0 ? void 0 : properties.length) ? (<OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>) : (<OpenAPISchemaProperty property={{ schema: schema }} circularRefs={circularRefs} context={context}/>)}
114
- </OpenAPIDisclosure>
115
- </>);
129
+ return (properties === null || properties === void 0 ? void 0 : properties.length) ? (<OpenAPIDisclosure icon={context.icons.plus} header={<OpenAPISchemaPresentation property={{ schema: schema }} context={context}/>} label={function (isExpanded) { return getDisclosureLabel({ schema: schema, isExpanded: isExpanded, context: context }); }}>
130
+ <OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>
131
+ </OpenAPIDisclosure>) : (<OpenAPISchemaProperty property={{ schema: schema }} circularRefs={circularRefs} context={context}/>);
132
+ }
133
+ function OpenAPISchemaAlternativeSeparator(props) {
134
+ var _a, _b, _c;
135
+ var schema = props.schema, context = props.context;
136
+ var anyOf = schema.anyOf || ((_a = schema.items) === null || _a === void 0 ? void 0 : _a.anyOf);
137
+ var oneOf = schema.oneOf || ((_b = schema.items) === null || _b === void 0 ? void 0 : _b.oneOf);
138
+ var allOf = schema.allOf || ((_c = schema.items) === null || _c === void 0 ? void 0 : _c.allOf);
139
+ if (!anyOf && !oneOf && !allOf) {
140
+ return null;
141
+ }
142
+ return (<span className="openapi-schema-alternative-separator">
143
+ {(anyOf || oneOf) && tString(context.translation, 'or')}
144
+ {allOf && tString(context.translation, 'and')}
145
+ </span>);
116
146
  }
117
147
  /**
118
148
  * Render a circular reference to a schema.
@@ -161,7 +191,7 @@ function OpenAPISchemaEnum(props) {
161
191
  return null;
162
192
  }
163
193
  return (<span className="openapi-schema-enum">
164
- Available options:{' '}
194
+ {tString(context.translation, 'possible_values')}:{' '}
165
195
  {enumValues.map(function (item, index) { return (<span key={index} className="openapi-schema-enum-value">
166
196
  <OpenAPICopyButton value={item.value} label={item.description} withTooltip={!!item.description} context={context}>
167
197
  <code>{"".concat(item.value)}</code>
@@ -172,7 +202,7 @@ function OpenAPISchemaEnum(props) {
172
202
  /**
173
203
  * Render the top row of a schema. e.g: name, type, and required status.
174
204
  */
175
- function OpenAPISchemaPresentation(props) {
205
+ export function OpenAPISchemaPresentation(props) {
176
206
  var _a = props.property, schema = _a.schema, propertyName = _a.propertyName, required = _a.required, context = props.context;
177
207
  var description = resolveDescription(schema);
178
208
  var example = resolveFirstExample(schema);
@@ -255,6 +285,11 @@ function getSchemaProperties(schema) {
255
285
  */
256
286
  export function getSchemaAlternatives(schema, ancestors) {
257
287
  if (ancestors === void 0) { ancestors = new Set(); }
288
+ // Search for alternatives in the items property if it exists
289
+ if (schema.items &&
290
+ ('oneOf' in schema.items || 'allOf' in schema.items || 'anyOf' in schema.items)) {
291
+ return getSchemaAlternatives(schema.items, ancestors);
292
+ }
258
293
  var alternatives = (function () {
259
294
  if (schema.anyOf) {
260
295
  return ['anyOf', schema.anyOf];
@@ -332,6 +367,8 @@ function mergeAlternatives(alternativeType, schemasOrRefs) {
332
367
  }
333
368
  }
334
369
  function flattenAlternatives(alternativeType, schemasOrRefs, ancestors) {
370
+ // Get the parent schema's required fields from the most recent ancestor
371
+ var latestAncestor = Array.from(ancestors).pop();
335
372
  return schemasOrRefs.reduce(function (acc, schemaOrRef) {
336
373
  if (checkIsReference(schemaOrRef)) {
337
374
  return acc;
@@ -339,14 +376,28 @@ function flattenAlternatives(alternativeType, schemasOrRefs, ancestors) {
339
376
  if (schemaOrRef[alternativeType] && !ancestors.has(schemaOrRef)) {
340
377
  var schemas = getSchemaAlternatives(schemaOrRef, ancestors);
341
378
  if (schemas) {
342
- acc.push.apply(acc, schemas);
379
+ acc.push.apply(acc, schemas.map(function (schema) { return (__assign(__assign({}, schema), { required: mergeRequiredFields(schema, latestAncestor) })); }));
343
380
  }
344
381
  return acc;
345
382
  }
346
- acc.push(schemaOrRef);
383
+ // For direct schemas, handle required fields
384
+ var schema = __assign(__assign({}, schemaOrRef), { required: mergeRequiredFields(schemaOrRef, latestAncestor) });
385
+ acc.push(schema);
347
386
  return acc;
348
387
  }, []);
349
388
  }
389
+ /**
390
+ * Merge the required fields of a schema with the required fields of its latest ancestor.
391
+ */
392
+ function mergeRequiredFields(schemaOrRef, latestAncestor) {
393
+ if (!schemaOrRef.required && !(latestAncestor === null || latestAncestor === void 0 ? void 0 : latestAncestor.required)) {
394
+ return undefined;
395
+ }
396
+ if (checkIsReference(schemaOrRef)) {
397
+ return latestAncestor === null || latestAncestor === void 0 ? void 0 : latestAncestor.required;
398
+ }
399
+ return Array.from(new Set(__spreadArray(__spreadArray([], ((latestAncestor === null || latestAncestor === void 0 ? void 0 : latestAncestor.required) || []), true), (schemaOrRef.required || []), true)));
400
+ }
350
401
  function getSchemaTitle(schema) {
351
402
  var _a;
352
403
  // Otherwise try to infer a nice title
@@ -366,6 +417,10 @@ function getSchemaTitle(schema) {
366
417
  if (schema.format) {
367
418
  type += " \u00B7 ".concat(schema.format);
368
419
  }
420
+ // Only add the title if it's an object (no need for the title of a string, number, etc.)
421
+ if (type === 'object' && schema.title) {
422
+ type += " \u00B7 ".concat(schema.title.replaceAll(' ', ''));
423
+ }
369
424
  }
370
425
  if ('anyOf' in schema) {
371
426
  type = 'any of';
@@ -381,24 +436,3 @@ function getSchemaTitle(schema) {
381
436
  }
382
437
  return type;
383
438
  }
384
- function getDisclosureLabel(props) {
385
- var _a, _b;
386
- var schema = props.schema, isExpanded = props.isExpanded, context = props.context;
387
- var label;
388
- if (schema.type === 'array' && !!schema.items) {
389
- if (schema.items.oneOf) {
390
- label = tString(context.translation, 'available_items').toLowerCase();
391
- }
392
- // Fallback to "child attributes" for enums and objects
393
- else if (schema.items.enum || schema.items.type === 'object') {
394
- label = tString(context.translation, 'child_attributes').toLowerCase();
395
- }
396
- else {
397
- label = (_b = (_a = schema.items.title) !== null && _a !== void 0 ? _a : schema.title) !== null && _b !== void 0 ? _b : getSchemaTitle(schema.items);
398
- }
399
- }
400
- else {
401
- label = schema.title || tString(context.translation, 'child_attributes').toLowerCase();
402
- }
403
- return "".concat(isExpanded ? tString(context.translation, 'hide') : tString(context.translation, 'show'), " ").concat(label);
404
- }
@@ -4,7 +4,7 @@ import type { OpenAPIClientContext } from './context';
4
4
  interface OpenAPISchemaNameProps {
5
5
  schema?: OpenAPIV3.SchemaObject;
6
6
  propertyName?: string | React.JSX.Element;
7
- required?: boolean;
7
+ required?: boolean | null;
8
8
  type?: string;
9
9
  context: OpenAPIClientContext;
10
10
  }
@@ -20,7 +20,7 @@ export function OpenAPISchemaName(props) {
20
20
  {(schema === null || schema === void 0 ? void 0 : schema.writeOnly) ? (<span className="openapi-schema-writeonly">
21
21
  {t(context.translation, 'write_only')}
22
22
  </span>) : null}
23
- {required ? (<span className="openapi-schema-required">
23
+ {required === null ? null : required ? (<span className="openapi-schema-required">
24
24
  {t(context.translation, 'required')}
25
25
  </span>) : (<span className="openapi-schema-optional">
26
26
  {t(context.translation, 'optional')}
@@ -4,7 +4,7 @@ export function Section(props) {
4
4
  return <div {...props} className={clsx('openapi-section', props.className)}/>;
5
5
  }
6
6
  export function SectionHeader(props) {
7
- return (<div {...props} className={clsx('openapi-section-header', props.className && "".concat(props.className, "-header"))}/>);
7
+ return (<div {...props} className={clsx('openapi-section-header', props.className ? "".concat(props.className, "-header") : undefined)}/>);
8
8
  }
9
9
  export function SectionHeaderContent(props) {
10
10
  return (<div {...props} className={clsx('openapi-section-header-content', props.className && "".concat(props.className, "-header-content"))}/>);
@@ -16,7 +16,7 @@ export var codeSampleGenerators = [
16
16
  {
17
17
  id: 'http',
18
18
  label: 'HTTP',
19
- syntax: 'bash',
19
+ syntax: 'http',
20
20
  generate: function (_a) {
21
21
  var method = _a.method, url = _a.url, _b = _a.headers, headers = _b === void 0 ? {} : _b, body = _a.body;
22
22
  var _c = parseHostAndPath(url), host = _c.host, path = _c.path;
@@ -340,12 +340,15 @@ var BodyGenerators = {
340
340
  return '$$__TRUE__$$';
341
341
  case false:
342
342
  return '$$__FALSE__$$';
343
+ case null:
344
+ return '$$__NULL__$$';
343
345
  default:
344
346
  return value;
345
347
  }
346
348
  })
347
349
  .replaceAll('"$$__TRUE__$$"', 'True')
348
- .replaceAll('"$$__FALSE__$$"', 'False');
350
+ .replaceAll('"$$__FALSE__$$"', 'False')
351
+ .replaceAll('"$$__NULL__$$"', 'None');
349
352
  }
350
353
  return { body: body, code: code, headers: headers };
351
354
  },
@@ -159,6 +159,11 @@ var getExampleFromSchema = function (schema, options, level, parentSchema, name,
159
159
  if (schema.example !== undefined) {
160
160
  return cache(schema, schema.example);
161
161
  }
162
+ // Use a default value, if there’s one and it’s a string or number
163
+ if (schema.default !== undefined &&
164
+ ['string', 'number', 'boolean'].includes(typeof schema.default)) {
165
+ return cache(schema, schema.default);
166
+ }
162
167
  // enum: [ 'available', 'pending', 'sold' ]
163
168
  if (Array.isArray(schema.enum) && schema.enum.length > 0) {
164
169
  return cache(schema, schema.enum[0]);
@@ -0,0 +1,7 @@
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
+ import type { OpenAPIClientContext } from './context';
3
+ export declare function getDisclosureLabel(props: {
4
+ schema: OpenAPIV3.SchemaObject;
5
+ isExpanded: boolean;
6
+ context: OpenAPIClientContext;
7
+ }): string;
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { tString } from './translate';
3
+ export function getDisclosureLabel(props) {
4
+ var schema = props.schema, isExpanded = props.isExpanded, context = props.context;
5
+ var label;
6
+ if (schema.type === 'array' && !!schema.items) {
7
+ if (schema.items.oneOf) {
8
+ label = tString(context.translation, 'available_items').toLowerCase();
9
+ }
10
+ else {
11
+ label = tString(context.translation, 'properties').toLowerCase();
12
+ }
13
+ }
14
+ else {
15
+ label = tString(context.translation, 'properties').toLowerCase();
16
+ }
17
+ return tString(context.translation, isExpanded ? 'hide' : 'show', label);
18
+ }
@@ -0,0 +1,7 @@
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
+ import type { OpenAPIClientContext } from '../context';
3
+ export declare function OpenAPISchemaItem(props: {
4
+ name: string;
5
+ schema: OpenAPIV3.SchemaObject;
6
+ context: OpenAPIClientContext;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { SectionBody } from '../StaticSection';
3
+ import { OpenAPIDisclosure } from '../OpenAPIDisclosure';
4
+ import { OpenAPIRootSchema } from '../OpenAPISchemaServer';
5
+ import { Section } from '../StaticSection';
6
+ import { getDisclosureLabel } from '../getDisclosureLabel';
7
+ export function OpenAPISchemaItem(props) {
8
+ var schema = props.schema, context = props.context, name = props.name;
9
+ return (<OpenAPIDisclosure className="openapi-schemas-disclosure" key={name} icon={context.icons.plus} header={name} label={function (isExpanded) { return getDisclosureLabel({ schema: schema, isExpanded: isExpanded, context: context }); }}>
10
+ <Section className="openapi-section-schemas">
11
+ <SectionBody>
12
+ <OpenAPIRootSchema schema={schema} context={context}/>
13
+ </SectionBody>
14
+ </Section>
15
+ </OpenAPIDisclosure>);
16
+ }
@@ -1,11 +1,11 @@
1
1
  import clsx from 'clsx';
2
- import { OpenAPIDisclosure } from '../OpenAPIDisclosure';
3
2
  import { OpenAPIExample } from '../OpenAPIExample';
4
3
  import { OpenAPIRootSchema } from '../OpenAPISchemaServer';
5
- import { Section, SectionBody, StaticSection } from '../StaticSection';
4
+ import { StaticSection } from '../StaticSection';
6
5
  import { getOpenAPIClientContext, resolveOpenAPIContext, } from '../context';
7
6
  import { t } from '../translate';
8
7
  import { getExampleFromSchema } from '../util/example';
8
+ import { OpenAPISchemaItem } from './OpenAPISchemaItem';
9
9
  /**
10
10
  * OpenAPI Schemas component.
11
11
  */
@@ -53,13 +53,7 @@ export function OpenAPISchemas(props) {
53
53
  return (<div className={clsx('openapi-schemas', className)}>
54
54
  {schemas.map(function (_a) {
55
55
  var name = _a.name, schema = _a.schema;
56
- return (<OpenAPIDisclosure className="openapi-schemas-disclosure" key={name} icon={context.icons.chevronRight} label={name}>
57
- <Section className="openapi-section-schemas">
58
- <SectionBody>
59
- <OpenAPIRootSchema schema={schema} context={clientContext}/>
60
- </SectionBody>
61
- </Section>
62
- </OpenAPIDisclosure>);
56
+ return (<OpenAPISchemaItem key={name} name={name} context={clientContext} schema={schema}/>);
63
57
  })}
64
58
  </div>);
65
59
  }