@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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # @gitbook/react-openapi
2
2
 
3
+ ## 1.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - f8d4c76: Sync tabs across all OpenAPI blocks
8
+ - dddb4ec: Fix long tab group description
9
+ - f8d4c76: Support for OpenAPI references
10
+
11
+ ## 1.0.0
12
+
13
+ ### Major Changes
14
+
15
+ - 727bde2: Improve and split OpenAPI parser into its own package
16
+ - 12c7862: Use `@scalar/openapi-parser` to be more resilient and perf on OpenAPI spec parsing:
17
+
18
+ - `fetcher.fetch` must now returns a valid OpenAPI document
19
+ - `parseOpenAPIV3` has been replaced by `parseOpenAPI`
20
+
21
+ ### Minor Changes
22
+
23
+ - 162b4b7: Add in HTTP example code blocks
24
+ - e4e2f52: Add an optional client context to get a callback called when the Scalar client is opened for a block.
25
+ - eb7c22f: Revert scalar to 1.0.87 to mitigate an issue with ApiClientModalProvider
26
+ - 160fca1: new OpenAPI blocks design
27
+ - e721f17: Use `@scalar/oas-utils` getExampleFromSchema to generate OpenAPI examples
28
+ - fe8acc9: Fix an issue where a missing OpenAPI example would crash the page.
29
+ - 1823101: Fix internal properties appearing in OpenAPI docs.
30
+
31
+ ### Patch Changes
32
+
33
+ - d9029c7: Support apiKey in CodeSample security headers
34
+ - 6e54a06: Support response examples
35
+ - 0c03676: Better securities sample and headers
36
+ - 3e5e458: Handle isArray schema type
37
+ - 46edde9: Improve the OpenAPI package API
38
+ - d9c8d57: Do not dereference before caching OpenAPI spec.
39
+ - ccf2cff: Fix an issue where a response object using a special ref would crash the page.
40
+ - dda0cc6: Flatten OpenAPI security object
41
+ - f92e906: Prevent codemirror from loading multiple versions in scalar
42
+ - dff08ae: Improve performances by loading Scalar API Client only when the button is clicked
43
+ - fc7b16f: Updated scalar depdenency
44
+ - a652958: Fix error on unresolvable refs by replacing with property name and any type
45
+ - 2f73db7: Support non primitive examples in OpenAPI block
46
+ - 160fca1: Support deprecated and x-deprecated-sunset in OpenAPI spec
47
+ - b41d425: Improve OpenAPI rendering performances by caching markdown parsing
48
+ - Updated dependencies [46edde9]
49
+ - Updated dependencies [727bde2]
50
+ - @gitbook/openapi-parser@1.0.0
51
+
3
52
  ## 0.7.1
4
53
 
5
54
  ### Patch Changes
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  interface InteractiveSectionTab {
3
2
  key: string;
4
3
  label: string;
@@ -16,20 +15,17 @@ export declare function InteractiveSection(props: {
16
15
  toggeable?: boolean;
17
16
  /** Default state of the toggle */
18
17
  defaultOpened?: boolean;
19
- /** Icons to display for the toggle */
20
- toggleOpenIcon?: React.ReactNode;
21
- toggleCloseIcon?: React.ReactNode;
18
+ /** Icon to display for the toggle */
19
+ toggleIcon?: React.ReactNode;
22
20
  /** Tabs of content to display */
23
21
  tabs?: Array<InteractiveSectionTab>;
24
22
  /** Default tab to have opened */
25
23
  defaultTab?: string;
26
24
  /** Content of the header */
27
- header: React.ReactNode;
25
+ header?: React.ReactNode;
28
26
  /** Body of the section */
29
27
  children?: React.ReactNode;
30
28
  /** Children to display within the container */
31
29
  overlay?: React.ReactNode;
32
- /** An optional key referencing a value in global state */
33
- stateKey?: string;
34
- }): React.JSX.Element;
30
+ }): import("react").JSX.Element;
35
31
  export {};
