@gitbook/react-openapi 1.0.5 → 1.1.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 (41) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/OpenAPIDisclosure.d.ts +5 -9
  3. package/dist/OpenAPIDisclosure.jsx +24 -27
  4. package/dist/OpenAPIDisclosureGroup.d.ts +1 -1
  5. package/dist/OpenAPIDisclosureGroup.jsx +5 -5
  6. package/dist/OpenAPIPath.jsx +5 -1
  7. package/dist/OpenAPISchema.d.ts +3 -26
  8. package/dist/OpenAPISchema.jsx +81 -132
  9. package/dist/ScalarApiButton.d.ts +3 -2
  10. package/dist/ScalarApiButton.jsx +22 -18
  11. package/dist/dereference.d.ts +5 -0
  12. package/dist/dereference.js +68 -0
  13. package/dist/index.d.ts +3 -2
  14. package/dist/index.js +2 -1
  15. package/dist/models/OpenAPIModels.d.ts +9 -0
  16. package/dist/models/OpenAPIModels.jsx +62 -0
  17. package/dist/models/index.d.ts +2 -0
  18. package/dist/models/index.js +2 -0
  19. package/dist/models/resolveOpenAPIModels.d.ts +7 -0
  20. package/dist/models/resolveOpenAPIModels.js +73 -0
  21. package/dist/resolveOpenAPIOperation.d.ts +2 -2
  22. package/dist/resolveOpenAPIOperation.js +3 -34
  23. package/dist/tsconfig.build.tsbuildinfo +1 -1
  24. package/dist/types.d.ts +8 -0
  25. package/dist/utils.d.ts +1 -1
  26. package/dist/utils.js +43 -4
  27. package/package.json +3 -3
  28. package/src/OpenAPIDisclosure.tsx +34 -42
  29. package/src/OpenAPIDisclosureGroup.tsx +2 -2
  30. package/src/OpenAPIPath.tsx +7 -1
  31. package/src/OpenAPISchema.test.ts +26 -35
  32. package/src/OpenAPISchema.tsx +137 -226
  33. package/src/ScalarApiButton.tsx +26 -28
  34. package/src/dereference.ts +29 -0
  35. package/src/index.ts +3 -2
  36. package/src/models/OpenAPIModels.tsx +89 -0
  37. package/src/models/index.ts +2 -0
  38. package/src/models/resolveOpenAPIModels.ts +35 -0
  39. package/src/resolveOpenAPIOperation.ts +8 -36
  40. package/src/types.ts +10 -0
  41. package/src/utils.ts +53 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @gitbook/react-openapi
2
2
 
3
+ ## 1.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - f574858: Fix OpenAPI example display error
8
+
9
+ ## 1.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - bb3ca9c: Implement OpenAPI models blocks
14
+
15
+ ### Patch Changes
16
+
17
+ - 0278a14: Upgrade Scalar dependencies
18
+ - 3173d8e: Remove top level circular refs in alternatives
19
+ - Updated dependencies [0278a14]
20
+ - Updated dependencies [bb3ca9c]
21
+ - Updated dependencies [052e07a]
22
+ - @gitbook/openapi-parser@2.1.0
23
+
3
24
  ## 1.0.5
4
25
 
5
26
  ### Patch Changes
@@ -1,13 +1,9 @@
1
- import type React from 'react';
2
1
  import type { OpenAPIClientContext } from './types';
3
- interface Props {
4
- context: OpenAPIClientContext;
5
- children: React.ReactNode;
6
- label?: string;
7
- }
8
2
  /**
9
3
  * Display an interactive OpenAPI disclosure.
10
- * The label is optional and defaults to "child attributes".
11
4
  */
12
- export declare function OpenAPIDisclosure({ context, children, label }: Props): React.JSX.Element;
13
- export {};
5
+ export declare function OpenAPIDisclosure(props: {
6
+ context: OpenAPIClientContext;
7
+ children: React.ReactNode;
8
+ label: string;
9
+ }): React.JSX.Element;
@@ -1,33 +1,30 @@
1
1
  'use client';
2
- import { useRef } from 'react';
3
- import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
4
- import { useDisclosureState } from 'react-stately';
2
+ import { useState } from 'react';
3
+ import { Button, Disclosure, DisclosurePanel, Heading } from 'react-aria-components';
5
4
  /**
6
5
  * Display an interactive OpenAPI disclosure.
7
- * The label is optional and defaults to "child attributes".
8
6
  */
