@stoplight/elements 7.16.6 → 8.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.
- package/components/API/APIWithResponsiveSidebarLayout.d.ts +17 -0
- package/components/API/APIWithSidebarLayout.d.ts +9 -1
- package/components/API/utils.d.ts +7 -6
- package/containers/API.d.ts +1 -1
- package/containers/API.stories.d.ts +12 -11
- package/index.d.ts +1 -0
- package/index.esm.js +157 -22
- package/index.js +156 -21
- package/index.mjs +157 -22
- package/package.json +4 -4
- package/styles.min.css +1 -1
- package/utils/oas/types.d.ts +5 -2
- package/web-components.min.js +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ExportButtonProps } from '@stoplight/elements-core';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { ServiceNode } from '../../utils/oas/types';
|
|
4
|
+
declare type SidebarLayoutProps = {
|
|
5
|
+
serviceNode: ServiceNode;
|
|
6
|
+
logo?: string;
|
|
7
|
+
hideTryIt?: boolean;
|
|
8
|
+
hideSchemas?: boolean;
|
|
9
|
+
hideInternal?: boolean;
|
|
10
|
+
hideExport?: boolean;
|
|
11
|
+
exportProps?: ExportButtonProps;
|
|
12
|
+
tryItCredentialsPolicy?: 'omit' | 'include' | 'same-origin';
|
|
13
|
+
tryItCorsProxy?: string;
|
|
14
|
+
compact?: number | boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare const APIWithResponsiveSidebarLayout: React.FC<SidebarLayoutProps>;
|
|
17
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExportButtonProps } from '@stoplight/elements-core';
|
|
1
|
+
import { ExportButtonProps, TableOfContentsItem } from '@stoplight/elements-core';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { ServiceNode } from '../../utils/oas/types';
|
|
4
4
|
declare type SidebarLayoutProps = {
|
|
@@ -13,4 +13,12 @@ declare type SidebarLayoutProps = {
|
|
|
13
13
|
tryItCorsProxy?: string;
|
|
14
14
|
};
|
|
15
15
|
export declare const APIWithSidebarLayout: React.FC<SidebarLayoutProps>;
|
|
16
|
+
declare type SidebarProps = {
|
|
17
|
+
serviceNode: ServiceNode;
|
|
18
|
+
logo?: string;
|
|
19
|
+
container: React.RefObject<HTMLElement>;
|
|
20
|
+
pathname: string;
|
|
21
|
+
tree: TableOfContentsItem[];
|
|
22
|
+
};
|
|
23
|
+
export declare const Sidebar: React.FC<SidebarProps>;
|
|
16
24
|
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { TableOfContentsItem } from '@stoplight/elements-core';
|
|
2
|
-
import { OperationNode, ServiceChildNode, ServiceNode } from '../../utils/oas/types';
|
|
3
|
-
|
|
2
|
+
import { OperationNode, ServiceChildNode, ServiceNode, WebhookNode } from '../../utils/oas/types';
|
|
3
|
+
declare type GroupableNode = OperationNode | WebhookNode;
|
|
4
|
+
export declare type TagGroup<T extends GroupableNode> = {
|
|
4
5
|
title: string;
|
|
5
|
-
items:
|
|
6
|
+
items: T[];
|
|
6
7
|
};
|
|
7
|
-
export declare
|
|
8
|
-
groups: TagGroup[];
|
|
9
|
-
ungrouped:
|
|
8
|
+
export declare function computeTagGroups<T extends GroupableNode>(serviceNode: ServiceNode, nodeType: T['type']): {
|
|
9
|
+
groups: TagGroup<T>[];
|
|
10
|
+
ungrouped: T[];
|
|
10
11
|
};
|
|
11
12
|
interface ComputeAPITreeConfig {
|
|
12
13
|
hideSchemas?: boolean;
|
package/containers/API.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare type APIPropsWithDocument = {
|
|
|
9
9
|
apiDescriptionUrl?: string;
|
|
10
10
|
} & CommonAPIProps;
|
|
11
11
|
export interface CommonAPIProps extends RoutingProps {
|
|
12
|
-
layout?: 'sidebar' | 'stacked';
|
|
12
|
+
layout?: 'sidebar' | 'stacked' | 'responsive';
|
|
13
13
|
logo?: string;
|
|
14
14
|
hideTryIt?: boolean;
|
|
15
15
|
hideSchemas?: boolean;
|
|
@@ -43,14 +43,15 @@ declare const _default: {
|
|
|
43
43
|
};
|
|
44
44
|
};
|
|
45
45
|
export default _default;
|
|
46
|
-
export declare const APIWithYamlProvidedDirectly: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-
|
|
47
|
-
export declare const APIWithJSONProvidedDirectly: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-
|
|
48
|
-
export declare const APIWithoutDescription: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-
|
|
49
|
-
export declare const APIWithInternalOperations: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-
|
|
50
|
-
export declare const OpenApi3Schema: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-
|
|
51
|
-
export declare const BadgesForSchema: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-
|
|
52
|
-
export declare const StackedLayout: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-
|
|
53
|
-
export declare const
|
|
54
|
-
export declare const
|
|
55
|
-
export declare const
|
|
56
|
-
export declare const
|
|
46
|
+
export declare const APIWithYamlProvidedDirectly: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
47
|
+
export declare const APIWithJSONProvidedDirectly: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
48
|
+
export declare const APIWithoutDescription: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
49
|
+
export declare const APIWithInternalOperations: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
50
|
+
export declare const OpenApi3Schema: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
51
|
+
export declare const BadgesForSchema: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
52
|
+
export declare const StackedLayout: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
53
|
+
export declare const ResponsiveLayout: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
54
|
+
export declare const Box: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
55
|
+
export declare const DigitalOcean: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
56
|
+
export declare const Github: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
|
57
|
+
export declare const Instagram: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, APIProps>;
|
package/index.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export type { APIProps } from './containers/API';
|
|
|
3
3
|
export { API } from './containers/API';
|
|
4
4
|
export { useExportDocumentProps } from './hooks/useExportDocumentProps';
|
|
5
5
|
export { transformOasToServiceNode } from './utils/oas';
|
|
6
|
+
export type { ServiceNode } from './utils/oas/types';
|
package/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isHttpOperation, isHttpService, HttpMethodColors, DeprecatedBadge, ParsedDocs, TryItWithRequestSamples, Docs, Logo, TableOfContents, PoweredByLink,
|
|
1
|
+
import { isHttpOperation, isHttpWebhookOperation, isHttpService, HttpMethodColors, DeprecatedBadge, ParsedDocs, TryItWithRequestSamples, Docs, ResponsiveSidebarLayout, SidebarLayout, Logo, TableOfContents, PoweredByLink, slugify, withRouter, withStyles, withPersistenceBoundary, withMosaicProvider, withQueryClientProvider, useResponsiveLayout, useParsedValue, useBundleRefsIntoDocument, NonIdealState, InlineRefResolverProvider } from '@stoplight/elements-core';
|
|
2
2
|
import { Box, Flex, Icon, Tabs, TabList, Tab, TabPanels, TabPanel, Heading } from '@stoplight/mosaic';
|
|
3
3
|
import { NodeType } from '@stoplight/types';
|
|
4
4
|
import cn from 'classnames';
|
|
@@ -9,6 +9,7 @@ import { useQuery } from 'react-query';
|
|
|
9
9
|
import { useLocation, Redirect, Link } from 'react-router-dom';
|
|
10
10
|
import { safeStringify } from '@stoplight/yaml';
|
|
11
11
|
import saver from 'file-saver';
|
|
12
|
+
import { OPERATION_CONFIG, WEBHOOK_CONFIG } from '@stoplight/http-spec/oas';
|
|
12
13
|
import { transformOas2Service, transformOas2Operation } from '@stoplight/http-spec/oas2';
|
|
13
14
|
import { transformOas3Service, transformOas3Operation } from '@stoplight/http-spec/oas3';
|
|
14
15
|
import { encodePointerFragment, pointerToPath } from '@stoplight/json';
|
|
@@ -16,13 +17,12 @@ import get from 'lodash/get.js';
|
|
|
16
17
|
import isObject from 'lodash/isObject.js';
|
|
17
18
|
import last from 'lodash/last.js';
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
function computeTagGroups(serviceNode, nodeType) {
|
|
20
21
|
const groupsByTagId = {};
|
|
21
22
|
const ungrouped = [];
|
|
22
23
|
const lowerCaseServiceTags = serviceNode.tags.map(tn => tn.toLowerCase());
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
continue;
|
|
24
|
+
const groupableNodes = serviceNode.children.filter(n => n.type === nodeType);
|
|
25
|
+
for (const node of groupableNodes) {
|
|
26
26
|
const tagName = node.tags[0];
|
|
27
27
|
if (tagName) {
|
|
28
28
|
const tagId = tagName.toLowerCase();
|
|
@@ -58,7 +58,7 @@ const computeTagGroups = (serviceNode) => {
|
|
|
58
58
|
})
|
|
59
59
|
.map(([, tagGroup]) => tagGroup);
|
|
60
60
|
return { groups: orderedTagGroups, ungrouped };
|
|
61
|
-
}
|
|
61
|
+
}
|
|
62
62
|
const defaultComputerAPITreeConfig = {
|
|
63
63
|
hideSchemas: false,
|
|
64
64
|
hideInternal: false,
|
|
@@ -73,12 +73,12 @@ const computeAPITree = (serviceNode, config = {}) => {
|
|
|
73
73
|
type: 'overview',
|
|
74
74
|
meta: '',
|
|
75
75
|
});
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
76
|
+
const hasOperationNodes = serviceNode.children.some(node => node.type === NodeType.HttpOperation);
|
|
77
|
+
if (hasOperationNodes) {
|
|
78
78
|
tree.push({
|
|
79
79
|
title: 'Endpoints',
|
|
80
80
|
});
|
|
81
|
-
const { groups, ungrouped } = computeTagGroups(serviceNode);
|
|
81
|
+
const { groups, ungrouped } = computeTagGroups(serviceNode, NodeType.HttpOperation);
|
|
82
82
|
ungrouped.forEach(operationNode => {
|
|
83
83
|
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
84
84
|
return;
|
|
@@ -108,13 +108,54 @@ const computeAPITree = (serviceNode, config = {}) => {
|
|
|
108
108
|
tree.push({
|
|
109
109
|
title: group.title,
|
|
110
110
|
items,
|
|
111
|
+
itemsType: 'http_operation',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const hasWebhookNodes = serviceNode.children.some(node => node.type === NodeType.HttpWebhook);
|
|
117
|
+
if (hasWebhookNodes) {
|
|
118
|
+
tree.push({
|
|
119
|
+
title: 'Webhooks',
|
|
120
|
+
});
|
|
121
|
+
const { groups, ungrouped } = computeTagGroups(serviceNode, NodeType.HttpWebhook);
|
|
122
|
+
ungrouped.forEach(operationNode => {
|
|
123
|
+
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
tree.push({
|
|
127
|
+
id: operationNode.uri,
|
|
128
|
+
slug: operationNode.uri,
|
|
129
|
+
title: operationNode.name,
|
|
130
|
+
type: operationNode.type,
|
|
131
|
+
meta: operationNode.data.method,
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
groups.forEach(group => {
|
|
135
|
+
const items = group.items.flatMap(operationNode => {
|
|
136
|
+
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
id: operationNode.uri,
|
|
141
|
+
slug: operationNode.uri,
|
|
142
|
+
title: operationNode.name,
|
|
143
|
+
type: operationNode.type,
|
|
144
|
+
meta: operationNode.data.method,
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
if (items.length > 0) {
|
|
148
|
+
tree.push({
|
|
149
|
+
title: group.title,
|
|
150
|
+
items,
|
|
151
|
+
itemsType: 'http_webhook',
|
|
111
152
|
});
|
|
112
153
|
}
|
|
113
154
|
});
|
|
114
155
|
}
|
|
115
156
|
let schemaNodes = serviceNode.children.filter(node => node.type === NodeType.Model);
|
|
116
157
|
if (mergedConfig.hideInternal) {
|
|
117
|
-
schemaNodes = schemaNodes.filter(
|
|
158
|
+
schemaNodes = schemaNodes.filter(n => !isInternal(n));
|
|
118
159
|
}
|
|
119
160
|
if (!mergedConfig.hideSchemas && schemaNodes.length) {
|
|
120
161
|
tree.push({
|
|
@@ -148,7 +189,7 @@ const findFirstNodeSlug = (tree) => {
|
|
|
148
189
|
};
|
|
149
190
|
const isInternal = (node) => {
|
|
150
191
|
const data = node.data;
|
|
151
|
-
if (isHttpOperation(data)) {
|
|
192
|
+
if (isHttpOperation(data) || isHttpWebhookOperation(data)) {
|
|
152
193
|
return !!data.internal;
|
|
153
194
|
}
|
|
154
195
|
if (isHttpService(data)) {
|
|
@@ -158,7 +199,12 @@ const isInternal = (node) => {
|
|
|
158
199
|
};
|
|
159
200
|
|
|
160
201
|
const itemMatchesHash = (hash, item) => {
|
|
161
|
-
|
|
202
|
+
if (item.type === NodeType.HttpOperation) {
|
|
203
|
+
return hash.substr(1) === `${item.data.path}-${item.data.method}`;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
return hash.substr(1) === `${item.data.name}-${item.data.method}`;
|
|
207
|
+
}
|
|
162
208
|
};
|
|
163
209
|
const TryItContext = React.createContext({
|
|
164
210
|
hideTryIt: false,
|
|
@@ -176,14 +222,19 @@ const LocationContext = React.createContext({
|
|
|
176
222
|
});
|
|
177
223
|
LocationContext.displayName = 'LocationContext';
|
|
178
224
|
const APIWithStackedLayout = ({ serviceNode, hideTryIt, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, showPoweredByLink = true, location, }) => {
|
|
179
|
-
const { groups } = computeTagGroups(serviceNode);
|
|
225
|
+
const { groups: operationGroups } = computeTagGroups(serviceNode, NodeType.HttpOperation);
|
|
226
|
+
const { groups: webhookGroups } = computeTagGroups(serviceNode, NodeType.HttpWebhook);
|
|
180
227
|
return (React.createElement(LocationContext.Provider, { value: { location } },
|
|
181
228
|
React.createElement(TryItContext.Provider, { value: { hideTryIt, tryItCredentialsPolicy, corsProxy: tryItCorsProxy } },
|
|
182
229
|
React.createElement(Flex, { w: "full", flexDirection: "col", m: "auto", className: "sl-max-w-4xl" },
|
|
183
230
|
React.createElement(Box, { w: "full", borderB: true },
|
|
184
231
|
React.createElement(Docs, { className: "sl-mx-auto", nodeData: serviceNode.data, nodeTitle: serviceNode.name, nodeType: NodeType.HttpService, location: location, layoutOptions: { showPoweredByLink, hideExport }, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy })),
|
|
185
|
-
|
|
232
|
+
operationGroups.length > 0 && webhookGroups.length > 0 ? React.createElement(Heading, { size: 2 }, "Endpoints") : null,
|
|
233
|
+
operationGroups.map(group => (React.createElement(Group, { key: group.title, group: group }))),
|
|
234
|
+
webhookGroups.length > 0 ? React.createElement(Heading, { size: 2 }, "Webhooks") : null,
|
|
235
|
+
webhookGroups.map(group => (React.createElement(Group, { key: group.title, group: group })))))));
|
|
186
236
|
};
|
|
237
|
+
APIWithStackedLayout.displayName = 'APIWithStackedLayout';
|
|
187
238
|
const Group = React.memo(({ group }) => {
|
|
188
239
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
189
240
|
const scrollRef = React.useRef(null);
|
|
@@ -210,6 +261,7 @@ const Group = React.memo(({ group }) => {
|
|
|
210
261
|
return React.createElement(Item, { key: item.uri, item: item });
|
|
211
262
|
}))));
|
|
212
263
|
});
|
|
264
|
+
Group.displayName = 'Group';
|
|
213
265
|
const Item = React.memo(({ item }) => {
|
|
214
266
|
const { location } = React.useContext(LocationContext);
|
|
215
267
|
const { hash } = location;
|
|
@@ -231,7 +283,7 @@ const Item = React.memo(({ item }) => {
|
|
|
231
283
|
return (React.createElement(Box, { ref: scrollRef, w: "full", my: 2, border: true, borderColor: { default: isExpanded ? 'light' : 'transparent', hover: 'light' }, bg: { default: isExpanded ? 'code' : 'transparent', hover: 'code' } },
|
|
232
284
|
React.createElement(Flex, { mx: "auto", alignItems: "center", cursor: "pointer", fontSize: "lg", p: 2, onClick: onClick, color: "current" },
|
|
233
285
|
React.createElement(Box, { w: 24, textTransform: "uppercase", textAlign: "center", fontWeight: "semibold", border: true, rounded: true, px: 2, bg: "canvas", className: cn(`sl-mr-5 sl-text-base`, `sl-text-${color}`, `sl-border-${color}`) }, item.data.method || 'UNKNOWN'),
|
|
234
|
-
React.createElement(Box, { flex: 1, fontWeight: "medium", wordBreak: "all" }, item.data.path),
|
|
286
|
+
React.createElement(Box, { flex: 1, fontWeight: "medium", wordBreak: "all" }, item.type === NodeType.HttpOperation ? item.data.path : item.name),
|
|
235
287
|
isDeprecated && React.createElement(DeprecatedBadge, null)),
|
|
236
288
|
React.createElement(Collapse, { isOpen: isExpanded },
|
|
237
289
|
React.createElement(Box, { flex: 1, p: 2, fontWeight: "medium", mx: "auto", fontSize: "xl" }, item.name),
|
|
@@ -245,10 +297,37 @@ const Item = React.memo(({ item }) => {
|
|
|
245
297
|
React.createElement(TabPanel, null,
|
|
246
298
|
React.createElement(TryItWithRequestSamples, { httpOperation: item.data, tryItCredentialsPolicy: tryItCredentialsPolicy, corsProxy: corsProxy }))))))));
|
|
247
299
|
});
|
|
300
|
+
Item.displayName = 'Item';
|
|
248
301
|
const Collapse = ({ isOpen, children }) => {
|
|
249
302
|
if (!isOpen)
|
|
250
303
|
return null;
|
|
251
304
|
return React.createElement(Box, null, children);
|
|
305
|
+
};
|
|
306
|
+
Collapse.displayName = 'Collapse';
|
|
307
|
+
|
|
308
|
+
const APIWithResponsiveSidebarLayout = ({ serviceNode, logo, hideTryIt, compact, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
309
|
+
const container = React.useRef(null);
|
|
310
|
+
const tree = React.useMemo(() => computeAPITree(serviceNode, { hideSchemas, hideInternal }), [serviceNode, hideSchemas, hideInternal]);
|
|
311
|
+
const location = useLocation();
|
|
312
|
+
const { pathname } = location;
|
|
313
|
+
const isRootPath = !pathname || pathname === '/';
|
|
314
|
+
const node = isRootPath ? serviceNode : serviceNode.children.find(child => child.uri === pathname);
|
|
315
|
+
const layoutOptions = React.useMemo(() => ({ hideTryIt: hideTryIt, compact: compact, hideExport: hideExport || (node === null || node === void 0 ? void 0 : node.type) !== NodeType.HttpService }), [hideTryIt, hideExport, node, compact]);
|
|
316
|
+
if (!node) {
|
|
317
|
+
const firstSlug = findFirstNodeSlug(tree);
|
|
318
|
+
if (firstSlug) {
|
|
319
|
+
return React.createElement(Redirect, { to: firstSlug });
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (hideInternal && node && isInternal(node)) {
|
|
323
|
+
return React.createElement(Redirect, { to: "/" });
|
|
324
|
+
}
|
|
325
|
+
const handleTocClick = () => {
|
|
326
|
+
if (container.current) {
|
|
327
|
+
container.current.scrollIntoView();
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
return (React.createElement(ResponsiveSidebarLayout, { onTocClick: handleTocClick, tree: tree, logo: logo !== null && logo !== void 0 ? logo : serviceNode.data.logo, ref: container, name: serviceNode.name }, node && (React.createElement(ParsedDocs, { key: pathname, uri: pathname, node: node, nodeTitle: node.name, layoutOptions: layoutOptions, location: location, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }))));
|
|
252
331
|
};
|
|
253
332
|
|
|
254
333
|
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
@@ -268,26 +347,32 @@ const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideI
|
|
|
268
347
|
if (hideInternal && node && isInternal(node)) {
|
|
269
348
|
return React.createElement(Redirect, { to: "/" });
|
|
270
349
|
}
|
|
350
|
+
const sidebar = (React.createElement(Sidebar, { serviceNode: serviceNode, logo: logo, container: container, pathname: pathname, tree: tree }));
|
|
351
|
+
return (React.createElement(SidebarLayout, { ref: container, sidebar: sidebar }, node && (React.createElement(ParsedDocs, { key: pathname, uri: pathname, node: node, nodeTitle: node.name, layoutOptions: layoutOptions, location: location, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }))));
|
|
352
|
+
};
|
|
353
|
+
const Sidebar = ({ serviceNode, logo, container, pathname, tree }) => {
|
|
271
354
|
const handleTocClick = () => {
|
|
272
355
|
if (container.current) {
|
|
273
356
|
container.current.scrollIntoView();
|
|
274
357
|
}
|
|
275
358
|
};
|
|
276
|
-
|
|
359
|
+
return (React.createElement(React.Fragment, null,
|
|
277
360
|
React.createElement(Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
278
361
|
logo ? (React.createElement(Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React.createElement(Logo, { logo: serviceNode.data.logo })),
|
|
279
362
|
React.createElement(Heading, { size: 4 }, serviceNode.name)),
|
|
280
363
|
React.createElement(Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
281
364
|
React.createElement(TableOfContents, { tree: tree, activeId: pathname, Link: Link, onLinkClick: handleTocClick })),
|
|
282
365
|
React.createElement(PoweredByLink, { source: serviceNode.name, pathname: pathname, packageType: "elements" })));
|
|
283
|
-
|
|
284
|
-
|
|
366
|
+
};
|
|
367
|
+
Sidebar.displayName = 'Sidebar';
|
|
285
368
|
|
|
286
369
|
var NodeTypes;
|
|
287
370
|
(function (NodeTypes) {
|
|
288
371
|
NodeTypes["Paths"] = "paths";
|
|
289
372
|
NodeTypes["Path"] = "path";
|
|
290
373
|
NodeTypes["Operation"] = "operation";
|
|
374
|
+
NodeTypes["Webhooks"] = "webhooks";
|
|
375
|
+
NodeTypes["Webhook"] = "webhook";
|
|
291
376
|
NodeTypes["Components"] = "components";
|
|
292
377
|
NodeTypes["Models"] = "models";
|
|
293
378
|
NodeTypes["Model"] = "model";
|
|
@@ -339,6 +424,22 @@ const oas3SourceMap = [
|
|
|
339
424
|
},
|
|
340
425
|
],
|
|
341
426
|
},
|
|
427
|
+
{
|
|
428
|
+
match: 'webhooks',
|
|
429
|
+
type: NodeTypes.Webhooks,
|
|
430
|
+
children: [
|
|
431
|
+
{
|
|
432
|
+
notMatch: '^x-',
|
|
433
|
+
type: NodeTypes.Webhook,
|
|
434
|
+
children: [
|
|
435
|
+
{
|
|
436
|
+
match: 'get|post|put|delete|options|head|patch|trace',
|
|
437
|
+
type: NodeTypes.Webhook,
|
|
438
|
+
},
|
|
439
|
+
],
|
|
440
|
+
},
|
|
441
|
+
],
|
|
442
|
+
},
|
|
342
443
|
{
|
|
343
444
|
match: 'components',
|
|
344
445
|
type: NodeTypes.Components,
|
|
@@ -393,7 +494,7 @@ function computeServiceNode(document, map, transformService, transformOperation)
|
|
|
393
494
|
return serviceNode;
|
|
394
495
|
}
|
|
395
496
|
function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
396
|
-
var _a;
|
|
497
|
+
var _a, _b;
|
|
397
498
|
const nodes = [];
|
|
398
499
|
if (!isObject(data))
|
|
399
500
|
return nodes;
|
|
@@ -406,7 +507,12 @@ function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
|
406
507
|
if (match.type === NodeTypes.Operation && jsonPath.length === 3) {
|
|
407
508
|
const path = String(jsonPath[1]);
|
|
408
509
|
const method = String(jsonPath[2]);
|
|
409
|
-
const operationDocument = transformer({
|
|
510
|
+
const operationDocument = transformer({
|
|
511
|
+
document,
|
|
512
|
+
name: path,
|
|
513
|
+
method,
|
|
514
|
+
config: OPERATION_CONFIG,
|
|
515
|
+
});
|
|
410
516
|
let parsedUri;
|
|
411
517
|
const encodedPath = String(encodePointerFragment(path));
|
|
412
518
|
if (operationDocument.iid) {
|
|
@@ -423,6 +529,31 @@ function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
|
423
529
|
tags: ((_a = operationDocument.tags) === null || _a === void 0 ? void 0 : _a.map(tag => tag.name)) || [],
|
|
424
530
|
});
|
|
425
531
|
}
|
|
532
|
+
else if (match.type === NodeTypes.Webhook && jsonPath.length === 3) {
|
|
533
|
+
const name = String(jsonPath[1]);
|
|
534
|
+
const method = String(jsonPath[2]);
|
|
535
|
+
const webhookDocument = transformer({
|
|
536
|
+
document,
|
|
537
|
+
name,
|
|
538
|
+
method,
|
|
539
|
+
config: WEBHOOK_CONFIG,
|
|
540
|
+
});
|
|
541
|
+
let parsedUri;
|
|
542
|
+
const encodedPath = String(encodePointerFragment(name));
|
|
543
|
+
if (webhookDocument.iid) {
|
|
544
|
+
parsedUri = `/webhooks/${webhookDocument.iid}`;
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
parsedUri = uri.replace(encodedPath, slugify(name));
|
|
548
|
+
}
|
|
549
|
+
nodes.push({
|
|
550
|
+
type: NodeType.HttpWebhook,
|
|
551
|
+
uri: parsedUri,
|
|
552
|
+
data: webhookDocument,
|
|
553
|
+
name: webhookDocument.summary || webhookDocument.name,
|
|
554
|
+
tags: ((_b = webhookDocument.tags) === null || _b === void 0 ? void 0 : _b.map(tag => tag.name)) || [],
|
|
555
|
+
});
|
|
556
|
+
}
|
|
426
557
|
else if (match.type === NodeTypes.Model) {
|
|
427
558
|
const schemaDocument = get(document, jsonPath);
|
|
428
559
|
const parsedUri = uri.replace(OAS_MODEL_REGEXP, 'schemas/');
|
|
@@ -495,9 +626,10 @@ const propsAreWithDocument = (props) => {
|
|
|
495
626
|
return props.hasOwnProperty('apiDescriptionDocument');
|
|
496
627
|
};
|
|
497
628
|
const APIImpl = props => {
|
|
498
|
-
const { layout, apiDescriptionUrl = '', logo, hideTryIt, hideSchemas, hideInternal, hideExport, tryItCredentialsPolicy, tryItCorsProxy, maxRefDepth, } = props;
|
|
629
|
+
const { layout = 'sidebar', apiDescriptionUrl = '', logo, hideTryIt, hideSchemas, hideInternal, hideExport, tryItCredentialsPolicy, tryItCorsProxy, maxRefDepth, } = props;
|
|
499
630
|
const location = useLocation();
|
|
500
631
|
const apiDescriptionDocument = propsAreWithDocument(props) ? props.apiDescriptionDocument : undefined;
|
|
632
|
+
const { isResponsiveLayoutEnabled } = useResponsiveLayout();
|
|
501
633
|
const { data: fetchedDocument, error } = useQuery([apiDescriptionUrl], () => fetch(apiDescriptionUrl).then(res => {
|
|
502
634
|
if (res.ok) {
|
|
503
635
|
return res.text();
|
|
@@ -523,7 +655,10 @@ const APIImpl = props => {
|
|
|
523
655
|
return (React.createElement(Flex, { justify: "center", alignItems: "center", w: "full", minH: "screen" },
|
|
524
656
|
React.createElement(NonIdealState, { title: "Failed to parse OpenAPI file", description: "Please make sure your OpenAPI file is valid and try again" })));
|
|
525
657
|
}
|
|
526
|
-
return (React.createElement(InlineRefResolverProvider, { document: parsedDocument, maxRefDepth: maxRefDepth },
|
|
658
|
+
return (React.createElement(InlineRefResolverProvider, { document: parsedDocument, maxRefDepth: maxRefDepth },
|
|
659
|
+
layout === 'stacked' && (React.createElement(APIWithStackedLayout, { serviceNode: serviceNode, hideTryIt: hideTryIt, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy, location: location })),
|
|
660
|
+
layout === 'sidebar' && (React.createElement(APIWithSidebarLayout, { logo: logo, serviceNode: serviceNode, hideTryIt: hideTryIt, hideSchemas: hideSchemas, hideInternal: hideInternal, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy })),
|
|
661
|
+
layout === 'responsive' && (React.createElement(APIWithResponsiveSidebarLayout, { logo: logo, serviceNode: serviceNode, hideTryIt: hideTryIt, hideSchemas: hideSchemas, hideInternal: hideInternal, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy, compact: isResponsiveLayoutEnabled }))));
|
|
527
662
|
};
|
|
528
663
|
const API = flow(withRouter, withStyles, withPersistenceBoundary, withMosaicProvider, withQueryClientProvider)(APIImpl);
|
|
529
664
|
|