@gitbook/react-openapi 0.7.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/InteractiveSection.d.ts +4 -8
  3. package/dist/InteractiveSection.jsx +60 -0
  4. package/dist/Markdown.d.ts +1 -2
  5. package/dist/Markdown.jsx +5 -0
  6. package/dist/OpenAPICodeSample.d.ts +2 -4
  7. package/dist/OpenAPICodeSample.jsx +141 -0
  8. package/dist/OpenAPIDisclosure.d.ts +12 -0
  9. package/dist/OpenAPIDisclosure.jsx +32 -0
  10. package/dist/OpenAPIDisclosureGroup.d.ts +19 -0
  11. package/dist/OpenAPIDisclosureGroup.jsx +81 -0
  12. package/dist/OpenAPIOperation.d.ts +2 -4
  13. package/dist/OpenAPIOperation.jsx +51 -0
  14. package/dist/OpenAPIOperationContext.d.ts +16 -0
  15. package/dist/OpenAPIOperationContext.jsx +26 -0
  16. package/dist/OpenAPIPath.d.ts +8 -0
  17. package/dist/OpenAPIPath.jsx +54 -0
  18. package/dist/OpenAPIRequestBody.d.ts +4 -5
  19. package/dist/OpenAPIRequestBody.jsx +22 -0
  20. package/dist/OpenAPIResponse.d.ts +4 -4
  21. package/dist/OpenAPIResponse.jsx +39 -0
  22. package/dist/OpenAPIResponseExample.d.ts +2 -4
  23. package/dist/OpenAPIResponseExample.jsx +108 -0
  24. package/dist/OpenAPIResponses.d.ts +3 -4
  25. package/dist/OpenAPIResponses.jsx +35 -0
  26. package/dist/OpenAPISchema.d.ts +11 -8
  27. package/dist/OpenAPISchema.jsx +285 -0
  28. package/dist/OpenAPISchemaName.d.ts +12 -0
  29. package/dist/OpenAPISchemaName.jsx +15 -0
  30. package/dist/OpenAPISecurities.d.ts +2 -4
  31. package/dist/OpenAPISecurities.jsx +55 -0
  32. package/dist/OpenAPIServerURL.d.ts +2 -3
  33. package/dist/OpenAPIServerURL.jsx +67 -0
  34. package/dist/OpenAPIServerURLVariable.d.ts +2 -3
  35. package/dist/OpenAPIServerURLVariable.jsx +8 -0
  36. package/dist/OpenAPISpec.d.ts +3 -4
  37. package/dist/OpenAPISpec.jsx +91 -0
  38. package/dist/OpenAPITabs.d.ts +26 -0
  39. package/dist/OpenAPITabs.jsx +103 -0
  40. package/dist/ScalarApiButton.d.ts +3 -3
  41. package/dist/ScalarApiButton.jsx +51 -0
  42. package/dist/code-samples.d.ts +4 -0
  43. package/dist/code-samples.js +103 -38
  44. package/dist/generateSchemaExample.d.ts +2 -2
  45. package/dist/generateSchemaExample.js +29 -102
  46. package/dist/index.d.ts +3 -2
  47. package/dist/index.js +2 -1
  48. package/dist/resolveOpenAPIOperation.d.ts +11 -0
  49. package/dist/resolveOpenAPIOperation.js +194 -0
  50. package/dist/stringifyOpenAPI.d.ts +4 -0
  51. package/dist/stringifyOpenAPI.js +6 -0
  52. package/dist/tsconfig.build.tsbuildinfo +1 -0
  53. package/dist/types.d.ts +11 -12
  54. package/dist/useSyncedTabsGlobalState.d.ts +1 -0
  55. package/dist/useSyncedTabsGlobalState.js +16 -0
  56. package/dist/utils.d.ts +6 -2
  57. package/dist/utils.js +13 -6
  58. package/package.json +12 -10
  59. package/src/InteractiveSection.tsx +90 -86
  60. package/src/Markdown.tsx +2 -3
  61. package/src/OpenAPICodeSample.tsx +43 -31
  62. package/src/OpenAPIDisclosure.tsx +50 -0
  63. package/src/OpenAPIDisclosureGroup.tsx +136 -0
  64. package/src/OpenAPIOperation.tsx +36 -42
  65. package/src/OpenAPIOperationContext.tsx +45 -0
  66. package/src/OpenAPIPath.tsx +65 -0
  67. package/src/OpenAPIRequestBody.tsx +10 -17
  68. package/src/OpenAPIResponse.tsx +27 -45
  69. package/src/OpenAPIResponseExample.tsx +89 -31
  70. package/src/OpenAPIResponses.tsx +48 -17
  71. package/src/OpenAPISchema.test.ts +1 -1
  72. package/src/OpenAPISchema.tsx +129 -108
  73. package/src/OpenAPISchemaName.tsx +27 -0
  74. package/src/OpenAPISecurities.tsx +45 -24
  75. package/src/OpenAPIServerURL.tsx +17 -10
  76. package/src/OpenAPIServerURLVariable.tsx +2 -4
  77. package/src/OpenAPISpec.tsx +58 -58
  78. package/src/OpenAPITabs.tsx +153 -0
  79. package/src/ScalarApiButton.tsx +84 -7
  80. package/src/code-samples.test.ts +51 -0
  81. package/src/code-samples.ts +95 -31
  82. package/src/generateSchemaExample.ts +26 -153
  83. package/src/index.ts +3 -2
  84. package/src/resolveOpenAPIOperation.test.ts +177 -0
  85. package/src/resolveOpenAPIOperation.ts +164 -0
  86. package/src/stringifyOpenAPI.ts +6 -0
  87. package/src/types.ts +17 -10
  88. package/src/useSyncedTabsGlobalState.ts +23 -0
  89. package/src/utils.ts +14 -7
  90. package/dist/InteractiveSection.js +0 -47
  91. package/dist/Markdown.js +0 -6
  92. package/dist/OpenAPICodeSample.js +0 -110
  93. package/dist/OpenAPIOperation.js +0 -38
  94. package/dist/OpenAPIRequestBody.js +0 -18
  95. package/dist/OpenAPIResponse.js +0 -32
  96. package/dist/OpenAPIResponseExample.js +0 -54
  97. package/dist/OpenAPIResponses.js +0 -18
  98. package/dist/OpenAPISchema.js +0 -235
  99. package/dist/OpenAPISchema.test.d.ts +0 -1
  100. package/dist/OpenAPISchema.test.js +0 -91
  101. package/dist/OpenAPISecurities.js +0 -42
  102. package/dist/OpenAPIServerURL.js +0 -51
  103. package/dist/OpenAPIServerURLVariable.js +0 -10
  104. package/dist/OpenAPISpec.js +0 -70
  105. package/dist/ScalarApiButton.js +0 -14
  106. package/dist/fetchOpenAPIOperation.d.ts +0 -72
  107. package/dist/fetchOpenAPIOperation.js +0 -124
  108. package/dist/fetchOpenAPIOperation.test.d.ts +0 -1
  109. package/dist/fetchOpenAPIOperation.test.js +0 -152
  110. package/dist/resolveOpenAPIPath.d.ts +0 -7
  111. package/dist/resolveOpenAPIPath.js +0 -112
  112. package/dist/resolveOpenAPIPath.test.d.ts +0 -1
  113. package/dist/resolveOpenAPIPath.test.js +0 -39
  114. package/dist/tsconfig.tsbuildinfo +0 -1
  115. package/src/fetchOpenAPIOperation.test.ts +0 -185
  116. package/src/fetchOpenAPIOperation.ts +0 -230
  117. package/src/resolveOpenAPIPath.test.ts +0 -60
  118. package/src/resolveOpenAPIPath.ts +0 -145