@@ -0,0 +1,60 @@
1
+ 'use client';
2
+ import clsx from 'clsx';
3
+ import { useRef, useState } from 'react';
4
+ import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
5
+ import { useDisclosureState } from 'react-stately';
6
+ /**
7
+ * To optimize rendering, most of the components are server-components,
8
+ * and the interactiveness is mainly handled by a few key components like this one.
9
+ */
10
+ export function InteractiveSection(props) {
11
+ var _a, _b, _c;
12
+ var id = props.id, className = props.className, _d = props.toggeable, toggeable = _d === void 0 ? false : _d, _e = props.defaultOpened, defaultOpened = _e === void 0 ? true : _e, _f = props.tabs, tabs = _f === void 0 ? [] : _f, _g = props.defaultTab, defaultTab = _g === void 0 ? (_a = tabs[0]) === null || _a === void 0 ? void 0 : _a.key : _g, header = props.header, children = props.children, overlay = props.overlay, _h = props.toggleIcon, toggleIcon = _h === void 0 ? '▶' : _h;
13
+ var _j = useState(defaultTab), selectedTabKey = _j[0], setSelectedTab = _j[1];
14
+ var selectedTab = (_b = tabs.find(function (tab) { return tab.key === selectedTabKey; })) !== null && _b !== void 0 ? _b : tabs[0];
15
+ var state = useDisclosureState({
16
+ defaultExpanded: defaultOpened,
17
+ });
18
+ var panelRef = useRef(null);
19
+ var triggerRef = useRef(null);
20
+ var _k = useDisclosure({}, state, panelRef), triggerProps = _k.buttonProps, panelProps = _k.panelProps;
21
+ var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
22
+ var _l = useFocusRing(), isFocusVisible = _l.isFocusVisible, focusProps = _l.focusProps;
23
+ return (<div id={id} className={clsx('openapi-section', toggeable ? 'openapi-section-toggeable' : null, className, toggeable ? "".concat(className, "-").concat(state.isExpanded ? 'opened' : 'closed') : null)}>
24
+ {header ? (<div onClick={function () {
25
+ if (toggeable) {
26
+ state.toggle();
27
+ }
28
+ }} className={clsx('openapi-section-header', "".concat(className, "-header"))}>
29
+ <div className={clsx('openapi-section-header-content', "".concat(className, "-header-content"))}>
30
+ {(children || (selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body)) && toggeable ? (<button {...mergeProps(buttonProps, focusProps)} ref={triggerRef} className={clsx('openapi-section-toggle', "".concat(className, "-toggle"))} style={{
31
+ outline: isFocusVisible
32
+ ? '2px solid rgb(var(--primary-color-500) / 0.4)'
33
+ : 'none',
34
+ }}>
35
+ {toggleIcon}
36
+ </button>) : null}
37
+ {header}
38
+ </div>
39
+ <div className={clsx('openapi-section-header-controls', "".concat(className, "-header-controls"))} onClick={function (event) {
40
+ event.stopPropagation();
41
+ }}>
42
+ {tabs.length > 1 ? (<select className={clsx('openapi-section-select', 'openapi-select', "".concat(className, "-tabs-select"))} value={(_c = selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.key) !== null && _c !== void 0 ? _c : ''} onChange={function (event) {
43
+ setSelectedTab(event.target.value);
44
+ state.expand();
45
+ }}>
46
+ {tabs.map(function (tab) { return (<option key={tab.key} value={tab.key}>
47
+ {tab.label}
48
+ </option>); })}
49
+ </select>) : null}
50
+ </div>
51
+ </div>) : null}
52
+ {(!toggeable || state.isExpanded) && (children || (selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body)) ? (<div ref={panelRef} {...panelProps} className={clsx('openapi-section-body', "".concat(className, "-body"))}>
53
+ {children}
54
+ {selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.body}
55
+ </div>) : null}
56
+ {overlay ? (<div className={clsx('openapi-section-overlay', "".concat(className, "-overlay"))}>
57
+ {overlay}
58
+ </div>) : null}
59
+ </div>);
60
+ }
@@ -1,5 +1,4 @@
1
- import * as React from 'react';
2
1
  export declare function Markdown(props: {
3
2
  source: string;
4
3
  className?: string;
5
- }): React.JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import clsx from 'clsx';
2
+ export function Markdown(props) {
3
+ var source = props.source, className = props.className;
4
+ return (<div className={clsx('openapi-markdown', className)} dangerouslySetInnerHTML={{ __html: source }}/>);
5
+ }
@@ -1,6 +1,4 @@
1
- import * as React from 'react';
2
- import { OpenAPIOperationData } from './fetchOpenAPIOperation';
3
- import { OpenAPIContextProps } from './types';
1
+ import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
4
2
  /**
5
3
  * Display code samples to execute the operation.
6
4
  * It supports the Redocly custom syntax as well (https://redocly.com/docs/api-reference-docs/specification-extensions/x-code-samples/)
@@ -8,4 +6,4 @@ import { OpenAPIContextProps } from './types';
8
6
  export declare function OpenAPICodeSample(props: {
9
7
  data: OpenAPIOperationData;
10
8
  context: OpenAPIContextProps;
11
- }): React.JSX.Element | null;
9
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,141 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { codeSampleGenerators } from './code-samples';
13
+ import { generateMediaTypeExample, generateSchemaExample } from './generateSchemaExample';
14
+ import { InteractiveSection } from './InteractiveSection';
15
+ import { getServersURL } from './OpenAPIServerURL';
16
+ import { createStateKey } from './utils';
17
+ import { stringifyOpenAPI } from './stringifyOpenAPI';
18
+ import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
19
+ import { checkIsReference } from './utils';
20
+ /**
21
+ * Display code samples to execute the operation.
22
+ * It supports the Redocly custom syntax as well (https://redocly.com/docs/api-reference-docs/specification-extensions/x-code-samples/)
23
+ */
24
+ export function OpenAPICodeSample(props) {
25
+ var _a;
26
+ var data = props.data, context = props.context;
27
+ var searchParams = new URLSearchParams();
28
+ var headersObject = {};
29
+ (_a = data.operation.parameters) === null || _a === void 0 ? void 0 : _a.forEach(function (param) {
30
+ if (!param) {
31
+ return;
32
+ }
33
+ if (param.in === 'header' && param.required) {
34
+ var example = param.schema ? generateSchemaExample(param.schema) : undefined;
35
+ if (example !== undefined && param.name) {
36
+ headersObject[param.name] =
37
+ typeof example !== 'string' ? stringifyOpenAPI(example) : example;
38
+ }
39
+ }
40
+ else if (param.in === 'query' && param.required) {
41
+ var example = param.schema ? generateSchemaExample(param.schema) : undefined;
42
+ if (example !== undefined && param.name) {
43
+ searchParams.append(param.name, String(Array.isArray(example) ? example[0] : example));
44
+ }
45
+ }
46
+ });
47
+ var requestBody = !checkIsReference(data.operation.requestBody)
48
+ ? data.operation.requestBody
49
+ : undefined;
50
+ var requestBodyContentEntries = (requestBody === null || requestBody === void 0 ? void 0 : requestBody.content)
51
+ ? Object.entries(requestBody.content)
52
+ : undefined;
53
+ var requestBodyContent = requestBodyContentEntries === null || requestBodyContentEntries === void 0 ? void 0 : requestBodyContentEntries[0];
54
+ var input = {
55
+ url: getServersURL(data.servers) +
56
+ data.path +
57
+ (searchParams.size ? "?".concat(searchParams.toString()) : ''),
58
+ method: data.method,
59
+ body: requestBodyContent
60
+ ? generateMediaTypeExample(requestBodyContent[1], { onlyRequired: true })
61
+ : undefined,
62
+ headers: __assign(__assign(__assign({}, getSecurityHeaders(data.securities)), headersObject), (requestBodyContent
63
+ ? {
64
+ 'Content-Type': requestBodyContent[0],
65
+ }
66
+ : undefined)),
67
+ };
68
+ var autoCodeSamples = codeSampleGenerators.map(function (generator) { return ({
69
+ key: "default-".concat(generator.id),
70
+ label: generator.label,
71
+ body: <context.CodeBlock code={generator.generate(input)} syntax={generator.syntax}/>,
72
+ }); });
73
+ // Use custom samples if defined
74
+ var customCodeSamples = null;
75
+ ['x-custom-examples', 'x-code-samples', 'x-codeSamples'].forEach(function (key) {
76
+ var customSamples = data.operation[key];
77
+ if (customSamples && Array.isArray(customSamples)) {
78
+ customCodeSamples = customSamples
79
+ .filter(function (sample) {
80
+ return (typeof sample.label === 'string' &&
81
+ typeof sample.source === 'string' &&
82
+ typeof sample.lang === 'string');
83
+ })
84
+ .map(function (sample) { return ({
85
+ key: "redocly-".concat(sample.lang),
86
+ label: sample.label,
87
+ body: <context.CodeBlock code={sample.source} syntax={sample.lang}/>,
88
+ }); });
89
+ }
90
+ });
91
+ // Code samples can be disabled at the top-level or at the operation level
92
+ // If code samples are defined at the operation level, it will override the top-level setting
93
+ var codeSamplesDisabled = data['x-codeSamples'] === false || data.operation['x-codeSamples'] === false;
94
+ var samples = customCodeSamples !== null && customCodeSamples !== void 0 ? customCodeSamples : (!codeSamplesDisabled ? autoCodeSamples : []);
95
+ if (samples.length === 0) {
96
+ return null;
97
+ }
98
+ return (<OpenAPITabs stateKey={createStateKey('codesample')} items={samples}>
99
+ <InteractiveSection header={<OpenAPITabsList />} className="openapi-codesample">
100
+ <OpenAPITabsPanels />
101
+ </InteractiveSection>
102
+ </OpenAPITabs>);
103
+ }
104
+ function getSecurityHeaders(securities) {
105
+ var _a;
106
+ var _b, _c;
107
+ var security = securities[0];
108
+ if (!security) {
109
+ return {};
110
+ }
111
+ switch (security[1].type) {
112
+ case 'http': {
113
+ var scheme = security[1].scheme;
114
+ var format = (_b = security[1].bearerFormat) !== null && _b !== void 0 ? _b : 'YOUR_SECRET_TOKEN';
115
+ if (scheme === null || scheme === void 0 ? void 0 : scheme.includes('bearer')) {
116
+ scheme = 'Bearer';
117
+ }
118
+ else if (scheme === null || scheme === void 0 ? void 0 : scheme.includes('basic')) {
119
+ scheme = 'Basic';
120
+ format = 'username:password';
121
+ }
122
+ else if (scheme === null || scheme === void 0 ? void 0 : scheme.includes('token')) {
123
+ scheme = 'Token';
124
+ }
125
+ return {
126
+ Authorization: scheme + ' ' + format,
127
+ };
128
+ }
129
+ case 'apiKey': {
130
+ if (security[1].in !== 'header')
131
+ return {};
132
+ var name_1 = (_c = security[1].name) !== null && _c !== void 0 ? _c : 'Authorization';
133
+ return _a = {},
134
+ _a[name_1] = 'YOUR_API_KEY',
135
+ _a;
136
+ }
137
+ default: {
138
+ return {};
139
+ }
140
+ }
141
+ }
@@ -0,0 +1,12 @@
1
+ import type { OpenAPIClientContext } from './types';
2
+ interface Props {
3
+ context: OpenAPIClientContext;
4
+ children: React.ReactNode;
5
+ label?: string;
6
+ }
7
+ /**
8
+ * Display an interactive OpenAPI disclosure.
9
+ * The label is optional and defaults to "child attributes".
10
+ */
11
+ export declare function OpenAPIDisclosure({ context, children, label }: Props): JSX.Element;
12
+ export {};
@@ -0,0 +1,32 @@
1
+ import { useRef } from 'react';
2
+ import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
3
+ import { useDisclosureState } from 'react-stately';
4
+ /**
5
+ * Display an interactive OpenAPI disclosure.
6
+ * The label is optional and defaults to "child attributes".
7
+ */
8
+ export function OpenAPIDisclosure(_a) {
9
+ var context = _a.context, children = _a.children, label = _a.label;
10
+ var state = useDisclosureState({});
11
+ var panelRef = useRef(null);
12
+ var triggerRef = useRef(null);
13
+ var _b = useDisclosure({}, state, panelRef), triggerProps = _b.buttonProps, panelProps = _b.panelProps;
14
+ var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
15
+ var _c = useFocusRing(), isFocusVisible = _c.isFocusVisible, focusProps = _c.focusProps;
16
+ return (<div className="openapi-disclosure">
17
+ <button ref={triggerRef} {...mergeProps(buttonProps, focusProps)} slot="trigger" className="openapi-disclosure-trigger" style={{
18
+ outline: isFocusVisible
19
+ ? '2px solid rgb(var(--primary-color-500) / 0.4)'
20
+ : 'none',
21
+ }}>
22
+ {context.icons.plus}
23
+ <span>
24
+ {"".concat(state.isExpanded ? 'Hide' : 'Show', " ").concat(label ? label : "child attributes")}
25
+ </span>
26
+ </button>
27
+
28
+ {state.isExpanded && (<div ref={panelRef} {...panelProps} className="openapi-disclosure-panel">
29
+ {children}
30
+ </div>)}
31
+ </div>);
32
+ }
@@ -0,0 +1,19 @@
1
+ interface Props {
2
+ groups: TDisclosureGroup[];
3
+ icon?: React.ReactNode;
4
+ }
5
+ type TDisclosureGroup = {
6
+ id: string;
7
+ label: string | React.ReactNode;
8
+ tabs?: {
9
+ id: string;
10
+ label: string | React.ReactNode;
11
+ body?: React.ReactNode;
12
+ }[];
13
+ };
14
+ import { DisclosureGroupProps } from 'react-stately';
15
+ /**
16
+ * Display an interactive OpenAPI disclosure group.
17
+ */
18
+ export declare function OpenAPIDisclosureGroup(props: DisclosureGroupProps & Props): import("react").JSX.Element;
19
+ export {};
@@ -0,0 +1,81 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { mergeProps, useButton, useDisclosure, useFocusRing, useId } from 'react-aria';
13
+ import { useDisclosureGroupState, useDisclosureState, } from 'react-stately';
14
+ import { createContext, useContext, useRef, useState } from 'react';
15
+ var DisclosureGroupStateContext = createContext(null);
16
+ /**
17
+ * Display an interactive OpenAPI disclosure group.
18
+ */
19
+ export function OpenAPIDisclosureGroup(props) {
20
+ var icon = props.icon, groups = props.groups;
21
+ var state = useDisclosureGroupState(props);
22
+ return (<DisclosureGroupStateContext.Provider value={state}>
23
+ {groups.map(function (group) { return (<DisclosureItem icon={icon} key={group.id} group={group}/>); })}
24
+ </DisclosureGroupStateContext.Provider>);
25
+ }
26
+ function DisclosureItem(props) {
27
+ var _a, _b, _c, _d, _e;
28
+ var icon = props.icon, group = props.group;
29
+ var defaultId = useId();
30
+ var id = group.id || defaultId;
31
+ var groupState = useContext(DisclosureGroupStateContext);
32
+ var isExpanded = (groupState === null || groupState === void 0 ? void 0 : groupState.expandedKeys.has(id)) || false;
33
+ var state = useDisclosureState({
34
+ isExpanded: isExpanded,
35
+ onExpandedChange: function () {
36
+ if (groupState) {
37
+ groupState.toggleKey(id);
38
+ }
39
+ },
40
+ });
41
+ var panelRef = useRef(null);
42
+ var triggerRef = useRef(null);
43
+ var isDisabled = (groupState === null || groupState === void 0 ? void 0 : groupState.isDisabled) || !((_a = group.tabs) === null || _a === void 0 ? void 0 : _a.length) || false;
44
+ var _f = useDisclosure(__assign(__assign({}, props), { isExpanded: isExpanded, isDisabled: isDisabled }), state, panelRef), triggerProps = _f.buttonProps, panelProps = _f.panelProps;
45
+ var buttonProps = useButton(triggerProps, triggerRef).buttonProps;
46
+ var _g = useFocusRing(), isFocusVisible = _g.isFocusVisible, focusProps = _g.focusProps;
47
+ var defaultTab = ((_c = (_b = group.tabs) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.id) || '';
48
+ var _h = useState(defaultTab), selectedTabKey = _h[0], setSelectedTabKey = _h[1];
49
+ var selectedTab = (_d = group.tabs) === null || _d === void 0 ? void 0 : _d.find(function (tab) { return tab.id === selectedTabKey; });
50
+ return (<div className="openapi-disclosure-group" aria-expanded={state.isExpanded}>
51
+ <div className="openapi-disclosure-group-header">
52
+ <button slot="trigger" ref={triggerRef} {...mergeProps(buttonProps, focusProps)} disabled={isDisabled} style={{
53
+ outline: isFocusVisible
54
+ ? '2px solid rgb(var(--primary-color-500)/0.4)'
55
+ : 'none',
56
+ }} className="openapi-disclosure-group-trigger">
57
+ <div className="openapi-disclosure-group-icon">
58
+ {icon || (<svg viewBox="0 0 24 24" className="openapi-disclosure-group-icon">
59
+ <path d="m8.25 4.5 7.5 7.5-7.5 7.5"/>
60
+ </svg>)}
61
+ </div>
62
+
63
+ {group.label}
64
+ </button>
65
+ {group.tabs ? (<div className="openapi-disclosure-group-mediatype">
66
+ {((_e = group.tabs) === null || _e === void 0 ? void 0 : _e.length) > 1 ? (<select className="openapi-section-select openapi-select openapi-disclosure-group-tabs-select" onClick={function (event) { return event.stopPropagation(); }} value={selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.id} onChange={function (event) {
67
+ setSelectedTabKey(event.target.value);
68
+ state.expand();
69
+ }}>
70
+ {group.tabs.map(function (tab) { return (<option key={tab.id} value={tab.id}>
71
+ {tab.label}
72
+ </option>); })}
73
+ </select>) : !!group.tabs[0] ? (<span>{group.tabs[0].label}</span>) : null}
74
+ </div>) : null}
75
+ </div>
76
+
77
+ {state.isExpanded && selectedTab && (<div className="openapi-disclosure-group-panel" ref={panelRef} {...panelProps}>
78
+ {selectedTab.body}
79
+ </div>)}
80
+ </div>);
81
+ }
@@ -1,6 +1,4 @@
1
- import * as React from 'react';
2
- import { OpenAPIOperationData } from './fetchOpenAPIOperation';
3
- import { OpenAPIContextProps } from './types';
1
+ import type { OpenAPIContextProps, OpenAPIOperationData } from './types';
4
2
  /**
5
3
  * Display an interactive OpenAPI operation.
6
4
  */
@@ -8,4 +6,4 @@ export declare function OpenAPIOperation(props: {
8
6
  className?: string;
9
7
  data: OpenAPIOperationData;
10
8
  context: OpenAPIContextProps;
11
- }): React.JSX.Element;
9
+ }): import("react").JSX.Element;
@@ -0,0 +1,51 @@
1
+ import clsx from 'clsx';
2
+ import { Markdown } from './Markdown';
3
+ import { OpenAPICodeSample } from './OpenAPICodeSample';
4
+ import { OpenAPIResponseExample } from './OpenAPIResponseExample';
5
+ import { OpenAPISpec } from './OpenAPISpec';
6
+ import { OpenAPIPath } from './OpenAPIPath';
7
+ import { resolveDescription } from './utils';
8
+ /**
9
+ * Display an interactive OpenAPI operation.
10
+ */
11
+ export function OpenAPIOperation(props) {
12
+ var _a;
13
+ var className = props.className, data = props.data, context = props.context;
14
+ var operation = data.operation;
15
+ var clientContext = {
16
+ defaultInteractiveOpened: context.defaultInteractiveOpened,
17
+ icons: context.icons,
18
+ blockKey: context.blockKey,
19
+ };
20
+ var description = (_a = resolveDescription(operation)) === null || _a === void 0 ? void 0 : _a.trim();
21
+ return (<div className={clsx('openapi-operation', className)}>
22
+ <div className="openapi-summary" id={context.id}>
23
+ <h2 className="openapi-summary-title" data-deprecated={operation.deprecated}>
24
+ {operation.summary}
25
+ </h2>
26
+ {operation.deprecated && <div className="openapi-deprecated">Deprecated</div>}
27
+ </div>
28
+ <div className="openapi-columns">
29
+ <div className="openapi-column-spec">
30
+ {operation['x-deprecated-sunset'] ? (<div className="openapi-deprecated-sunset openapi-description openapi-markdown">
31
+ This operation is deprecated and will be sunset on{' '}
32
+ <span className="openapi-deprecated-sunset-date">
33
+ {operation['x-deprecated-sunset']}
34
+ </span>
35
+ {"."}
36
+ </div>) : null}
37
+ {description ? (<div className="openapi-intro">
38
+ <Markdown className="openapi-description" source={description}/>
39
+ </div>) : null}
40
+ <OpenAPIPath data={data} context={context}/>
41
+ <OpenAPISpec data={data} context={clientContext}/>
42
+ </div>
43
+ <div className="openapi-column-preview">
44
+ <div className="openapi-column-preview-body">
45
+ <OpenAPICodeSample {...props}/>
46
+ <OpenAPIResponseExample {...props}/>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>);
51
+ }
@@ -0,0 +1,16 @@
1
+ interface OpenAPIOperationPointer {
2
+ path: string;
3
+ method: string;
4
+ }
5
+ interface OpenAPIOperationContextValue {
6
+ onOpenClient: (pointer: OpenAPIOperationPointer) => void;
7
+ }
8
+ /**
9
+ * Provider for the OpenAPIOperationContext.
10
+ */
11
+ export declare function OpenAPIOperationContextProvider(props: React.PropsWithChildren<Partial<OpenAPIOperationContextValue>>): import("react").JSX.Element;
12
+ /**
13
+ * Hook to access the OpenAPIOperationContext.
14
+ */
15
+ export declare function useOpenAPIOperationContext(): OpenAPIOperationContextValue;
16
+ export {};
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { createContext, useContext, useMemo } from 'react';
3
+ import { useEventCallback } from 'usehooks-ts';
4
+ var OpenAPIOperationContext = createContext({
5
+ onOpenClient: function () { },
6
+ });
7
+ /**
8
+ * Provider for the OpenAPIOperationContext.
9
+ */
10
+ export function OpenAPIOperationContextProvider(props) {
11
+ var children = props.children;
12
+ var onOpenClient = useEventCallback(function (pointer) {
13
+ var _a;
14
+ (_a = props.onOpenClient) === null || _a === void 0 ? void 0 : _a.call(props, pointer);
15
+ });
16
+ var value = useMemo(function () { return ({ onOpenClient: onOpenClient }); }, [onOpenClient]);
17
+ return (<OpenAPIOperationContext.Provider value={value}>
18
+ {children}
19
+ </OpenAPIOperationContext.Provider>);
20
+ }
21
+ /**
22
+ * Hook to access the OpenAPIOperationContext.
23
+ */
24
+ export function useOpenAPIOperationContext() {
25
+ return useContext(OpenAPIOperationContext);
26
+ }
@@ -0,0 +1,8 @@
1
+ import type { OpenAPIOperationData, OpenAPIContextProps } from './types';
2
+ /**
3
+ * Display the path of an operation.
4
+ */
5
+ export declare function OpenAPIPath(props: {
6
+ data: OpenAPIOperationData;
7
+ context: OpenAPIContextProps;
8
+ }): JSX.Element;
@@ -0,0 +1,54 @@
1
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
+ if (ar || !(i in from)) {
4
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
+ ar[i] = from[i];
6
+ }
7
+ }
8
+ return to.concat(ar || Array.prototype.slice.call(from));
9
+ };
10
+ import { ScalarApiButton } from './ScalarApiButton';
11
+ /**
12
+ * Display the path of an operation.
13
+ */
14
+ export function OpenAPIPath(props) {
15
+ var data = props.data, context = props.context;
16
+ var method = data.method, path = data.path;
17
+ var specUrl = context.specUrl;
18
+ return (<div className="openapi-path">
19
+ <div className={"openapi-method openapi-method-".concat(method)}>{method}</div>
20
+ <div className="openapi-path-title" data-deprecated={data.operation.deprecated}>
21
+ <p>{formatPath(path)}</p>
22
+ </div>
23
+ {data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'] ? null : (<ScalarApiButton method={method} path={path} specUrl={specUrl}/>)}
24
+ </div>);
25
+ }
26
+ // Format the path to highlight placeholders
27
+ function formatPath(path) {
28
+ // Matches placeholders like {id}, {userId}, etc.
29
+ var regex = /\{(\w+)\}/g;
30
+ var parts = [];
31
+ var lastIndex = 0;
32
+ // Replace placeholders with <em> tags
33
+ path.replace(regex, function (match, key, offset) {
34
+ parts.push(path.slice(lastIndex, offset));
35
+ parts.push(<em key={key}>{"{".concat(key, "}")}</em>);
36
+ lastIndex = offset + match.length;
37
+ return match;
38
+ });
39
+ // Push remaining text after the last placeholder
40
+ parts.push(path.slice(lastIndex));
41
+ // Join parts with separators wrapped in <span>
42
+ var formattedPath = parts.reduce(function (acc, part, index) {
43
+ if (typeof part === 'string' && index > 0 && part === '/') {
44
+ return __spreadArray(__spreadArray([], acc, true), [
45
+ <span className="openapi-path-separator" key={"sep-".concat(index)}>
46
+ /
47
+ </span>,
48
+ part,
49
+ ], false);
50
+ }
51
+ return __spreadArray(__spreadArray([], acc, true), [part], false);
52
+ }, []);
53
+ return <span>{formattedPath}</span>;
54
+ }
@@ -1,10 +1,9 @@
1
- import * as React from 'react';
2
- import { OpenAPIV3 } from 'openapi-types';
3
- import { OpenAPIClientContext } from './types';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
+ import type { OpenAPIClientContext } from './types';
4
3
  /**
5
4
  * Display an interactive request body.
6
5
  */
7
6
  export declare function OpenAPIRequestBody(props: {
8
- requestBody: OpenAPIV3.RequestBodyObject;
7
+ requestBody: OpenAPIV3.RequestBodyObject | OpenAPIV3.ReferenceObject;
9
8
  context: OpenAPIClientContext;
10
- }): React.JSX.Element;
9
+ }): import("react").JSX.Element | null;