@stoplight/elements 7.16.6 → 8.0.0
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/APIWithSidebarLayout.d.ts +9 -1
- package/components/API/utils.d.ts +7 -6
- package/index.esm.js +127 -21
- package/index.js +126 -20
- package/index.mjs +127 -21
- package/package.json +4 -4
- package/utils/oas/types.d.ts +5 -2
- package/web-components.min.js +1 -1
|
@@ -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/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, SidebarLayout, Logo, TableOfContents, PoweredByLink, slugify, withRouter, withStyles, withPersistenceBoundary, withMosaicProvider, withQueryClientProvider, 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,52 @@ 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
|
+
ungrouped.forEach(operationNode => {
|
|
83
|
+
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
tree.push({
|
|
87
|
+
id: operationNode.uri,
|
|
88
|
+
slug: operationNode.uri,
|
|
89
|
+
title: operationNode.name,
|
|
90
|
+
type: operationNode.type,
|
|
91
|
+
meta: operationNode.data.method,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
groups.forEach(group => {
|
|
95
|
+
const items = group.items.flatMap(operationNode => {
|
|
96
|
+
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
id: operationNode.uri,
|
|
101
|
+
slug: operationNode.uri,
|
|
102
|
+
title: operationNode.name,
|
|
103
|
+
type: operationNode.type,
|
|
104
|
+
meta: operationNode.data.method,
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
if (items.length > 0) {
|
|
108
|
+
tree.push({
|
|
109
|
+
title: group.title,
|
|
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);
|
|
82
122
|
ungrouped.forEach(operationNode => {
|
|
83
123
|
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
84
124
|
return;
|
|
@@ -108,13 +148,14 @@ const computeAPITree = (serviceNode, config = {}) => {
|
|
|
108
148
|
tree.push({
|
|
109
149
|
title: group.title,
|
|
110
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,11 +297,13 @@ 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);
|
|
252
|
-
};
|
|
305
|
+
};
|
|
306
|
+
Collapse.displayName = 'Collapse';
|
|
253
307
|
|
|
254
308
|
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
255
309
|
const container = React.useRef(null);
|
|
@@ -268,26 +322,32 @@ const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideI
|
|
|
268
322
|
if (hideInternal && node && isInternal(node)) {
|
|
269
323
|
return React.createElement(Redirect, { to: "/" });
|
|
270
324
|
}
|
|
325
|
+
const sidebar = (React.createElement(Sidebar, { serviceNode: serviceNode, logo: logo, container: container, pathname: pathname, tree: tree }));
|
|
326
|
+
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 }))));
|
|
327
|
+
};
|
|
328
|
+
const Sidebar = ({ serviceNode, logo, container, pathname, tree }) => {
|
|
271
329
|
const handleTocClick = () => {
|
|
272
330
|
if (container.current) {
|
|
273
331
|
container.current.scrollIntoView();
|
|
274
332
|
}
|
|
275
333
|
};
|
|
276
|
-
|
|
334
|
+
return (React.createElement(React.Fragment, null,
|
|
277
335
|
React.createElement(Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
278
336
|
logo ? (React.createElement(Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React.createElement(Logo, { logo: serviceNode.data.logo })),
|
|
279
337
|
React.createElement(Heading, { size: 4 }, serviceNode.name)),
|
|
280
338
|
React.createElement(Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
281
339
|
React.createElement(TableOfContents, { tree: tree, activeId: pathname, Link: Link, onLinkClick: handleTocClick })),
|
|
282
340
|
React.createElement(PoweredByLink, { source: serviceNode.name, pathname: pathname, packageType: "elements" })));
|
|
283
|
-
|
|
284
|
-
|
|
341
|
+
};
|
|
342
|
+
Sidebar.displayName = 'Sidebar';
|
|
285
343
|
|
|
286
344
|
var NodeTypes;
|
|
287
345
|
(function (NodeTypes) {
|
|
288
346
|
NodeTypes["Paths"] = "paths";
|
|
289
347
|
NodeTypes["Path"] = "path";
|
|
290
348
|
NodeTypes["Operation"] = "operation";
|
|
349
|
+
NodeTypes["Webhooks"] = "webhooks";
|
|
350
|
+
NodeTypes["Webhook"] = "webhook";
|
|
291
351
|
NodeTypes["Components"] = "components";
|
|
292
352
|
NodeTypes["Models"] = "models";
|
|
293
353
|
NodeTypes["Model"] = "model";
|
|
@@ -339,6 +399,22 @@ const oas3SourceMap = [
|
|
|
339
399
|
},
|
|
340
400
|
],
|
|
341
401
|
},
|
|
402
|
+
{
|
|
403
|
+
match: 'webhooks',
|
|
404
|
+
type: NodeTypes.Webhooks,
|
|
405
|
+
children: [
|
|
406
|
+
{
|
|
407
|
+
notMatch: '^x-',
|
|
408
|
+
type: NodeTypes.Webhook,
|
|
409
|
+
children: [
|
|
410
|
+
{
|
|
411
|
+
match: 'get|post|put|delete|options|head|patch|trace',
|
|
412
|
+
type: NodeTypes.Webhook,
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
},
|
|
416
|
+
],
|
|
417
|
+
},
|
|
342
418
|
{
|
|
343
419
|
match: 'components',
|
|
344
420
|
type: NodeTypes.Components,
|
|
@@ -393,7 +469,7 @@ function computeServiceNode(document, map, transformService, transformOperation)
|
|
|
393
469
|
return serviceNode;
|
|
394
470
|
}
|
|
395
471
|
function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
396
|
-
var _a;
|
|
472
|
+
var _a, _b;
|
|
397
473
|
const nodes = [];
|
|
398
474
|
if (!isObject(data))
|
|
399
475
|
return nodes;
|
|
@@ -406,7 +482,12 @@ function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
|
406
482
|
if (match.type === NodeTypes.Operation && jsonPath.length === 3) {
|
|
407
483
|
const path = String(jsonPath[1]);
|
|
408
484
|
const method = String(jsonPath[2]);
|
|
409
|
-
const operationDocument = transformer({
|
|
485
|
+
const operationDocument = transformer({
|
|
486
|
+
document,
|
|
487
|
+
name: path,
|
|
488
|
+
method,
|
|
489
|
+
config: OPERATION_CONFIG,
|
|
490
|
+
});
|
|
410
491
|
let parsedUri;
|
|
411
492
|
const encodedPath = String(encodePointerFragment(path));
|
|
412
493
|
if (operationDocument.iid) {
|
|
@@ -423,6 +504,31 @@ function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
|
423
504
|
tags: ((_a = operationDocument.tags) === null || _a === void 0 ? void 0 : _a.map(tag => tag.name)) || [],
|
|
424
505
|
});
|
|
425
506
|
}
|
|
507
|
+
else if (match.type === NodeTypes.Webhook && jsonPath.length === 3) {
|
|
508
|
+
const name = String(jsonPath[1]);
|
|
509
|
+
const method = String(jsonPath[2]);
|
|
510
|
+
const webhookDocument = transformer({
|
|
511
|
+
document,
|
|
512
|
+
name,
|
|
513
|
+
method,
|
|
514
|
+
config: WEBHOOK_CONFIG,
|
|
515
|
+
});
|
|
516
|
+
let parsedUri;
|
|
517
|
+
const encodedPath = String(encodePointerFragment(name));
|
|
518
|
+
if (webhookDocument.iid) {
|
|
519
|
+
parsedUri = `/webhooks/${webhookDocument.iid}`;
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
parsedUri = uri.replace(encodedPath, slugify(name));
|
|
523
|
+
}
|
|
524
|
+
nodes.push({
|
|
525
|
+
type: NodeType.HttpWebhook,
|
|
526
|
+
uri: parsedUri,
|
|
527
|
+
data: webhookDocument,
|
|
528
|
+
name: webhookDocument.summary || webhookDocument.name,
|
|
529
|
+
tags: ((_b = webhookDocument.tags) === null || _b === void 0 ? void 0 : _b.map(tag => tag.name)) || [],
|
|
530
|
+
});
|
|
531
|
+
}
|
|
426
532
|
else if (match.type === NodeTypes.Model) {
|
|
427
533
|
const schemaDocument = get(document, jsonPath);
|
|
428
534
|
const parsedUri = uri.replace(OAS_MODEL_REGEXP, 'schemas/');
|
package/index.js
CHANGED
|
@@ -13,6 +13,7 @@ var reactQuery = require('react-query');
|
|
|
13
13
|
var reactRouterDom = require('react-router-dom');
|
|
14
14
|
var yaml = require('@stoplight/yaml');
|
|
15
15
|
var saver = require('file-saver');
|
|
16
|
+
var oas = require('@stoplight/http-spec/oas');
|
|
16
17
|
var oas2 = require('@stoplight/http-spec/oas2');
|
|
17
18
|
var oas3 = require('@stoplight/http-spec/oas3');
|
|
18
19
|
var json = require('@stoplight/json');
|
|
@@ -49,13 +50,12 @@ var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
|
|
|
49
50
|
var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
|
|
50
51
|
var last__default = /*#__PURE__*/_interopDefaultLegacy(last);
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
function computeTagGroups(serviceNode, nodeType) {
|
|
53
54
|
const groupsByTagId = {};
|
|
54
55
|
const ungrouped = [];
|
|
55
56
|
const lowerCaseServiceTags = serviceNode.tags.map(tn => tn.toLowerCase());
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
continue;
|
|
57
|
+
const groupableNodes = serviceNode.children.filter(n => n.type === nodeType);
|
|
58
|
+
for (const node of groupableNodes) {
|
|
59
59
|
const tagName = node.tags[0];
|
|
60
60
|
if (tagName) {
|
|
61
61
|
const tagId = tagName.toLowerCase();
|
|
@@ -91,7 +91,7 @@ const computeTagGroups = (serviceNode) => {
|
|
|
91
91
|
})
|
|
92
92
|
.map(([, tagGroup]) => tagGroup);
|
|
93
93
|
return { groups: orderedTagGroups, ungrouped };
|
|
94
|
-
}
|
|
94
|
+
}
|
|
95
95
|
const defaultComputerAPITreeConfig = {
|
|
96
96
|
hideSchemas: false,
|
|
97
97
|
hideInternal: false,
|
|
@@ -106,12 +106,52 @@ const computeAPITree = (serviceNode, config = {}) => {
|
|
|
106
106
|
type: 'overview',
|
|
107
107
|
meta: '',
|
|
108
108
|
});
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
109
|
+
const hasOperationNodes = serviceNode.children.some(node => node.type === types.NodeType.HttpOperation);
|
|
110
|
+
if (hasOperationNodes) {
|
|
111
111
|
tree.push({
|
|
112
112
|
title: 'Endpoints',
|
|
113
113
|
});
|
|
114
|
-
const { groups, ungrouped } = computeTagGroups(serviceNode);
|
|
114
|
+
const { groups, ungrouped } = computeTagGroups(serviceNode, types.NodeType.HttpOperation);
|
|
115
|
+
ungrouped.forEach(operationNode => {
|
|
116
|
+
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
tree.push({
|
|
120
|
+
id: operationNode.uri,
|
|
121
|
+
slug: operationNode.uri,
|
|
122
|
+
title: operationNode.name,
|
|
123
|
+
type: operationNode.type,
|
|
124
|
+
meta: operationNode.data.method,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
groups.forEach(group => {
|
|
128
|
+
const items = group.items.flatMap(operationNode => {
|
|
129
|
+
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
id: operationNode.uri,
|
|
134
|
+
slug: operationNode.uri,
|
|
135
|
+
title: operationNode.name,
|
|
136
|
+
type: operationNode.type,
|
|
137
|
+
meta: operationNode.data.method,
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
if (items.length > 0) {
|
|
141
|
+
tree.push({
|
|
142
|
+
title: group.title,
|
|
143
|
+
items,
|
|
144
|
+
itemsType: 'http_operation',
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
const hasWebhookNodes = serviceNode.children.some(node => node.type === types.NodeType.HttpWebhook);
|
|
150
|
+
if (hasWebhookNodes) {
|
|
151
|
+
tree.push({
|
|
152
|
+
title: 'Webhooks',
|
|
153
|
+
});
|
|
154
|
+
const { groups, ungrouped } = computeTagGroups(serviceNode, types.NodeType.HttpWebhook);
|
|
115
155
|
ungrouped.forEach(operationNode => {
|
|
116
156
|
if (mergedConfig.hideInternal && operationNode.data.internal) {
|
|
117
157
|
return;
|
|
@@ -141,13 +181,14 @@ const computeAPITree = (serviceNode, config = {}) => {
|
|
|
141
181
|
tree.push({
|
|
142
182
|
title: group.title,
|
|
143
183
|
items,
|
|
184
|
+
itemsType: 'http_webhook',
|
|
144
185
|
});
|
|
145
186
|
}
|
|
146
187
|
});
|
|
147
188
|
}
|
|
148
189
|
let schemaNodes = serviceNode.children.filter(node => node.type === types.NodeType.Model);
|
|
149
190
|
if (mergedConfig.hideInternal) {
|
|
150
|
-
schemaNodes = schemaNodes.filter(
|
|
191
|
+
schemaNodes = schemaNodes.filter(n => !isInternal(n));
|
|
151
192
|
}
|
|
152
193
|
if (!mergedConfig.hideSchemas && schemaNodes.length) {
|
|
153
194
|
tree.push({
|
|
@@ -181,7 +222,7 @@ const findFirstNodeSlug = (tree) => {
|
|
|
181
222
|
};
|
|
182
223
|
const isInternal = (node) => {
|
|
183
224
|
const data = node.data;
|
|
184
|
-
if (elementsCore.isHttpOperation(data)) {
|
|
225
|
+
if (elementsCore.isHttpOperation(data) || elementsCore.isHttpWebhookOperation(data)) {
|
|
185
226
|
return !!data.internal;
|
|
186
227
|
}
|
|
187
228
|
if (elementsCore.isHttpService(data)) {
|
|
@@ -191,7 +232,12 @@ const isInternal = (node) => {
|
|
|
191
232
|
};
|
|
192
233
|
|
|
193
234
|
const itemMatchesHash = (hash, item) => {
|
|
194
|
-
|
|
235
|
+
if (item.type === types.NodeType.HttpOperation) {
|
|
236
|
+
return hash.substr(1) === `${item.data.path}-${item.data.method}`;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
return hash.substr(1) === `${item.data.name}-${item.data.method}`;
|
|
240
|
+
}
|
|
195
241
|
};
|
|
196
242
|
const TryItContext = React__namespace.createContext({
|
|
197
243
|
hideTryIt: false,
|
|
@@ -209,14 +255,19 @@ const LocationContext = React__namespace.createContext({
|
|
|
209
255
|
});
|
|
210
256
|
LocationContext.displayName = 'LocationContext';
|
|
211
257
|
const APIWithStackedLayout = ({ serviceNode, hideTryIt, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, showPoweredByLink = true, location, }) => {
|
|
212
|
-
const { groups } = computeTagGroups(serviceNode);
|
|
258
|
+
const { groups: operationGroups } = computeTagGroups(serviceNode, types.NodeType.HttpOperation);
|
|
259
|
+
const { groups: webhookGroups } = computeTagGroups(serviceNode, types.NodeType.HttpWebhook);
|
|
213
260
|
return (React__namespace.createElement(LocationContext.Provider, { value: { location } },
|
|
214
261
|
React__namespace.createElement(TryItContext.Provider, { value: { hideTryIt, tryItCredentialsPolicy, corsProxy: tryItCorsProxy } },
|
|
215
262
|
React__namespace.createElement(mosaic.Flex, { w: "full", flexDirection: "col", m: "auto", className: "sl-max-w-4xl" },
|
|
216
263
|
React__namespace.createElement(mosaic.Box, { w: "full", borderB: true },
|
|
217
264
|
React__namespace.createElement(elementsCore.Docs, { className: "sl-mx-auto", nodeData: serviceNode.data, nodeTitle: serviceNode.name, nodeType: types.NodeType.HttpService, location: location, layoutOptions: { showPoweredByLink, hideExport }, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy })),
|
|
218
|
-
|
|
265
|
+
operationGroups.length > 0 && webhookGroups.length > 0 ? React__namespace.createElement(mosaic.Heading, { size: 2 }, "Endpoints") : null,
|
|
266
|
+
operationGroups.map(group => (React__namespace.createElement(Group, { key: group.title, group: group }))),
|
|
267
|
+
webhookGroups.length > 0 ? React__namespace.createElement(mosaic.Heading, { size: 2 }, "Webhooks") : null,
|
|
268
|
+
webhookGroups.map(group => (React__namespace.createElement(Group, { key: group.title, group: group })))))));
|
|
219
269
|
};
|
|
270
|
+
APIWithStackedLayout.displayName = 'APIWithStackedLayout';
|
|
220
271
|
const Group = React__namespace.memo(({ group }) => {
|
|
221
272
|
const [isExpanded, setIsExpanded] = React__namespace.useState(false);
|
|
222
273
|
const scrollRef = React__namespace.useRef(null);
|
|
@@ -243,6 +294,7 @@ const Group = React__namespace.memo(({ group }) => {
|
|
|
243
294
|
return React__namespace.createElement(Item, { key: item.uri, item: item });
|
|
244
295
|
}))));
|
|
245
296
|
});
|
|
297
|
+
Group.displayName = 'Group';
|
|
246
298
|
const Item = React__namespace.memo(({ item }) => {
|
|
247
299
|
const { location } = React__namespace.useContext(LocationContext);
|
|
248
300
|
const { hash } = location;
|
|
@@ -264,7 +316,7 @@ const Item = React__namespace.memo(({ item }) => {
|
|
|
264
316
|
return (React__namespace.createElement(mosaic.Box, { ref: scrollRef, w: "full", my: 2, border: true, borderColor: { default: isExpanded ? 'light' : 'transparent', hover: 'light' }, bg: { default: isExpanded ? 'code' : 'transparent', hover: 'code' } },
|
|
265
317
|
React__namespace.createElement(mosaic.Flex, { mx: "auto", alignItems: "center", cursor: "pointer", fontSize: "lg", p: 2, onClick: onClick, color: "current" },
|
|
266
318
|
React__namespace.createElement(mosaic.Box, { w: 24, textTransform: "uppercase", textAlign: "center", fontWeight: "semibold", border: true, rounded: true, px: 2, bg: "canvas", className: cn__default["default"](`sl-mr-5 sl-text-base`, `sl-text-${color}`, `sl-border-${color}`) }, item.data.method || 'UNKNOWN'),
|
|
267
|
-
React__namespace.createElement(mosaic.Box, { flex: 1, fontWeight: "medium", wordBreak: "all" }, item.data.path),
|
|
319
|
+
React__namespace.createElement(mosaic.Box, { flex: 1, fontWeight: "medium", wordBreak: "all" }, item.type === types.NodeType.HttpOperation ? item.data.path : item.name),
|
|
268
320
|
isDeprecated && React__namespace.createElement(elementsCore.DeprecatedBadge, null)),
|
|
269
321
|
React__namespace.createElement(Collapse, { isOpen: isExpanded },
|
|
270
322
|
React__namespace.createElement(mosaic.Box, { flex: 1, p: 2, fontWeight: "medium", mx: "auto", fontSize: "xl" }, item.name),
|
|
@@ -278,11 +330,13 @@ const Item = React__namespace.memo(({ item }) => {
|
|
|
278
330
|
React__namespace.createElement(mosaic.TabPanel, null,
|
|
279
331
|
React__namespace.createElement(elementsCore.TryItWithRequestSamples, { httpOperation: item.data, tryItCredentialsPolicy: tryItCredentialsPolicy, corsProxy: corsProxy }))))))));
|
|
280
332
|
});
|
|
333
|
+
Item.displayName = 'Item';
|
|
281
334
|
const Collapse = ({ isOpen, children }) => {
|
|
282
335
|
if (!isOpen)
|
|
283
336
|
return null;
|
|
284
337
|
return React__namespace.createElement(mosaic.Box, null, children);
|
|
285
|
-
};
|
|
338
|
+
};
|
|
339
|
+
Collapse.displayName = 'Collapse';
|
|
286
340
|
|
|
287
341
|
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
288
342
|
const container = React__namespace.useRef(null);
|
|
@@ -301,26 +355,32 @@ const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideI
|
|
|
301
355
|
if (hideInternal && node && isInternal(node)) {
|
|
302
356
|
return React__namespace.createElement(reactRouterDom.Redirect, { to: "/" });
|
|
303
357
|
}
|
|
358
|
+
const sidebar = (React__namespace.createElement(Sidebar, { serviceNode: serviceNode, logo: logo, container: container, pathname: pathname, tree: tree }));
|
|
359
|
+
return (React__namespace.createElement(elementsCore.SidebarLayout, { ref: container, sidebar: sidebar }, node && (React__namespace.createElement(elementsCore.ParsedDocs, { key: pathname, uri: pathname, node: node, nodeTitle: node.name, layoutOptions: layoutOptions, location: location, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }))));
|
|
360
|
+
};
|
|
361
|
+
const Sidebar = ({ serviceNode, logo, container, pathname, tree }) => {
|
|
304
362
|
const handleTocClick = () => {
|
|
305
363
|
if (container.current) {
|
|
306
364
|
container.current.scrollIntoView();
|
|
307
365
|
}
|
|
308
366
|
};
|
|
309
|
-
|
|
367
|
+
return (React__namespace.createElement(React__namespace.Fragment, null,
|
|
310
368
|
React__namespace.createElement(mosaic.Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
311
369
|
logo ? (React__namespace.createElement(elementsCore.Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React__namespace.createElement(elementsCore.Logo, { logo: serviceNode.data.logo })),
|
|
312
370
|
React__namespace.createElement(mosaic.Heading, { size: 4 }, serviceNode.name)),
|
|
313
371
|
React__namespace.createElement(mosaic.Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
314
372
|
React__namespace.createElement(elementsCore.TableOfContents, { tree: tree, activeId: pathname, Link: reactRouterDom.Link, onLinkClick: handleTocClick })),
|
|
315
373
|
React__namespace.createElement(elementsCore.PoweredByLink, { source: serviceNode.name, pathname: pathname, packageType: "elements" })));
|
|
316
|
-
|
|
317
|
-
|
|
374
|
+
};
|
|
375
|
+
Sidebar.displayName = 'Sidebar';
|
|
318
376
|
|
|
319
377
|
var NodeTypes;
|
|
320
378
|
(function (NodeTypes) {
|
|
321
379
|
NodeTypes["Paths"] = "paths";
|
|
322
380
|
NodeTypes["Path"] = "path";
|
|
323
381
|
NodeTypes["Operation"] = "operation";
|
|
382
|
+
NodeTypes["Webhooks"] = "webhooks";
|
|
383
|
+
NodeTypes["Webhook"] = "webhook";
|
|
324
384
|
NodeTypes["Components"] = "components";
|
|
325
385
|
NodeTypes["Models"] = "models";
|
|
326
386
|
NodeTypes["Model"] = "model";
|
|
@@ -372,6 +432,22 @@ const oas3SourceMap = [
|
|
|
372
432
|
},
|
|
373
433
|
],
|
|
374
434
|
},
|
|
435
|
+
{
|
|
436
|
+
match: 'webhooks',
|
|
437
|
+
type: NodeTypes.Webhooks,
|
|
438
|
+
children: [
|
|
439
|
+
{
|
|
440
|
+
notMatch: '^x-',
|
|
441
|
+
type: NodeTypes.Webhook,
|
|
442
|
+
children: [
|
|
443
|
+
{
|
|
444
|
+
match: 'get|post|put|delete|options|head|patch|trace',
|
|
445
|
+
type: NodeTypes.Webhook,
|
|
446
|
+
},
|
|
447
|
+
],
|
|
448
|
+
},
|
|
449
|
+
],
|
|
450
|
+
},
|
|
375
451
|
{
|
|
376
452
|
match: 'components',
|
|
377
453
|
type: NodeTypes.Components,
|
|
@@ -426,7 +502,7 @@ function computeServiceNode(document, map, transformService, transformOperation)
|
|
|
426
502
|
return serviceNode;
|
|
427
503
|
}
|
|
428
504
|
function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
429
|
-
var _a;
|
|
505
|
+
var _a, _b;
|
|
430
506
|
const nodes = [];
|
|
431
507
|
if (!isObject__default["default"](data))
|
|
432
508
|
return nodes;
|
|
@@ -439,7 +515,12 @@ function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
|
439
515
|
if (match.type === NodeTypes.Operation && jsonPath.length === 3) {
|
|
440
516
|
const path = String(jsonPath[1]);
|
|
441
517
|
const method = String(jsonPath[2]);
|
|
442
|
-
const operationDocument = transformer({
|
|
518
|
+
const operationDocument = transformer({
|
|
519
|
+
document,
|
|
520
|
+
name: path,
|
|
521
|
+
method,
|
|
522
|
+
config: oas.OPERATION_CONFIG,
|
|
523
|
+
});
|
|
443
524
|
let parsedUri;
|
|
444
525
|
const encodedPath = String(json.encodePointerFragment(path));
|
|
445
526
|
if (operationDocument.iid) {
|
|
@@ -456,6 +537,31 @@ function computeChildNodes(document, data, map, transformer, parentUri = '') {
|
|
|
456
537
|
tags: ((_a = operationDocument.tags) === null || _a === void 0 ? void 0 : _a.map(tag => tag.name)) || [],
|
|
457
538
|
});
|
|
458
539
|
}
|
|
540
|
+
else if (match.type === NodeTypes.Webhook && jsonPath.length === 3) {
|
|
541
|
+
const name = String(jsonPath[1]);
|
|
542
|
+
const method = String(jsonPath[2]);
|
|
543
|
+
const webhookDocument = transformer({
|
|
544
|
+
document,
|
|
545
|
+
name,
|
|
546
|
+
method,
|
|
547
|
+
config: oas.WEBHOOK_CONFIG,
|
|
548
|
+
});
|
|
549
|
+
let parsedUri;
|
|
550
|
+
const encodedPath = String(json.encodePointerFragment(name));
|
|
551
|
+
if (webhookDocument.iid) {
|
|
552
|
+
parsedUri = `/webhooks/${webhookDocument.iid}`;
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
parsedUri = uri.replace(encodedPath, elementsCore.slugify(name));
|
|
556
|
+
}
|
|
557
|
+
nodes.push({
|
|
558
|
+
type: types.NodeType.HttpWebhook,
|
|
559
|
+
uri: parsedUri,
|
|
560
|
+
data: webhookDocument,
|
|
561
|
+
name: webhookDocument.summary || webhookDocument.name,
|
|
562
|
+
tags: ((_b = webhookDocument.tags) === null || _b === void 0 ? void 0 : _b.map(tag => tag.name)) || [],
|
|
563
|
+
});
|
|
564
|
+
}
|
|
459
565
|
else if (match.type === NodeTypes.Model) {
|
|
460
566
|
const schemaDocument = get__default["default"](document, jsonPath);
|
|
461
567
|
const parsedUri = uri.replace(OAS_MODEL_REGEXP, 'schemas/');
|