@@ -0,0 +1,55 @@
1
+ import { InteractiveSection } from './InteractiveSection';
2
+ import { Markdown } from './Markdown';
3
+ import { OpenAPISchemaName } from './OpenAPISchemaName';
4
+ import { resolveDescription } from './utils';
5
+ /**
6
+ * Present securities authorization that can be used for this operation.
7
+ */
8
+ export function OpenAPISecurities(props) {
9
+ var securities = props.securities, context = props.context;
10
+ if (securities.length === 0) {
11
+ return null;
12
+ }
13
+ return (<InteractiveSection header="Authorizations" toggeable defaultOpened={false} toggleIcon={context.icons.chevronRight} className="openapi-securities" tabs={securities.map(function (_a) {
14
+ var key = _a[0], security = _a[1];
15
+ var description = resolveDescription(security);
16
+ return {
17
+ key: key,
18
+ label: key,
19
+ body: (<div className="openapi-schema-body">
20
+ <div className="openapi-schema-presentation">
21
+ {getLabelForType(security)}
22
+
23
+ {description ? (<Markdown source={description} className="openapi-securities-description"/>) : null}
24
+ </div>
25
+ </div>),
26
+ };
27
+ })}/>);
28
+ }
29
+ function getLabelForType(security) {
30
+ var _a;
31
+ switch (security.type) {
32
+ case 'apiKey':
33
+ return (<OpenAPISchemaName propertyName={(_a = security.name) !== null && _a !== void 0 ? _a : 'apiKey'} type="string" required/>);
34
+ case 'http':
35
+ if (security.scheme === 'basic') {
36
+ return <OpenAPISchemaName propertyName="Authorization" type="string" required/>;
37
+ }
38
+ if (security.scheme == 'bearer') {
39
+ var description = resolveDescription(security);
40
+ return (<>
41
+ <OpenAPISchemaName propertyName="Authorization" type="string" required/>
42
+ {/** Show a default description if none is provided */}
43
+ {!description ? (<Markdown source={"Bearer authentication header of the form Bearer ".concat("&lt;token&gt;", ".")} className="openapi-securities-description"/>) : null}
44
+ </>);
45
+ }
46
+ return <OpenAPISchemaName propertyName="HTTP" required/>;
47
+ case 'oauth2':
48
+ return <OpenAPISchemaName propertyName="OAuth2" required/>;
49
+ case 'openIdConnect':
50
+ return <OpenAPISchemaName propertyName="OpenID Connect" required/>;
51
+ default:
52
+ // @ts-ignore
53
+ return security.type;
54
+ }
55
+ }
@@ -1,11 +1,10 @@
1
- import * as React from 'react';
2
- import { OpenAPIV3 } from 'openapi-types';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
3
2
  /**
4
3
  * Show the url of the server with variables replaced by their default values.
5
4
  */
