@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.
@@ -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
- export declare type TagGroup = {
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: OperationNode[];
6
+ items: T[];
6
7
  };
7
- export declare const computeTagGroups: (serviceNode: ServiceNode) => {
8
- groups: TagGroup[];
9
- ungrouped: OperationNode[];
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;
@@ -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-0fc72a6d").R, APIProps>;
47
- export declare const APIWithJSONProvidedDirectly: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
48
- export declare const APIWithoutDescription: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
49
- export declare const APIWithInternalOperations: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
50
- export declare const OpenApi3Schema: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
51
- export declare const BadgesForSchema: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
52
- export declare const StackedLayout: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
53
- export declare const Box: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
54
- export declare const DigitalOcean: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
55
- export declare const Github: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
56
- export declare const Instagram: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, APIProps>;
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, SidebarLayout, slugify, withRouter, withStyles, withPersistenceBoundary, withMosaicProvider, withQueryClientProvider, useParsedValue, useBundleRefsIntoDocument, NonIdealState, InlineRefResolverProvider } from '@stoplight/elements-core';
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
- const computeTagGroups = (serviceNode) => {
20
+ function computeTagGroups(serviceNode, nodeType) {
20
21
  const groupsByTagId = {};
21
22
  const ungrouped = [];
22
23
  const lowerCaseServiceTags = serviceNode.tags.map(tn => tn.toLowerCase());
23
- for (const node of serviceNode.children) {
24
- if (node.type !== NodeType.HttpOperation)
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 operationNodes = serviceNode.children.filter(node => node.type === NodeType.HttpOperation);
77
- if (operationNodes.length) {
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(node => !node.data['x-internal']);
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
- return hash.substr(1) === `${item.data.path}-${item.data.method}`;
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
- groups.map(group => (React.createElement(Group, { key: group.title, group: group })))))));
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
- const sidebar = (React.createElement(React.Fragment, null,
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
- 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 }))));
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({ document, path, method });
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 }, layout === 'stacked' ? (React.createElement(APIWithStackedLayout, { serviceNode: serviceNode, hideTryIt: hideTryIt, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy, location: location })) : (React.createElement(APIWithSidebarLayout, { logo: logo, serviceNode: serviceNode, hideTryIt: hideTryIt, hideSchemas: hideSchemas, hideInternal: hideInternal, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }))));
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