9
- export function OpenAPIDisclosure(_a) {
10
- var context = _a.context, children = _a.children, label = _a.label;
11
- var state = useDisclosureState({});
12
- var panelRef = useRef(null);
13
- var triggerRef = useRef(null);
14
- var _b = useDisclosure({}, state, panelRef), triggerProps = _b.buttonProps, panelProps = _b.panelProps;
15
- var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
16
- var _c = useFocusRing(), isFocusVisible = _c.isFocusVisible, focusProps = _c.focusProps;
17
- return (<div className="openapi-disclosure">
18
- <button ref={triggerRef} {...mergeProps(buttonProps, focusProps)} slot="trigger" className="openapi-disclosure-trigger" style={{
19
- outline: isFocusVisible
20
- ? '2px solid rgb(var(--primary-color-500) / 0.4)'
21
- : 'none',
7
+ export function OpenAPIDisclosure(props) {
8
+ var context = props.context, children = props.children, label = props.label;
9
+ var _a = useState(false), isExpanded = _a[0], setIsExpanded = _a[1];
10
+ return (<Disclosure className="openapi-disclosure" isExpanded={isExpanded} onExpandedChange={setIsExpanded}>
11
+ <Heading>
12
+ <Button slot="trigger" className="openapi-disclosure-trigger" style={function (_a) {
13
+ var isFocusVisible = _a.isFocusVisible;
14
+ return ({
15
+ outline: isFocusVisible
16
+ ? '2px solid rgb(var(--primary-color-500) / 0.4)'
17
+ : 'none',
18
+ });
22
19
  }}>
23
- {context.icons.plus}
24
- <span>
25
- {"".concat(state.isExpanded ? 'Hide' : 'Show', " ").concat(label ? label : 'child attributes')}
26
- </span>
27
- </button>
28
-
29
- {state.isExpanded && (<div ref={panelRef} {...panelProps} className="openapi-disclosure-panel">
30
- {children}
31
- </div>)}
32
- </div>);
20
+ {context.icons.plus}
21
+ <span>
22
+ {isExpanded ? 'Hide' : 'Show'} {label}
23
+ </span>
24
+ </Button>
25
+ </Heading>
26
+ <DisclosurePanel className="openapi-disclosure-panel">
27
+ {isExpanded ? children : null}
28
+ </DisclosurePanel>
29
+ </Disclosure>);
33
30
  }
@@ -8,7 +8,7 @@ type TDisclosureGroup = {
8
8
  label: string | React.ReactNode;
9
9
  tabs?: {
10
10
  id: string;
11
- label: string | React.ReactNode;
11
+ label?: string | React.ReactNode;
12
12
  body?: React.ReactNode;
13
13
  }[];
14
14
  };
@@ -25,7 +25,7 @@ export function OpenAPIDisclosureGroup(props) {
25
25
  </DisclosureGroupStateContext.Provider>);
26
26
  }
27
27
  function DisclosureItem(props) {
28
- var _a, _b, _c, _d, _e;
28
+ var _a, _b, _c, _d, _e, _f;
29
29
  var icon = props.icon, group = props.group;
30
30
  var defaultId = useId();
31
31
  var id = group.id || defaultId;
@@ -42,11 +42,11 @@ function DisclosureItem(props) {
42
42
  var panelRef = useRef(null);
43
43
  var triggerRef = useRef(null);
44
44
  var isDisabled = (groupState === null || groupState === void 0 ? void 0 : groupState.isDisabled) || !((_a = group.tabs) === null || _a === void 0 ? void 0 : _a.length) || false;
45
- var _f = useDisclosure(__assign(__assign({}, props), { isExpanded: isExpanded, isDisabled: isDisabled }), state, panelRef), triggerProps = _f.buttonProps, panelProps = _f.panelProps;
45
+ var _g = useDisclosure(__assign(__assign({}, props), { isExpanded: isExpanded, isDisabled: isDisabled }), state, panelRef), triggerProps = _g.buttonProps, panelProps = _g.panelProps;
46
46
  var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
47
- var _g = useFocusRing(), isFocusVisible = _g.isFocusVisible, focusProps = _g.focusProps;
47
+ var _h = useFocusRing(), isFocusVisible = _h.isFocusVisible, focusProps = _h.focusProps;
48
48
  var defaultTab = ((_c = (_b = group.tabs) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.id) || '';
49
- var _h = useState(defaultTab), selectedTabKey = _h[0], setSelectedTabKey = _h[1];
49
+ var _j = useState(defaultTab), selectedTabKey = _j[0], setSelectedTabKey = _j[1];
50
50
  var selectedTab = (_d = group.tabs) === null || _d === void 0 ? void 0 : _d.find(function (tab) { return tab.id === selectedTabKey; });
51
51
  return (<div className="openapi-disclosure-group" aria-expanded={state.isExpanded}>
52
52
  <div className="openapi-disclosure-group-header">
@@ -71,7 +71,7 @@ function DisclosureItem(props) {
71
71
  {group.tabs.map(function (tab) { return (<option key={tab.id} value={tab.id}>
72
72
  {tab.label}
73
73
  </option>); })}
74
- </select>) : group.tabs[0] ? (<span>{group.tabs[0].label}</span>) : null}
74
+ </select>) : ((_f = group.tabs[0]) === null || _f === void 0 ? void 0 : _f.label) ? (<span>{group.tabs[0].label}</span>) : null}
75
75
  </div>) : null}
76
76
  </div>
77
77
 
@@ -6,14 +6,18 @@ export function OpenAPIPath(props) {
6
6
  var data = props.data, context = props.context;
7
7
  var method = data.method, path = data.path;
8
8
  var specUrl = context.specUrl;
9
+ var hideTryItPanel = data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'];
9
10
  return (<div className="openapi-path">
10
11
  <div className={"openapi-method openapi-method-".concat(method)}>{method}</div>
11
12
  <div className="openapi-path-title" data-deprecated={data.operation.deprecated}>
12
13
  <p>{formatPath(path)}</p>
13
14
  </div>
14
- {data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'] ? null : (<ScalarApiButton method={method} path={path} specUrl={specUrl}/>)}
15
+ {!hideTryItPanel && validateHttpMethod(method) && (<ScalarApiButton method={method} path={path} specUrl={specUrl}/>)}
15
16
  </div>);
16
17
  }
18
+ function validateHttpMethod(method) {
19
+ return ['get', 'post', 'put', 'delete', 'patch', 'head', 'options', 'trace'].includes(method);
20
+ }
17
21
  // Format the path to highlight placeholders
18
22
  function formatPath(path) {
19
23
  // Matches placeholders like {id}, {userId}, etc.
@@ -1,20 +1,11 @@
1
1
  import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
2
  import type { OpenAPIClientContext } from './types';
3
3
  type CircularRefsIds = Map<OpenAPIV3.SchemaObject, string>;
4
- export interface OpenAPISchemaPropertyEntry {
4
+ interface OpenAPISchemaPropertyEntry {
5
5
  propertyName?: string | undefined;
6
6
  required?: boolean | undefined;
7
7
  schema: OpenAPIV3.SchemaObject;
8
8
  }
9
- /**
10
- * Render a property of an OpenAPI schema.
11
- */
12
- export declare function OpenAPISchemaProperty(props: OpenAPISchemaPropertyEntry & {
13
- /** Set of objects already observed as parents */
14
- circularRefs?: CircularRefsIds;
15
- context: OpenAPIClientContext;
16
- className?: string;
17
- }): import("react").JSX.Element;
18
9
  /**
19
10
  * Render a set of properties of an OpenAPI schema.
20
11
  */
@@ -23,7 +14,7 @@ export declare function OpenAPISchemaProperties(props: {
23
14
  properties: OpenAPISchemaPropertyEntry[];
24
15
  circularRefs?: CircularRefsIds;
25
16
  context: OpenAPIClientContext;
26
- }): import("react").JSX.Element | null;
17
+ }): import("react").JSX.Element;
27
18
  /**
28
19
  * Render a root schema (such as the request body or response body).
29
20
  */
@@ -31,22 +22,8 @@ export declare function OpenAPIRootSchema(props: {
31
22
  schema: OpenAPIV3.SchemaObject;
32
23
  context: OpenAPIClientContext;
33
24
  }): import("react").JSX.Element;
34
- /**
35
- * Render the enum value for a schema.
36
- */
37
- export declare function OpenAPISchemaEnum(props: {
38
- enumValues: any[];
39
- }): import("react").JSX.Element;
40
- export declare function OpenAPISchemaPresentation(props: OpenAPISchemaPropertyEntry): import("react").JSX.Element;
41
- type OpenAPISchemaAlternatives = [
42
- OpenAPIV3.SchemaObject[],
43
- OpenAPIV3.DiscriminatorObject | undefined
44
- ];
45
25
  /**
46
26
  * Get the alternatives to display for a schema.
47
27
  */
48
- export declare function getSchemaAlternatives(schema: OpenAPIV3.SchemaObject, ancestors?: Set<OpenAPIV3.SchemaObject>): null | OpenAPISchemaAlternatives;
49
- export declare function getSchemaTitle(schema: OpenAPIV3.SchemaObject,
50
- /** If the title is inferred in a oneOf with discriminator, we can use it to optimize the title */
51
- discriminator?: OpenAPIV3.DiscriminatorObject): string;
28
+ export declare function getSchemaAlternatives(schema: OpenAPIV3.SchemaObject, ancestors?: Set<OpenAPIV3.SchemaObject>): OpenAPIV3.SchemaObject[] | null;
52
29
  export {};
@@ -1,57 +1,43 @@
1
- import clsx from 'clsx';
2
1
  import { useId } from 'react';
3
- import { InteractiveSection } from './InteractiveSection';
2
+ import clsx from 'clsx';
4
3
  import { Markdown } from './Markdown';
5
4
  import { OpenAPIDisclosure } from './OpenAPIDisclosure';
6
5
  import { OpenAPISchemaName } from './OpenAPISchemaName';
7
- import { stringifyOpenAPI } from './stringifyOpenAPI';
8
- import { checkIsReference, resolveDescription } from './utils';
6
+ import { checkIsReference, resolveDescription, resolveFirstExample } from './utils';
9
7
  /**
10
8
  * Render a property of an OpenAPI schema.
11
9
  */
12
- export function OpenAPISchemaProperty(props) {
13
- var _a;
14
- var schema = props.schema, _b = props.circularRefs, parentCircularRefs = _b === void 0 ? new Map() : _b, context = props.context, className = props.className;
10
+ function OpenAPISchemaProperty(props) {
11
+ var property = props.property, _a = props.circularRefs, parentCircularRefs = _a === void 0 ? new Map() : _a, context = props.context, className = props.className;
12
+ var schema = property.schema;
15
13
  var id = useId();
16
- var parentCircularRef = parentCircularRefs.get(schema);
17
- var circularRefs = new Map(parentCircularRefs).set(schema, id);
18
- // Avoid recursing infinitely, and instead render a link to the parent schema
19
- var properties = parentCircularRef ? null : getSchemaProperties(schema);
20
- var alternatives = parentCircularRef
21
- ? null
22
- : getSchemaAlternatives(schema, new Set(circularRefs.keys()));
23
- if ((_a = alternatives === null || alternatives === void 0 ? void 0 : alternatives[0]) === null || _a === void 0 ? void 0 : _a.length) {
24
- return (<OpenAPISchemaAlternativesItem {...props} circularRefs={circularRefs} context={context} alternatives={alternatives} parentCircularRef={parentCircularRef}/>);
25
- }
26
- if ((properties && properties.length > 0) || schema.type === 'object') {
27
- return (<InteractiveSection id={id} className={clsx('openapi-schema', className)}>
28
- <OpenAPISchemaPresentation {...props}/>
29
- {properties && properties.length > 0 ? (<OpenAPIDisclosure context={context} label={getDisclosureLabel(schema)}>
30
- <OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>
31
- </OpenAPIDisclosure>) : null}
32
- {parentCircularRef ? (<OpenAPISchemaCircularRef id={parentCircularRef} schema={schema}/>) : null}
33
- </InteractiveSection>);
34
- }
35
- return (<InteractiveSection id={id} className={clsx('openapi-schema', className)}>
36
- <OpenAPISchemaPresentation {...props}/>
37
- {(properties && properties.length > 0) ||
38
- (schema.enum && schema.enum.length > 0) ||
39
- parentCircularRef ? (<>
40
- {(properties === null || properties === void 0 ? void 0 : properties.length) ? (<OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>) : null}
41
- {parentCircularRef ? (<OpenAPISchemaCircularRef id={parentCircularRef} schema={schema}/>) : null}
42
- </>) : null}
43
- </InteractiveSection>);
14
+ return (<div id={id} className={clsx('openapi-schema', className)}>
15
+ <OpenAPISchemaPresentation property={property}/>
16
+ {(function () {
17
+ var parentCircularRef = parentCircularRefs.get(schema);
18
+ // Avoid recursing infinitely, and instead render a link to the parent schema
19
+ if (parentCircularRef) {
20
+ return <OpenAPISchemaCircularRef id={parentCircularRef} schema={schema}/>;
21
+ }
22
+ var circularRefs = parentCircularRefs.set(schema, id);
23
+ var properties = getSchemaProperties(schema);
24
+ var alternatives = getSchemaAlternatives(schema, new Set(circularRefs.keys()));
25
+ return (<>
26
+ {alternatives === null || alternatives === void 0 ? void 0 : alternatives.map(function (schema, index) { return (<OpenAPISchemaAlternative key={index} schema={schema} circularRefs={circularRefs} context={context}/>); })}
27
+ {(properties === null || properties === void 0 ? void 0 : properties.length) ? (<OpenAPIDisclosure context={context} label={getDisclosureLabel(schema)}>
28
+ <OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>
29
+ </OpenAPIDisclosure>) : null}
30
+ </>);
31
+ })()}
32
+ </div>);
44
33
  }
45
34
  /**
46
35
  * Render a set of properties of an OpenAPI schema.
47
36
  */
48
37
  export function OpenAPISchemaProperties(props) {
49
38
  var id = props.id, properties = props.properties, circularRefs = props.circularRefs, context = props.context;
50
- if (!properties.length) {
51
- return null;
52
- }
53
39
  return (<div id={id} className="openapi-schema-properties">
54
- {properties.map(function (property, index) { return (<OpenAPISchemaProperty key={index} circularRefs={circularRefs} {...property} context={context}/>); })}
40
+ {properties.map(function (property, index) { return (<OpenAPISchemaProperty key={index} circularRefs={circularRefs} property={property} context={context}/>); })}
55
41
  </div>);
56
42
  }
57
43
  /**
@@ -59,12 +45,11 @@ export function OpenAPISchemaProperties(props) {
59
45
  */
60
46
  export function OpenAPIRootSchema(props) {
61
47
  var schema = props.schema, context = props.context;
62
- // Avoid recursing infinitely, and instead render a link to the parent schema
63
48
  var properties = getSchemaProperties(schema);
64
- if (properties && properties.length > 0) {
49
+ if (properties === null || properties === void 0 ? void 0 : properties.length) {
65
50
  return <OpenAPISchemaProperties properties={properties} context={context}/>;
66
51
  }
67
- return (<OpenAPISchemaProperty schema={schema} context={context} className="openapi-schema-root"/>);
52
+ return (<OpenAPISchemaProperty className="openapi-schema-root" property={{ schema: schema }} context={context}/>);
68
53
  }
69
54
  /**
70
55
  * Render a tab for an alternative schema.
@@ -72,36 +57,16 @@ export function OpenAPIRootSchema(props) {
72
57
  * for primitives, it renders the schema itself.
73
58
  */
74
59
  function OpenAPISchemaAlternative(props) {
75
- var _a;
76
60
  var schema = props.schema, circularRefs = props.circularRefs, context = props.context;
77
- var id = useId();
78
- var subProperties = getSchemaProperties(schema);
79
61
  var description = resolveDescription(schema);
80
- var alternatives = getSchemaAlternatives(schema, new Set(circularRefs === null || circularRefs === void 0 ? void 0 : circularRefs.keys()));
81
- if (((_a = alternatives === null || alternatives === void 0 ? void 0 : alternatives[0]) === null || _a === void 0 ? void 0 : _a.length) && !(subProperties === null || subProperties === void 0 ? void 0 : subProperties.length)) {
82
- return (<>
83
- {description ? (<Markdown source={description} className="openapi-schema-description"/>) : null}
84
- <OpenAPIDisclosure context={context} label={getDisclosureLabel(schema)}>
85
- <OpenAPISchemaAlternativesItem schema={schema} circularRefs={circularRefs} context={context} alternatives={alternatives}/>
86
- </OpenAPIDisclosure>
87
- </>);
88
- }
62
+ var properties = getSchemaProperties(schema);
89
63
  return (<>
90
64
  {description ? (<Markdown source={description} className="openapi-schema-description"/>) : null}
91
65
  <OpenAPIDisclosure context={context} label={getDisclosureLabel(schema)}>
92
- <OpenAPISchemaProperties id={id} properties={subProperties !== null && subProperties !== void 0 ? subProperties : [{ schema: schema }]} circularRefs={subProperties ? new Map(circularRefs).set(schema, id) : circularRefs} context={context}/>
66
+ {(properties === null || properties === void 0 ? void 0 : properties.length) ? (<OpenAPISchemaProperties properties={properties} circularRefs={circularRefs} context={context}/>) : (<OpenAPISchemaProperty property={{ schema: schema }} circularRefs={circularRefs} context={context}/>)}
93
67
  </OpenAPIDisclosure>
94
68
  </>);
95
69
  }
96
- function OpenAPISchemaAlternativesItem(props) {
97
- var id = useId();
98
- var schema = props.schema, circularRefs = props.circularRefs, context = props.context, alternatives = props.alternatives, parentCircularRef = props.parentCircularRef;
99
- return (<InteractiveSection id={id} className={clsx('openapi-schema')}>
100
- <OpenAPISchemaPresentation {...props}/>
101
- {alternatives[0].map(function (alternative, index) { return (<OpenAPISchemaAlternative key={"alternative-".concat(index)} schema={alternative} circularRefs={circularRefs} context={context}/>); })}
102
- {parentCircularRef ? (<OpenAPISchemaCircularRef id={parentCircularRef} schema={schema}/>) : null}
103
- </InteractiveSection>);
104
- }
105
70
  /**
106
71
  * Render a circular reference to a schema.
107
72
  */
@@ -115,7 +80,7 @@ function OpenAPISchemaCircularRef(props) {
115
80
  /**
116
81
  * Render the enum value for a schema.
117
82
  */
118
- export function OpenAPISchemaEnum(props) {
83
+ function OpenAPISchemaEnum(props) {
119
84
  var enumValues = props.enumValues;
120
85
  return (<div className="openapi-schema-enum">
121
86
  <span>
@@ -127,29 +92,24 @@ export function OpenAPISchemaEnum(props) {
127
92
  </span>
128
93
  </div>);
129
94
  }
130
- export function OpenAPISchemaPresentation(props) {
131
- var schema = props.schema, propertyName = props.propertyName, required = props.required;
132
- var shouldDisplayExample = function (schema) {
133
- return ((typeof schema.example === 'string' && !!schema.example) ||
134
- typeof schema.example === 'number' ||
135
- typeof schema.example === 'boolean' ||
136
- (Array.isArray(schema.example) && schema.example.length > 0) ||
137
- (typeof schema.example === 'object' &&
138
- schema.example !== null &&
139
- Object.keys(schema.example).length > 0));
140
- };
95
+ /**
96
+ * Render the top row of a schema. e.g: name, type, and required status.
97
+ */
98
+ function OpenAPISchemaPresentation(props) {
99
+ var _a = props.property, schema = _a.schema, propertyName = _a.propertyName, required = _a.required;
141
100
  var description = resolveDescription(schema);
101
+ var example = resolveFirstExample(schema);
142
102
  return (<div className="openapi-schema-presentation">
143
103
  <OpenAPISchemaName schema={schema} type={getSchemaTitle(schema)} propertyName={propertyName} required={required}/>
144
- {schema['x-deprecated-sunset'] ? (<div className="openapi-deprecated-sunset openapi-schema-description openapi-markdown">
104
+ {typeof schema['x-deprecated-sunset'] === 'string' ? (<div className="openapi-deprecated-sunset openapi-schema-description openapi-markdown">
145
105
  Sunset date:{' '}
146
106
  <span className="openapi-deprecated-sunset-date">
147
107
  {schema['x-deprecated-sunset']}
148
108
  </span>
149
109
  </div>) : null}
150
110
  {description ? (<Markdown source={description} className="openapi-schema-description"/>) : null}
151
- {shouldDisplayExample(schema) ? (<div className="openapi-schema-example">
152
- Example: <code>{formatExample(schema.example)}</code>
111
+ {typeof example === 'string' ? (<div className="openapi-schema-example">
112
+ Example: <code>{example}</code>
153
113
  </div>) : null}
154
114
  {schema.pattern ? (<div className="openapi-schema-pattern">
155
115
  Pattern: <code>{schema.pattern}</code>
@@ -162,28 +122,30 @@ export function OpenAPISchemaPresentation(props) {
162
122
  */
163
123
  function getSchemaProperties(schema) {
164
124
  // check array AND schema.items as this is sometimes null despite what the type indicates
165
- if (schema.type === 'array' && !!schema.items) {
125
+ if (schema.type === 'array' && schema.items && !checkIsReference(schema.items)) {
166
126
  var items = schema.items;
167
127
  var itemProperties = getSchemaProperties(items);
168
128
  if (itemProperties) {
169
129
  return itemProperties;
170
130
  }
171
131
  // If the items are a primitive type, we don't need to display them
172
- if (['string', 'number', 'boolean', 'integer'].includes(items.type) && !items.enum) {
132
+ if ((items.type === 'string' ||
133
+ items.type === 'number' ||
134
+ items.type === 'boolean' ||
135
+ items.type === 'integer') &&
136
+ !items.enum) {
173
137
  return null;
174
138
  }
175
- return [
176
- {
177
- propertyName: 'items',
178
- schema: items,
179
- },
180
- ];
139
+ return [{ propertyName: 'items', schema: items }];
181
140
  }
182
141
  if (schema.type === 'object' || schema.properties) {
183
142
  var result_1 = [];
184
143
  if (schema.properties) {
185
144
  Object.entries(schema.properties).forEach(function (_a) {
186
145
  var propertyName = _a[0], propertySchema = _a[1];
146
+ if (checkIsReference(propertySchema)) {
147
+ return;
148
+ }
187
149
  result_1.push({
188
150
  propertyName: propertyName,
189
151
  required: Array.isArray(schema.required)
@@ -193,11 +155,10 @@ function getSchemaProperties(schema) {
193
155
  });
194
156
  });
195
157
  }
196
- if (schema.additionalProperties) {
197
- var additionalProperties = schema.additionalProperties;
158
+ if (schema.additionalProperties && !checkIsReference(schema.additionalProperties)) {
198
159
  result_1.push({
199
160
  propertyName: 'Other properties',
200
- schema: additionalProperties === true ? {} : additionalProperties,
161
+ schema: schema.additionalProperties === true ? {} : schema.additionalProperties,
201
162
  });
202
163
  }
203
164
  return result_1;
@@ -209,43 +170,42 @@ function getSchemaProperties(schema) {
209
170
  */
210
171
  export function getSchemaAlternatives(schema, ancestors) {
211
172
  if (ancestors === void 0) { ancestors = new Set(); }
212
- var downAncestors = new Set(ancestors).add(schema);
213
- if (schema.anyOf) {
214
- return [flattenAlternatives('anyOf', schema.anyOf, downAncestors), schema.discriminator];
215
- }
216
- if (schema.oneOf) {
217
- return [flattenAlternatives('oneOf', schema.oneOf, downAncestors), schema.discriminator];
218
- }
219
- if (schema.allOf) {
220
- return [flattenAlternatives('allOf', schema.allOf, downAncestors), schema.discriminator];
173
+ var alternatives = (function () {
174
+ if (schema.anyOf) {
175
+ return ['anyOf', schema.anyOf];
176
+ }
177
+ if (schema.oneOf) {
178
+ return ['oneOf', schema.oneOf];
179
+ }
180
+ if (schema.allOf) {
181
+ return ['allOf', schema.allOf];
182
+ }
183
+ return null;
184
+ })();
185
+ if (!alternatives) {
186
+ return null;
221
187
  }
222
- return null;
188
+ var type = alternatives[0], schemas = alternatives[1];
189
+ return flattenAlternatives(type, schemas, new Set(ancestors).add(schema));
223
190
  }
224
- function flattenAlternatives(alternativeType, alternatives, ancestors) {
225
- return alternatives.reduce(function (acc, alternative) {
226
- var _a;
227
- if (!!alternative[alternativeType] && !ancestors.has(alternative)) {
228
- acc.push.apply(acc, (((_a = getSchemaAlternatives(alternative, ancestors)) === null || _a === void 0 ? void 0 : _a[0]) || []));
191
+ function flattenAlternatives(alternativeType, schemasOrRefs, ancestors) {
192
+ return schemasOrRefs.reduce(function (acc, schemaOrRef) {
193
+ if (checkIsReference(schemaOrRef)) {
194
+ return acc;
229
195
  }
230
- else {
231
- acc.push(alternative);
196
+ if (schemaOrRef[alternativeType] && !ancestors.has(schemaOrRef)) {
197
+ var schemas = getSchemaAlternatives(schemaOrRef, ancestors);
198
+ if (schemas) {
199
+ acc.push.apply(acc, schemas);
200
+ }
201
+ return acc;
232
202
  }
203
+ acc.push(schemaOrRef);
233
204
  return acc;
234
205
  }, []);
235
206
  }
236
- export function getSchemaTitle(schema,
237
- /** If the title is inferred in a oneOf with discriminator, we can use it to optimize the title */
238
- discriminator) {
207
+ function getSchemaTitle(schema) {
239
208
  var _a;
240
- // Try using the discriminator
241
- if ((discriminator === null || discriminator === void 0 ? void 0 : discriminator.propertyName) && schema.properties) {
242
- var discriminatorProperty = schema.properties[discriminator.propertyName];
243
- if (discriminatorProperty && !checkIsReference(discriminatorProperty)) {
244
- if (discriminatorProperty.enum) {
245
- return discriminatorProperty.enum.map(function (value) { return value.toString(); }).join(' | ');
246
- }
247
- }
248
- }
249
209
  // Otherwise try to infer a nice title
250
210
  var type = 'any';
251
211
  if (schema.enum) {
@@ -286,20 +246,9 @@ function getDisclosureLabel(schema) {
286
246
  }
287
247
  // Fallback to "child attributes" for enums and objects
288
248
  if (schema.items.enum || schema.items.type === 'object') {
289
- return;
249
+ return 'child attributes';
290
250
  }
291
251
  return (_b = (_a = schema.items.title) !== null && _a !== void 0 ? _a : schema.title) !== null && _b !== void 0 ? _b : getSchemaTitle(schema.items);
292
252
  }
293
- return schema.title;
294
- }
295
- function formatExample(example) {
296
- if (typeof example === 'string') {
297
- return example
298
- .replace(/\n/g, ' ') // Replace newlines with spaces
299
- .replace(/\s+/g, ' ') // Collapse multiple spaces/newlines into a single space
300
- .replace(/([\{\}:,])\s+/g, '$1 ') // Ensure a space after {, }, :, and ,
301
- .replace(/\s+([\{\}:,])/g, ' $1') // Ensure a space before {, }, :, and ,
302
- .trim();
303
- }
304
- return stringifyOpenAPI(example);
253
+ return schema.title || 'child attributes';
305
254
  }
@@ -1,8 +1,9 @@
1
+ import type { OpenAPIV3_1 } from '@gitbook/openapi-parser';
1
2
  /**
2
3
  * Button which launches the Scalar API Client
3
4
  */
4
- export declare function ScalarApiButton({ method, path, specUrl, }: {
5
- method: string;
5
+ export declare function ScalarApiButton(props: {
6
+ method: OpenAPIV3_1.HttpMethods;
6
7
  path: string;
7
8
  specUrl: string;
8
9
  }): import("react").JSX.Element;
@@ -1,15 +1,14 @@
1
1
  'use client';
2
2
  import { ApiClientModalProvider, useApiClientModal } from '@scalar/api-client-react';
3
- import { useEffect, useImperativeHandle, useRef, useState } from 'react';
3
+ import { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
4
4
  import { createPortal } from 'react-dom';
5
- import { useEventCallback } from 'usehooks-ts';
6
5
  import { useOpenAPIOperationContext } from './OpenAPIOperationContext';
7
6
  /**
8
7
  * Button which launches the Scalar API Client
9
8
  */
10
- export function ScalarApiButton(_a) {
11
- var method = _a.method, path = _a.path, specUrl = _a.specUrl;
12
- var _b = useState(false), isOpen = _b[0], setIsOpen = _b[1];
9
+ export function ScalarApiButton(props) {
10
+ var method = props.method, path = props.path, specUrl = props.specUrl;
11
+ var _a = useState(false), isOpen = _a[0], setIsOpen = _a[1];
13
12
  var controllerRef = useRef(null);
14
13
  return (<div className="scalar scalar-activate">
15
14
  <button className="scalar-activate-button button" onClick={function () {
@@ -28,24 +27,29 @@ export function ScalarApiButton(_a) {
28
27
  </div>);
29
28
  }
30
29
  function ScalarModal(props) {
31
- return (<ApiClientModalProvider configuration={{ spec: { url: props.specUrl } }} initialRequest={{ path: props.path, method: props.method }}>
32
- <ScalarModalController method={props.method} path={props.path} controllerRef={props.controllerRef}/>
30
+ var method = props.method, path = props.path, specUrl = props.specUrl, controllerRef = props.controllerRef;
31
+ return (<ApiClientModalProvider configuration={{ spec: { url: specUrl } }} initialRequest={{ method: method, path: path }}>
32
+ <ScalarModalController method={method} path={path} controllerRef={controllerRef}/>
33
33
  </ApiClientModalProvider>);
34
34
  }
35
35
  function ScalarModalController(props) {
36
+ var method = props.method, path = props.path, controllerRef = props.controllerRef;
36
37
  var client = useApiClientModal();
37
- var openClient = client === null || client === void 0 ? void 0 : client.open;
38
- useImperativeHandle(props.controllerRef, function () { return ({ openClient: openClient ? function () { return openClient(); } : undefined }); }, [openClient]);
39
- // Open the client when the component is mounted.
40
- var onOpenClient = useOpenAPIOperationContext().onOpenClient;
41
- var trackOpening = useEventCallback(function () {
42
- onOpenClient({ method: props.method, path: props.path });
43
- });
44
- useEffect(function () {
45
- if (openClient) {
46
- openClient();
47
- trackOpening();
38
+ var openScalarClient = client === null || client === void 0 ? void 0 : client.open;
39
+ var trackClientOpening = useOpenAPIOperationContext().onOpenClient;
40
+ var openClient = useMemo(function () {
41
+ if (openScalarClient) {
42
+ return function () {
43
+ openScalarClient({ method: method, path: path, _source: 'gitbook' });
44
+ trackClientOpening({ method: method, path: path });
45
+ };
48
46
  }
47
+ return null;
48
+ }, [openScalarClient, method, path, trackClientOpening]);
49
+ useImperativeHandle(controllerRef, function () { return ({ openClient: openClient ? function () { return openClient(); } : undefined }); }, [openClient]);
50
+ // Open at mount
51
+ useEffect(function () {
52
+ openClient === null || openClient === void 0 ? void 0 : openClient();
49
53
  }, [openClient]);
50
54
  return null;
51
55
  }
@@ -0,0 +1,5 @@
1
+ import { type Filesystem, type OpenAPIV3xDocument } from '@gitbook/openapi-parser';
2
+ /**
3
+ * Memoized version of `dereferenceSchema`.
4
+ */
5
+ export declare function dereferenceFilesystem(filesystem: Filesystem): Promise<OpenAPIV3xDocument>;