6
5
  export declare function OpenAPIServerURL(props: {
7
6
  servers: OpenAPIV3.ServerObject[];
8
- }): React.JSX.Element;
7
+ }): import("react").JSX.Element | null;
9
8
  /**
10
9
  * Get the default URL for the server.
11
10
  */
@@ -0,0 +1,67 @@
1
+ import { OpenAPIServerURLVariable } from './OpenAPIServerURLVariable';
2
+ /**
3
+ * Show the url of the server with variables replaced by their default values.
4
+ */
5
+ export function OpenAPIServerURL(props) {
6
+ var _a;
7
+ var servers = props.servers;
8
+ var server = servers[0];
9
+ if (!server) {
10
+ return null;
11
+ }
12
+ var parts = parseServerURL((_a = server === null || server === void 0 ? void 0 : server.url) !== null && _a !== void 0 ? _a : '');
13
+ return (<span>
14
+ {parts.map(function (part, i) {
15
+ var _a;
16
+ if (part.kind === 'text') {
17
+ return <span key={i}>{part.text}</span>;
18
+ }
19
+ else {
20
+ var variable = (_a = server.variables) === null || _a === void 0 ? void 0 : _a[part.name];
21
+ if (!variable) {
22
+ return <span key={i}>{"{".concat(part.name, "}")}</span>;
23
+ }
24
+ return (<OpenAPIServerURLVariable key={i} name={part.name} variable={variable}/>);
25
+ }
26
+ })}
27
+ </span>);
28
+ }
29
+ /**
30
+ * Get the default URL for the server.
31
+ */
32
+ export function getServersURL(servers) {
33
+ var _a;
34
+ var server = servers[0];
35
+ if (!server) {
36
+ return '';
37
+ }
38
+ var parts = parseServerURL((_a = server === null || server === void 0 ? void 0 : server.url) !== null && _a !== void 0 ? _a : '');
39
+ return parts
40
+ .map(function (part) {
41
+ var _a, _b, _c;
42
+ if (part.kind === 'text') {
43
+ return part.text;
44
+ }
45
+ else {
46
+ return (_c = (_b = (_a = server.variables) === null || _a === void 0 ? void 0 : _a[part.name]) === null || _b === void 0 ? void 0 : _b.default) !== null && _c !== void 0 ? _c : "{".concat(part.name, "}");
47
+ }
48
+ })
49
+ .join('');
50
+ }
51
+ function parseServerURL(url) {
52
+ var parts = url.split(/{([^}]+)}/g);
53
+ var result = [];
54
+ for (var i = 0; i < parts.length; i++) {
55
+ var part = parts[i];
56
+ if (!part) {
57
+ continue;
58
+ }
59
+ if (i % 2 === 0) {
60
+ result.push({ kind: 'text', text: part });
61
+ }
62
+ else {
63
+ result.push({ kind: 'variable', name: part });
64
+ }
65
+ }
66
+ return result;
67
+ }
@@ -1,9 +1,8 @@
1
- import * as React from 'react';
2
- import { OpenAPIV3 } from 'openapi-types';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
3
2
  /**
4
3
  * Interactive component to show the value of a server variable and let the user change it.
5
4
  */
6
5
  export declare function OpenAPIServerURLVariable(props: {
7
6
  name: string;
8
7
  variable: OpenAPIV3.ServerVariableObject;
9
- }): React.JSX.Element;
8
+ }): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ 'use client';
2
+ /**
3
+ * Interactive component to show the value of a server variable and let the user change it.
4
+ */
5
+ export function OpenAPIServerURLVariable(props) {
6
+ var variable = props.variable;
7
+ return <span className="openapi-url-var">{variable.default}</span>;
8
+ }
@@ -1,5 +1,4 @@
1
- import * as React from 'react';
2
- import { OpenAPIClientContext } from './types';
1
+ import type { OpenAPIClientContext, OpenAPIOperationData } from './types';
3
2
  /**
4
3
  * Client component to render the spec for the request and response.
5
4
  *
@@ -7,6 +6,6 @@ import { OpenAPIClientContext } from './types';
7
6
  * (the entire schema is rendered at once, while the client component only renders the visible part)
8
7
  */
9
8
  export declare function OpenAPISpec(props: {
10
- rawData: any;
9
+ data: OpenAPIOperationData;
11
10
  context: OpenAPIClientContext;
12
- }): React.JSX.Element;
11
+ }): import("react").JSX.Element;
@@ -0,0 +1,91 @@
1
+ 'use client';
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ import { InteractiveSection } from './InteractiveSection';
14
+ import { OpenAPIRequestBody } from './OpenAPIRequestBody';
15
+ import { OpenAPIResponses } from './OpenAPIResponses';
16
+ import { OpenAPISchemaProperties } from './OpenAPISchema';
17
+ import { OpenAPISecurities } from './OpenAPISecurities';
18
+ import { resolveDescription } from './utils';
19
+ /**
20
+ * Client component to render the spec for the request and response.
21
+ *
22
+ * We use a client component as rendering recursive JSON schema in the server is expensive
23
+ * (the entire schema is rendered at once, while the client component only renders the visible part)
24
+ */
25
+ export function OpenAPISpec(props) {
26
+ var _a;
27
+ var data = props.data, context = props.context;
28
+ var operation = data.operation, securities = data.securities;
29
+ var parameters = (_a = operation.parameters) !== null && _a !== void 0 ? _a : [];
30
+ var parameterGroups = groupParameters(parameters);
31
+ return (<>
32
+ {securities.length > 0 ? (<OpenAPISecurities securities={securities} context={context}/>) : null}
33
+
34
+ {parameterGroups.map(function (group) {
35
+ return (<InteractiveSection key={group.key} className="openapi-parameters" header={group.label}>
36
+ <OpenAPISchemaProperties properties={group.parameters.map(function (parameter) {
37
+ var _a;
38
+ var description = resolveDescription(parameter);
39
+ return {
40
+ propertyName: parameter.name,
41
+ schema: __assign({
42
+ // Description of the parameter is defined at the parameter level
43
+ // we use display it if the schema doesn't override it
44
+ description: description, example: parameter.example,
45
+ // Deprecated can be defined at the parameter level
46
+ deprecated: parameter.deprecated }, ((_a = parameter.schema) !== null && _a !== void 0 ? _a : {})),
47
+ required: parameter.required,
48
+ };
49
+ })} context={context}/>
50
+ </InteractiveSection>);
51
+ })}
52
+
53
+ {operation.requestBody ? (<OpenAPIRequestBody requestBody={operation.requestBody} context={context}/>) : null}
54
+ {operation.responses ? (<OpenAPIResponses responses={operation.responses} context={context}/>) : null}
55
+ </>);
56
+ }
57
+ function groupParameters(parameters) {
58
+ var sorted = ['path', 'query', 'header'];
59
+ var groups = [];
60
+ parameters
61
+ .filter(function (parameter) { return parameter.in; })
62
+ .forEach(function (parameter) {
63
+ var key = parameter.in;
64
+ var label = getParameterGroupName(parameter.in);
65
+ var group = groups.find(function (group) { return group.key === key; });
66
+ if (group) {
67
+ group.parameters.push(parameter);
68
+ }
69
+ else {
70
+ groups.push({
71
+ key: key,
72
+ label: label,
73
+ parameters: [parameter],
74
+ });
75
+ }
76
+ });
77
+ groups.sort(function (a, b) { return sorted.indexOf(a.key) - sorted.indexOf(b.key); });
78
+ return groups;
79
+ }
80
+ function getParameterGroupName(paramIn) {
81
+ switch (paramIn) {
82
+ case 'path':
83
+ return 'Path parameters';
84
+ case 'query':
85
+ return 'Query parameters';
86
+ case 'header':
87
+ return 'Header parameters';
88
+ default:
89
+ return paramIn;
90
+ }
91
+ }
@@ -0,0 +1,26 @@
1
+ import { Key, TabsProps } from 'react-aria-components';
2
+ export type Tab = {
3
+ key: Key;
4
+ label: string;
5
+ body: React.ReactNode;
6
+ description?: string;
7
+ };
8
+ /**
9
+ * The OpenAPI Tabs wrapper component.
10
+ */
11
+ export declare function OpenAPITabs(props: React.PropsWithChildren<TabsProps & {
12
+ items: Tab[];
13
+ stateKey?: string;
14
+ }>): import("react").JSX.Element;
15
+ /**
16
+ * The OpenAPI Tabs list component.
17
+ * This component should be used as a child of the OpenAPITabs component.
18
+ * It renders the list of tabs.
19
+ */
20
+ export declare function OpenAPITabsList(): import("react").JSX.Element;
21
+ /**
22
+ * The OpenAPI Tabs panels component.
23
+ * This component should be used as a child of the OpenAPITabs component.
24
+ * It renders the content of the selected tab.
25
+ */
26
+ export declare function OpenAPITabsPanels(): import("react").JSX.Element | null;
@@ -0,0 +1,103 @@
1
+ 'use client';
2
+ import { createContext, useContext, useEffect, useMemo, useState } from 'react';
3
+ import { Tab, TabList, TabPanel, Tabs } from 'react-aria-components';
4
+ import { Markdown } from './Markdown';
5
+ import { useSyncedTabsGlobalState } from './useSyncedTabsGlobalState';
6
+ import { useIntersectionObserver } from 'usehooks-ts';
7
+ var OpenAPITabsContext = createContext(null);
8
+ function useOpenAPITabsContext() {
9
+ var context = useContext(OpenAPITabsContext);
10
+ if (!context) {
11
+ throw new Error('OpenAPITabsContext is missing');
12
+ }
13
+ return context;
14
+ }
15
+ /**
16
+ * The OpenAPI Tabs wrapper component.
17
+ */
18
+ export function OpenAPITabs(props) {
19
+ var children = props.children, items = props.items, stateKey = props.stateKey;
20
+ var isVisible = stateKey
21
+ ? useIntersectionObserver({
22
+ threshold: 0.1,
23
+ rootMargin: '200px',
24
+ })
25
+ : true;
26
+ var defaultTab = items[0];
27
+ var _a = useSyncedTabsGlobalState(), syncedTabs = _a[0], setSyncedTabs = _a[1];
28
+ var _b = useState(function () {
29
+ var _a, _b, _c;
30
+ if (isVisible && stateKey && syncedTabs && syncedTabs.has(stateKey)) {
31
+ var tabFromState = syncedTabs.get(stateKey);
32
+ return (_a = tabFromState === null || tabFromState === void 0 ? void 0 : tabFromState.key) !== null && _a !== void 0 ? _a : (_b = items[0]) === null || _b === void 0 ? void 0 : _b.key;
33
+ }
34
+ return (_c = items[0]) === null || _c === void 0 ? void 0 : _c.key;
35
+ }), selectedTabKey = _b[0], setSelectedTabKey = _b[1];
36
+ var _c = useState(defaultTab), selectedTab = _c[0], setSelectedTab = _c[1];
37
+ var handleSelectionChange = function (key) {
38
+ setSelectedTabKey(key);
39
+ if (stateKey) {
40
+ var tab_1 = items.find(function (item) { return item.key === key; });
41
+ if (!tab_1) {
42
+ return;
43
+ }
44
+ setSyncedTabs(function (state) {
45
+ var newState = new Map(state);
46
+ newState.set(stateKey, tab_1);
47
+ return newState;
48
+ });
49
+ }
50
+ };
51
+ useEffect(function () {
52
+ if (isVisible && stateKey && syncedTabs && syncedTabs.has(stateKey)) {
53
+ var tabFromState_1 = syncedTabs.get(stateKey);
54
+ if (!items.some(function (item) { return item.key === (tabFromState_1 === null || tabFromState_1 === void 0 ? void 0 : tabFromState_1.key); })) {
55
+ return;
56
+ }
57
+ if (tabFromState_1 && (tabFromState_1 === null || tabFromState_1 === void 0 ? void 0 : tabFromState_1.key) !== (selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.key)) {
58
+ setSelectedTab(tabFromState_1);
59
+ }
60
+ }
61
+ }, [isVisible, stateKey, syncedTabs, selectedTabKey]);
62
+ var contextValue = useMemo(function () { return ({ items: items, selectedTab: selectedTab }); }, [items, selectedTab]);
63
+ return (<OpenAPITabsContext.Provider value={contextValue}>
64
+ <Tabs className="openapi-tabs" onSelectionChange={handleSelectionChange} selectedKey={selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.key}>
65
+ {children}
66
+ </Tabs>
67
+ </OpenAPITabsContext.Provider>);
68
+ }
69
+ /**
70
+ * The OpenAPI Tabs list component.
71
+ * This component should be used as a child of the OpenAPITabs component.
72
+ * It renders the list of tabs.
73
+ */
74
+ export function OpenAPITabsList() {
75
+ var items = useOpenAPITabsContext().items;
76
+ return (<TabList className="openapi-tabs-list">
77
+ {items.map(function (tab) { return (<Tab style={function (_a) {
78
+ var isFocusVisible = _a.isFocusVisible;
79
+ return ({
80
+ outline: isFocusVisible
81
+ ? '2px solid rgb(var(--primary-color-500)/0.4)'
82
+ : 'none',
83
+ });
84
+ }} className="openapi-tabs-tab" key={"Tab-".concat(tab.key)} id={tab.key}>
85
+ {tab.label}
86
+ </Tab>); })}
87
+ </TabList>);
88
+ }
89
+ /**
90
+ * The OpenAPI Tabs panels component.
91
+ * This component should be used as a child of the OpenAPITabs component.
92
+ * It renders the content of the selected tab.
93
+ */
94
+ export function OpenAPITabsPanels() {
95
+ var selectedTab = useOpenAPITabsContext().selectedTab;
96
+ if (!selectedTab) {
97
+ return null;
98
+ }
99
+ return (<TabPanel key={"TabPanel-".concat(selectedTab.key)} id={selectedTab.key.toString()} className="openapi-tabs-panel">
100
+ {selectedTab.body}
101
+ {selectedTab.description ? (<Markdown source={selectedTab.description} className="openapi-tabs-footer"/>) : null}
102
+ </TabPanel>);
103
+ }
@@ -1,8 +1,8 @@
1
- import React from 'react';
2
1
  /**
3
2
  * Button which launches the Scalar API Client
4
3
  */
5
- export declare function ScalarApiButton({ method, path }: {
4
+ export declare function ScalarApiButton({ method, path, specUrl, }: {
6
5
  method: string;
7
6
  path: string;
8
- }): React.JSX.Element;
7
+ specUrl: string;
8
+ }): import("react").JSX.Element;
@@ -0,0 +1,51 @@
1
+ 'use client';
2
+ import { ApiClientModalProvider, useApiClientModal } from '@scalar/api-client-react';
3
+ import { useEffect, useImperativeHandle, useRef, useState } from 'react';
4
+ import { createPortal } from 'react-dom';
5
+ import { useOpenAPIOperationContext } from './OpenAPIOperationContext';
6
+ import { useEventCallback } from 'usehooks-ts';
7
+ /**
8
+ * Button which launches the Scalar API Client
9
+ */
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];
13
+ var controllerRef = useRef(null);
14
+ return (<div className="scalar scalar-activate">
15
+ <button className="scalar-activate-button button" onClick={function () {
16
+ var _a, _b;
17
+ (_b = (_a = controllerRef.current) === null || _a === void 0 ? void 0 : _a.openClient) === null || _b === void 0 ? void 0 : _b.call(_a);
18
+ setIsOpen(true);
19
+ }}>
20
+ <svg xmlns="http://www.w3.org/2000/svg" width="10" height="12" fill="none">
21
+ <path stroke="currentColor" strokeWidth="1.5" d="M1 10.05V1.43c0-.2.2-.31.37-.22l7.26 4.08c.17.1.17.33.01.43l-7.26 4.54a.25.25 0 0 1-.38-.21Z"/>
22
+ </svg>
23
+ Test it
24
+ </button>
25
+
26
+ {isOpen &&
27
+ createPortal(<ScalarModal controllerRef={controllerRef} method={method} path={path} specUrl={specUrl}/>, document.body)}
28
+ </div>);
29
+ }
30
+ 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}/>
33
+ </ApiClientModalProvider>);
34
+ }
35
+ function ScalarModalController(props) {
36
+ 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();
48
+ }
49
+ }, [openClient]);
50
+ return null;
51
+ }
@@ -11,4 +11,8 @@ interface CodeSampleGenerator {
11
11
  generate: (operation: CodeSampleInput) => string;
12
12
  }
13
13
  export declare const codeSampleGenerators: CodeSampleGenerator[];
14
+ export declare function parseHostAndPath(url: string): {
15
+ host: string | undefined;
16
+ path: string;
17
+ };
14
18
  export {};
@@ -1,69 +1,134 @@
1
- export const codeSampleGenerators = [
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 { stringifyOpenAPI } from './stringifyOpenAPI';
13
+ export var codeSampleGenerators = [
2
14
  {
3
- id: 'javascript',
4
- label: 'JavaScript',
5
- syntax: 'javascript',
6
- generate: ({ method, url, headers, body }) => {
7
- let code = '';
8
- code += `const response = await fetch('${url}', {
9
- method: '${method.toUpperCase()}',\n`;
15
+ id: 'curl',
16
+ label: 'cURL',
17
+ syntax: 'bash',
18
+ generate: function (_a) {
19
+ var method = _a.method, url = _a.url, headers = _a.headers, body = _a.body;
20
+ var separator = ' \\\n';
21
+ var lines = ['curl -L'];
22
+ if (method.toUpperCase() !== 'GET') {
23
+ lines.push("--request ".concat(method.toUpperCase()));
24
+ }
25
+ lines.push("--url '".concat(url, "'"));
10
26
  if (headers) {
11
- code += indent(`headers: ${JSON.stringify(headers, null, 2)},\n`, 4);
27
+ Object.entries(headers).forEach(function (_a) {
28
+ var key = _a[0], value = _a[1];
29
+ lines.push("--header '".concat(key, ": ").concat(value, "'"));
30
+ });
12
31
  }
13
- if (body) {
14
- code += indent(`body: JSON.stringify(${JSON.stringify(body, null, 2)}),\n`, 4);
32
+ if (body && Object.keys(body).length > 0) {
33
+ lines.push("--data '".concat(stringifyOpenAPI(body), "'"));
15
34
  }
16
- code += `});\n`;
17
- code += `const data = await response.json();`;
18
- return code;
35
+ return lines.map(function (line, index) { return (index > 0 ? indent(line, 2) : line); }).join(separator);
19
36
  },
20
37
  },
21
38
  {
22
- id: 'curl',
23
- label: 'Curl',
24
- syntax: 'bash',
25
- generate: ({ method, url, headers, body }) => {
26
- const separator = ' \\\n';
27
- const lines = ['curl -L'];
28
- if (method.toUpperCase() !== 'GET') {
29
- lines.push(`-X ${method.toUpperCase()}`);
30
- }
39
+ id: 'javascript',
40
+ label: 'JavaScript',
41
+ syntax: 'javascript',
42
+ generate: function (_a) {
43
+ var method = _a.method, url = _a.url, headers = _a.headers, body = _a.body;
44
+ var code = '';
45
+ code += "const response = await fetch('".concat(url, "', {\n method: '").concat(method.toUpperCase(), "',\n");
31
46
  if (headers) {
32
- Object.entries(headers).forEach(([key, value]) => {
33
- lines.push(`-H '${key}: ${value}'`);
34
- });
47
+ code += indent("headers: ".concat(stringifyOpenAPI(headers, null, 2), ",\n"), 4);
35
48
  }
36
- lines.push(`'${url}'`);
37
49
  if (body) {
38
- lines.push(`-d '${JSON.stringify(body)}'`);
50
+ code += indent("body: JSON.stringify(".concat(stringifyOpenAPI(body, null, 2), "),\n"), 4);
39
51
  }
40
- return lines.map((line, index) => (index > 0 ? indent(line, 2) : line)).join(separator);
52
+ code += "});\n";
53
+ code += "const data = await response.json();";
54
+ return code;
41
55
  },
42
56
  },
43
57
  {
44
58
  id: 'python',
45
59
  label: 'Python',
46
60
  syntax: 'python',
47
- generate: ({ method, url, headers, body }) => {
48
- let code = 'import requests\n\n';
49
- code += `response = requests.${method.toLowerCase()}(\n`;
50
- code += indent(`"${url}",\n`, 4);
61
+ generate: function (_a) {
62
+ var method = _a.method, url = _a.url, headers = _a.headers, body = _a.body;
63
+ var code = 'import requests\n\n';
64
+ code += "response = requests.".concat(method.toLowerCase(), "(\n");
65
+ code += indent("\"".concat(url, "\",\n"), 4);
51
66
  if (headers) {
52
- code += indent(`headers=${JSON.stringify(headers)},\n`, 4);
67
+ code += indent("headers=".concat(stringifyOpenAPI(headers), ",\n"), 4);
53
68
  }
54
69
  if (body) {
55
- code += indent(`json=${JSON.stringify(body)}\n`, 4);
70
+ code += indent("json=".concat(stringifyOpenAPI(body), "\n"), 4);
56
71
  }
57
72
  code += ')\n';
58
- code += `data = response.json()`;
73
+ code += "data = response.json()";
59
74
  return code;
60
75
  },
61
76
  },
77
+ {
78
+ id: 'http',
79
+ label: 'HTTP',
80
+ syntax: 'bash',
81
+ generate: function (_a) {
82
+ var method = _a.method, url = _a.url, _b = _a.headers, headers = _b === void 0 ? {} : _b, body = _a.body;
83
+ var _c = parseHostAndPath(url), host = _c.host, path = _c.path;
84
+ if (body) {
85
+ // if we had a body add a content length header
86
+ var bodyContent = body ? stringifyOpenAPI(body) : '';
87
+ // handle unicode chars with a text encoder
88
+ var encoder = new TextEncoder();
89
+ headers = __assign(__assign({}, headers), { 'Content-Length': encoder.encode(bodyContent).length.toString() });
90
+ }
91
+ if (!headers.hasOwnProperty('Accept')) {
92
+ headers.Accept = '*/*';
93
+ }
94
+ var headerString = headers
95
+ ? Object.entries(headers)
96
+ .map(function (_a) {
97
+ var key = _a[0], value = _a[1];
98
+ return key.toLowerCase() !== 'host' ? "".concat(key, ": ").concat(value) : "";
99
+ })
100
+ .join('\n') + '\n'
101
+ : '';
102
+ var bodyString = body ? "\n".concat(stringifyOpenAPI(body, null, 2)) : '';
103
+ var httpRequest = "".concat(method.toUpperCase(), " ").concat(decodeURI(path), " HTTP/1.1\nHost: ").concat(host, "\n").concat(headerString).concat(bodyString);
104
+ return httpRequest;
105
+ },
106
+ },
62
107
  ];
63
108
  function indent(code, spaces) {
64
- const indent = ' '.repeat(spaces);
109
+ var indent = ' '.repeat(spaces);
65
110
  return code
66
111
  .split('\n')
67
- .map((line) => (line ? indent + line : ''))
112
+ .map(function (line) { return (line ? indent + line : ''); })
68
113
  .join('\n');
69
114
  }
115
+ export function parseHostAndPath(url) {
116
+ try {
117
+ var urlObj = new URL(url);
118
+ var path = urlObj.pathname || '/';
119
+ return { host: urlObj.host, path: path };
120
+ }
121
+ catch (e) {
122
+ // If the URL was invalid do our best to parse the URL.
123
+ // Check for the protocol part and pull it off to grab the host
124
+ var splitted = url.split('//');
125
+ var fullUrl = splitted[1] ? splitted[1] : url;
126
+ // separate paths from the first element (host)
127
+ var parts = fullUrl.split('/');
128
+ // pull off the host (mutates)
129
+ var host = parts.shift();
130
+ // add a leading slash and join the paths again
131
+ var path = '/' + parts.join('/');
132
+ return { host: host, path: path };
133
+ }
134
+ }
@@ -1,4 +1,4 @@
1
- import { OpenAPIV3 } from 'openapi-types';
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
2
  type JSONValue = string | number | boolean | null | JSONValue[] | {
3
3
  [key: string]: JSONValue;
4
4
  };
@@ -7,7 +7,7 @@ type JSONValue = string | number | boolean | null | JSONValue[] | {
7
7
  */
8
8
  export declare function generateSchemaExample(schema: OpenAPIV3.SchemaObject, options?: {
9
9
  onlyRequired?: boolean;
10
- }, ancestors?: Set<OpenAPIV3.SchemaObject>): JSONValue | undefined;
10
+ }): JSONValue | undefined;
11
11
  /**
12
12
  * Generate an example for a media type.
13
13
  */