@stoplight/elements 7.15.0 → 7.15.2
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/APIWithStackedLayout.d.ts +9 -0
- package/index.d.ts +1 -0
- package/index.esm.js +61 -50
- package/index.js +61 -49
- package/index.mjs +61 -50
- package/package.json +1 -1
- package/web-components.min.js +1 -1
|
@@ -2,6 +2,13 @@ import { ExportButtonProps } from '@stoplight/elements-core';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { ServiceNode } from '../../utils/oas/types';
|
|
4
4
|
declare type TryItCredentialsPolicy = 'omit' | 'include' | 'same-origin';
|
|
5
|
+
interface Location {
|
|
6
|
+
pathname: string;
|
|
7
|
+
search: string;
|
|
8
|
+
hash: string;
|
|
9
|
+
state: unknown;
|
|
10
|
+
key: string;
|
|
11
|
+
}
|
|
5
12
|
declare type StackedLayoutProps = {
|
|
6
13
|
serviceNode: ServiceNode;
|
|
7
14
|
hideTryIt?: boolean;
|
|
@@ -9,6 +16,8 @@ declare type StackedLayoutProps = {
|
|
|
9
16
|
exportProps?: ExportButtonProps;
|
|
10
17
|
tryItCredentialsPolicy?: TryItCredentialsPolicy;
|
|
11
18
|
tryItCorsProxy?: string;
|
|
19
|
+
showPoweredByLink?: boolean;
|
|
20
|
+
location: Location;
|
|
12
21
|
};
|
|
13
22
|
export declare const APIWithStackedLayout: React.FC<StackedLayoutProps>;
|
|
14
23
|
export {};
|
package/index.d.ts
CHANGED
package/index.esm.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { isHttpOperation, isHttpService,
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
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';
|
|
2
|
+
import { Box, Flex, Icon, Tabs, TabList, Tab, TabPanels, TabPanel, Heading } from '@stoplight/mosaic';
|
|
3
|
+
import { NodeType } from '@stoplight/types';
|
|
4
|
+
import cn from 'classnames';
|
|
4
5
|
import * as React from 'react';
|
|
6
|
+
import defaults from 'lodash/defaults.js';
|
|
7
|
+
import flow from 'lodash/flow.js';
|
|
5
8
|
import { useQuery } from 'react-query';
|
|
6
|
-
import { NodeType } from '@stoplight/types';
|
|
7
9
|
import { useLocation, Redirect, Link } from 'react-router-dom';
|
|
8
|
-
import defaults from 'lodash/defaults.js';
|
|
9
|
-
import cn from 'classnames';
|
|
10
10
|
import { safeStringify } from '@stoplight/yaml';
|
|
11
11
|
import saver from 'file-saver';
|
|
12
12
|
import { transformOas2Service, transformOas2Operation } from '@stoplight/http-spec/oas2';
|
|
@@ -157,59 +157,37 @@ const isInternal = (node) => {
|
|
|
157
157
|
return !!data['x-internal'];
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
161
|
-
const container = React.useRef(null);
|
|
162
|
-
const tree = React.useMemo(() => computeAPITree(serviceNode, { hideSchemas, hideInternal }), [serviceNode, hideSchemas, hideInternal]);
|
|
163
|
-
const location = useLocation();
|
|
164
|
-
const { pathname } = location;
|
|
165
|
-
const isRootPath = !pathname || pathname === '/';
|
|
166
|
-
const node = isRootPath ? serviceNode : serviceNode.children.find(child => child.uri === pathname);
|
|
167
|
-
const layoutOptions = React.useMemo(() => ({ hideTryIt: hideTryIt, hideExport: hideExport || (node === null || node === void 0 ? void 0 : node.type) !== NodeType.HttpService }), [hideTryIt, hideExport, node]);
|
|
168
|
-
if (!node) {
|
|
169
|
-
const firstSlug = findFirstNodeSlug(tree);
|
|
170
|
-
if (firstSlug) {
|
|
171
|
-
return React.createElement(Redirect, { to: firstSlug });
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (hideInternal && node && isInternal(node)) {
|
|
175
|
-
return React.createElement(Redirect, { to: "/" });
|
|
176
|
-
}
|
|
177
|
-
const handleTocClick = () => {
|
|
178
|
-
if (container.current) {
|
|
179
|
-
container.current.scrollIntoView();
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
const sidebar = (React.createElement(React.Fragment, null,
|
|
183
|
-
React.createElement(Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
184
|
-
logo ? (React.createElement(Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React.createElement(Logo, { logo: serviceNode.data.logo })),
|
|
185
|
-
React.createElement(Heading, { size: 4 }, serviceNode.name)),
|
|
186
|
-
React.createElement(Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
187
|
-
React.createElement(TableOfContents, { tree: tree, activeId: pathname, Link: Link, onLinkClick: handleTocClick })),
|
|
188
|
-
React.createElement(PoweredByLink, { source: serviceNode.name, pathname: pathname, packageType: "elements" })));
|
|
189
|
-
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 }))));
|
|
190
|
-
};
|
|
191
|
-
|
|
192
160
|
const itemMatchesHash = (hash, item) => {
|
|
193
|
-
return hash.substr(1) === `${item.
|
|
161
|
+
return hash.substr(1) === `${item.data.path}-${item.data.method}`;
|
|
194
162
|
};
|
|
195
163
|
const TryItContext = React.createContext({
|
|
196
164
|
hideTryIt: false,
|
|
197
165
|
tryItCredentialsPolicy: 'omit',
|
|
198
166
|
});
|
|
199
167
|
TryItContext.displayName = 'TryItContext';
|
|
200
|
-
const
|
|
201
|
-
|
|
168
|
+
const LocationContext = React.createContext({
|
|
169
|
+
location: {
|
|
170
|
+
hash: '',
|
|
171
|
+
key: '',
|
|
172
|
+
pathname: '',
|
|
173
|
+
search: '',
|
|
174
|
+
state: '',
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
LocationContext.displayName = 'LocationContext';
|
|
178
|
+
const APIWithStackedLayout = ({ serviceNode, hideTryIt, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, showPoweredByLink = true, location, }) => {
|
|
202
179
|
const { groups } = computeTagGroups(serviceNode);
|
|
203
|
-
return (React.createElement(
|
|
204
|
-
React.createElement(
|
|
205
|
-
React.createElement(
|
|
206
|
-
React.createElement(
|
|
207
|
-
|
|
180
|
+
return (React.createElement(LocationContext.Provider, { value: { location } },
|
|
181
|
+
React.createElement(TryItContext.Provider, { value: { hideTryIt, tryItCredentialsPolicy, corsProxy: tryItCorsProxy } },
|
|
182
|
+
React.createElement(Flex, { w: "full", flexDirection: "col", m: "auto", className: "sl-max-w-4xl" },
|
|
183
|
+
React.createElement(Box, { w: "full", borderB: true },
|
|
184
|
+
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 })))))));
|
|
208
186
|
};
|
|
209
187
|
const Group = React.memo(({ group }) => {
|
|
210
188
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
211
|
-
const { hash } = useLocation();
|
|
212
189
|
const scrollRef = React.useRef(null);
|
|
190
|
+
const { location: { hash }, } = React.useContext(LocationContext);
|
|
213
191
|
const urlHashMatches = hash.substr(1) === group.title;
|
|
214
192
|
const onClick = React.useCallback(() => setIsExpanded(!isExpanded), [isExpanded]);
|
|
215
193
|
const shouldExpand = React.useMemo(() => {
|
|
@@ -233,7 +211,7 @@ const Group = React.memo(({ group }) => {
|
|
|
233
211
|
}))));
|
|
234
212
|
});
|
|
235
213
|
const Item = React.memo(({ item }) => {
|
|
236
|
-
const location =
|
|
214
|
+
const { location } = React.useContext(LocationContext);
|
|
237
215
|
const { hash } = location;
|
|
238
216
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
239
217
|
const scrollRef = React.useRef(null);
|
|
@@ -273,6 +251,38 @@ const Collapse = ({ isOpen, children }) => {
|
|
|
273
251
|
return React.createElement(Box, null, children);
|
|
274
252
|
};
|
|
275
253
|
|
|
254
|
+
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
255
|
+
const container = React.useRef(null);
|
|
256
|
+
const tree = React.useMemo(() => computeAPITree(serviceNode, { hideSchemas, hideInternal }), [serviceNode, hideSchemas, hideInternal]);
|
|
257
|
+
const location = useLocation();
|
|
258
|
+
const { pathname } = location;
|
|
259
|
+
const isRootPath = !pathname || pathname === '/';
|
|
260
|
+
const node = isRootPath ? serviceNode : serviceNode.children.find(child => child.uri === pathname);
|
|
261
|
+
const layoutOptions = React.useMemo(() => ({ hideTryIt: hideTryIt, hideExport: hideExport || (node === null || node === void 0 ? void 0 : node.type) !== NodeType.HttpService }), [hideTryIt, hideExport, node]);
|
|
262
|
+
if (!node) {
|
|
263
|
+
const firstSlug = findFirstNodeSlug(tree);
|
|
264
|
+
if (firstSlug) {
|
|
265
|
+
return React.createElement(Redirect, { to: firstSlug });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (hideInternal && node && isInternal(node)) {
|
|
269
|
+
return React.createElement(Redirect, { to: "/" });
|
|
270
|
+
}
|
|
271
|
+
const handleTocClick = () => {
|
|
272
|
+
if (container.current) {
|
|
273
|
+
container.current.scrollIntoView();
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
const sidebar = (React.createElement(React.Fragment, null,
|
|
277
|
+
React.createElement(Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
278
|
+
logo ? (React.createElement(Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React.createElement(Logo, { logo: serviceNode.data.logo })),
|
|
279
|
+
React.createElement(Heading, { size: 4 }, serviceNode.name)),
|
|
280
|
+
React.createElement(Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
281
|
+
React.createElement(TableOfContents, { tree: tree, activeId: pathname, Link: Link, onLinkClick: handleTocClick })),
|
|
282
|
+
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
|
+
};
|
|
285
|
+
|
|
276
286
|
var NodeTypes;
|
|
277
287
|
(function (NodeTypes) {
|
|
278
288
|
NodeTypes["Paths"] = "paths";
|
|
@@ -486,6 +496,7 @@ const propsAreWithDocument = (props) => {
|
|
|
486
496
|
};
|
|
487
497
|
const APIImpl = props => {
|
|
488
498
|
const { layout, apiDescriptionUrl = '', logo, hideTryIt, hideSchemas, hideInternal, hideExport, tryItCredentialsPolicy, tryItCorsProxy, maxRefDepth, } = props;
|
|
499
|
+
const location = useLocation();
|
|
489
500
|
const apiDescriptionDocument = propsAreWithDocument(props) ? props.apiDescriptionDocument : undefined;
|
|
490
501
|
const { data: fetchedDocument, error } = useQuery([apiDescriptionUrl], () => fetch(apiDescriptionUrl).then(res => {
|
|
491
502
|
if (res.ok) {
|
|
@@ -512,8 +523,8 @@ const APIImpl = props => {
|
|
|
512
523
|
return (React.createElement(Flex, { justify: "center", alignItems: "center", w: "full", minH: "screen" },
|
|
513
524
|
React.createElement(NonIdealState, { title: "Failed to parse OpenAPI file", description: "Please make sure your OpenAPI file is valid and try again" })));
|
|
514
525
|
}
|
|
515
|
-
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 })) : (React.createElement(APIWithSidebarLayout, { logo: logo, serviceNode: serviceNode, hideTryIt: hideTryIt, hideSchemas: hideSchemas, hideInternal: hideInternal, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }))));
|
|
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 }))));
|
|
516
527
|
};
|
|
517
528
|
const API = flow(withRouter, withStyles, withPersistenceBoundary, withMosaicProvider, withQueryClientProvider)(APIImpl);
|
|
518
529
|
|
|
519
|
-
export { API, transformOasToServiceNode, useExportDocumentProps };
|
|
530
|
+
export { API, APIWithStackedLayout, transformOasToServiceNode, useExportDocumentProps };
|
package/index.js
CHANGED
|
@@ -4,13 +4,13 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var elementsCore = require('@stoplight/elements-core');
|
|
6
6
|
var mosaic = require('@stoplight/mosaic');
|
|
7
|
-
var
|
|
7
|
+
var types = require('@stoplight/types');
|
|
8
|
+
var cn = require('classnames');
|
|
8
9
|
var React = require('react');
|
|
10
|
+
var defaults = require('lodash/defaults.js');
|
|
11
|
+
var flow = require('lodash/flow.js');
|
|
9
12
|
var reactQuery = require('react-query');
|
|
10
|
-
var types = require('@stoplight/types');
|
|
11
13
|
var reactRouterDom = require('react-router-dom');
|
|
12
|
-
var defaults = require('lodash/defaults.js');
|
|
13
|
-
var cn = require('classnames');
|
|
14
14
|
var yaml = require('@stoplight/yaml');
|
|
15
15
|
var saver = require('file-saver');
|
|
16
16
|
var oas2 = require('@stoplight/http-spec/oas2');
|
|
@@ -40,10 +40,10 @@ function _interopNamespace(e) {
|
|
|
40
40
|
return Object.freeze(n);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
var
|
|
43
|
+
var cn__default = /*#__PURE__*/_interopDefaultLegacy(cn);
|
|
44
44
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
45
45
|
var defaults__default = /*#__PURE__*/_interopDefaultLegacy(defaults);
|
|
46
|
-
var
|
|
46
|
+
var flow__default = /*#__PURE__*/_interopDefaultLegacy(flow);
|
|
47
47
|
var saver__default = /*#__PURE__*/_interopDefaultLegacy(saver);
|
|
48
48
|
var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
|
|
49
49
|
var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
|
|
@@ -190,59 +190,37 @@ const isInternal = (node) => {
|
|
|
190
190
|
return !!data['x-internal'];
|
|
191
191
|
};
|
|
192
192
|
|
|
193
|
-
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
194
|
-
const container = React__namespace.useRef(null);
|
|
195
|
-
const tree = React__namespace.useMemo(() => computeAPITree(serviceNode, { hideSchemas, hideInternal }), [serviceNode, hideSchemas, hideInternal]);
|
|
196
|
-
const location = reactRouterDom.useLocation();
|
|
197
|
-
const { pathname } = location;
|
|
198
|
-
const isRootPath = !pathname || pathname === '/';
|
|
199
|
-
const node = isRootPath ? serviceNode : serviceNode.children.find(child => child.uri === pathname);
|
|
200
|
-
const layoutOptions = React__namespace.useMemo(() => ({ hideTryIt: hideTryIt, hideExport: hideExport || (node === null || node === void 0 ? void 0 : node.type) !== types.NodeType.HttpService }), [hideTryIt, hideExport, node]);
|
|
201
|
-
if (!node) {
|
|
202
|
-
const firstSlug = findFirstNodeSlug(tree);
|
|
203
|
-
if (firstSlug) {
|
|
204
|
-
return React__namespace.createElement(reactRouterDom.Redirect, { to: firstSlug });
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (hideInternal && node && isInternal(node)) {
|
|
208
|
-
return React__namespace.createElement(reactRouterDom.Redirect, { to: "/" });
|
|
209
|
-
}
|
|
210
|
-
const handleTocClick = () => {
|
|
211
|
-
if (container.current) {
|
|
212
|
-
container.current.scrollIntoView();
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
const sidebar = (React__namespace.createElement(React__namespace.Fragment, null,
|
|
216
|
-
React__namespace.createElement(mosaic.Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
217
|
-
logo ? (React__namespace.createElement(elementsCore.Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React__namespace.createElement(elementsCore.Logo, { logo: serviceNode.data.logo })),
|
|
218
|
-
React__namespace.createElement(mosaic.Heading, { size: 4 }, serviceNode.name)),
|
|
219
|
-
React__namespace.createElement(mosaic.Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
220
|
-
React__namespace.createElement(elementsCore.TableOfContents, { tree: tree, activeId: pathname, Link: reactRouterDom.Link, onLinkClick: handleTocClick })),
|
|
221
|
-
React__namespace.createElement(elementsCore.PoweredByLink, { source: serviceNode.name, pathname: pathname, packageType: "elements" })));
|
|
222
|
-
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 }))));
|
|
223
|
-
};
|
|
224
|
-
|
|
225
193
|
const itemMatchesHash = (hash, item) => {
|
|
226
|
-
return hash.substr(1) === `${item.
|
|
194
|
+
return hash.substr(1) === `${item.data.path}-${item.data.method}`;
|
|
227
195
|
};
|
|
228
196
|
const TryItContext = React__namespace.createContext({
|
|
229
197
|
hideTryIt: false,
|
|
230
198
|
tryItCredentialsPolicy: 'omit',
|
|
231
199
|
});
|
|
232
200
|
TryItContext.displayName = 'TryItContext';
|
|
233
|
-
const
|
|
234
|
-
|
|
201
|
+
const LocationContext = React__namespace.createContext({
|
|
202
|
+
location: {
|
|
203
|
+
hash: '',
|
|
204
|
+
key: '',
|
|
205
|
+
pathname: '',
|
|
206
|
+
search: '',
|
|
207
|
+
state: '',
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
LocationContext.displayName = 'LocationContext';
|
|
211
|
+
const APIWithStackedLayout = ({ serviceNode, hideTryIt, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, showPoweredByLink = true, location, }) => {
|
|
235
212
|
const { groups } = computeTagGroups(serviceNode);
|
|
236
|
-
return (React__namespace.createElement(
|
|
237
|
-
React__namespace.createElement(
|
|
238
|
-
React__namespace.createElement(mosaic.
|
|
239
|
-
React__namespace.createElement(
|
|
240
|
-
|
|
213
|
+
return (React__namespace.createElement(LocationContext.Provider, { value: { location } },
|
|
214
|
+
React__namespace.createElement(TryItContext.Provider, { value: { hideTryIt, tryItCredentialsPolicy, corsProxy: tryItCorsProxy } },
|
|
215
|
+
React__namespace.createElement(mosaic.Flex, { w: "full", flexDirection: "col", m: "auto", className: "sl-max-w-4xl" },
|
|
216
|
+
React__namespace.createElement(mosaic.Box, { w: "full", borderB: true },
|
|
217
|
+
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
|
+
groups.map(group => (React__namespace.createElement(Group, { key: group.title, group: group })))))));
|
|
241
219
|
};
|
|
242
220
|
const Group = React__namespace.memo(({ group }) => {
|
|
243
221
|
const [isExpanded, setIsExpanded] = React__namespace.useState(false);
|
|
244
|
-
const { hash } = reactRouterDom.useLocation();
|
|
245
222
|
const scrollRef = React__namespace.useRef(null);
|
|
223
|
+
const { location: { hash }, } = React__namespace.useContext(LocationContext);
|
|
246
224
|
const urlHashMatches = hash.substr(1) === group.title;
|
|
247
225
|
const onClick = React__namespace.useCallback(() => setIsExpanded(!isExpanded), [isExpanded]);
|
|
248
226
|
const shouldExpand = React__namespace.useMemo(() => {
|
|
@@ -266,7 +244,7 @@ const Group = React__namespace.memo(({ group }) => {
|
|
|
266
244
|
}))));
|
|
267
245
|
});
|
|
268
246
|
const Item = React__namespace.memo(({ item }) => {
|
|
269
|
-
const location =
|
|
247
|
+
const { location } = React__namespace.useContext(LocationContext);
|
|
270
248
|
const { hash } = location;
|
|
271
249
|
const [isExpanded, setIsExpanded] = React__namespace.useState(false);
|
|
272
250
|
const scrollRef = React__namespace.useRef(null);
|
|
@@ -306,6 +284,38 @@ const Collapse = ({ isOpen, children }) => {
|
|
|
306
284
|
return React__namespace.createElement(mosaic.Box, null, children);
|
|
307
285
|
};
|
|
308
286
|
|
|
287
|
+
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
288
|
+
const container = React__namespace.useRef(null);
|
|
289
|
+
const tree = React__namespace.useMemo(() => computeAPITree(serviceNode, { hideSchemas, hideInternal }), [serviceNode, hideSchemas, hideInternal]);
|
|
290
|
+
const location = reactRouterDom.useLocation();
|
|
291
|
+
const { pathname } = location;
|
|
292
|
+
const isRootPath = !pathname || pathname === '/';
|
|
293
|
+
const node = isRootPath ? serviceNode : serviceNode.children.find(child => child.uri === pathname);
|
|
294
|
+
const layoutOptions = React__namespace.useMemo(() => ({ hideTryIt: hideTryIt, hideExport: hideExport || (node === null || node === void 0 ? void 0 : node.type) !== types.NodeType.HttpService }), [hideTryIt, hideExport, node]);
|
|
295
|
+
if (!node) {
|
|
296
|
+
const firstSlug = findFirstNodeSlug(tree);
|
|
297
|
+
if (firstSlug) {
|
|
298
|
+
return React__namespace.createElement(reactRouterDom.Redirect, { to: firstSlug });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (hideInternal && node && isInternal(node)) {
|
|
302
|
+
return React__namespace.createElement(reactRouterDom.Redirect, { to: "/" });
|
|
303
|
+
}
|
|
304
|
+
const handleTocClick = () => {
|
|
305
|
+
if (container.current) {
|
|
306
|
+
container.current.scrollIntoView();
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
const sidebar = (React__namespace.createElement(React__namespace.Fragment, null,
|
|
310
|
+
React__namespace.createElement(mosaic.Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
311
|
+
logo ? (React__namespace.createElement(elementsCore.Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React__namespace.createElement(elementsCore.Logo, { logo: serviceNode.data.logo })),
|
|
312
|
+
React__namespace.createElement(mosaic.Heading, { size: 4 }, serviceNode.name)),
|
|
313
|
+
React__namespace.createElement(mosaic.Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
314
|
+
React__namespace.createElement(elementsCore.TableOfContents, { tree: tree, activeId: pathname, Link: reactRouterDom.Link, onLinkClick: handleTocClick })),
|
|
315
|
+
React__namespace.createElement(elementsCore.PoweredByLink, { source: serviceNode.name, pathname: pathname, packageType: "elements" })));
|
|
316
|
+
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 }))));
|
|
317
|
+
};
|
|
318
|
+
|
|
309
319
|
var NodeTypes;
|
|
310
320
|
(function (NodeTypes) {
|
|
311
321
|
NodeTypes["Paths"] = "paths";
|
|
@@ -519,6 +529,7 @@ const propsAreWithDocument = (props) => {
|
|
|
519
529
|
};
|
|
520
530
|
const APIImpl = props => {
|
|
521
531
|
const { layout, apiDescriptionUrl = '', logo, hideTryIt, hideSchemas, hideInternal, hideExport, tryItCredentialsPolicy, tryItCorsProxy, maxRefDepth, } = props;
|
|
532
|
+
const location = reactRouterDom.useLocation();
|
|
522
533
|
const apiDescriptionDocument = propsAreWithDocument(props) ? props.apiDescriptionDocument : undefined;
|
|
523
534
|
const { data: fetchedDocument, error } = reactQuery.useQuery([apiDescriptionUrl], () => fetch(apiDescriptionUrl).then(res => {
|
|
524
535
|
if (res.ok) {
|
|
@@ -545,10 +556,11 @@ const APIImpl = props => {
|
|
|
545
556
|
return (React__namespace.createElement(mosaic.Flex, { justify: "center", alignItems: "center", w: "full", minH: "screen" },
|
|
546
557
|
React__namespace.createElement(elementsCore.NonIdealState, { title: "Failed to parse OpenAPI file", description: "Please make sure your OpenAPI file is valid and try again" })));
|
|
547
558
|
}
|
|
548
|
-
return (React__namespace.createElement(elementsCore.InlineRefResolverProvider, { document: parsedDocument, maxRefDepth: maxRefDepth }, layout === 'stacked' ? (React__namespace.createElement(APIWithStackedLayout, { serviceNode: serviceNode, hideTryIt: hideTryIt, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy })) : (React__namespace.createElement(APIWithSidebarLayout, { logo: logo, serviceNode: serviceNode, hideTryIt: hideTryIt, hideSchemas: hideSchemas, hideInternal: hideInternal, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }))));
|
|
559
|
+
return (React__namespace.createElement(elementsCore.InlineRefResolverProvider, { document: parsedDocument, maxRefDepth: maxRefDepth }, layout === 'stacked' ? (React__namespace.createElement(APIWithStackedLayout, { serviceNode: serviceNode, hideTryIt: hideTryIt, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy, location: location })) : (React__namespace.createElement(APIWithSidebarLayout, { logo: logo, serviceNode: serviceNode, hideTryIt: hideTryIt, hideSchemas: hideSchemas, hideInternal: hideInternal, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }))));
|
|
549
560
|
};
|
|
550
561
|
const API = flow__default["default"](elementsCore.withRouter, elementsCore.withStyles, elementsCore.withPersistenceBoundary, elementsCore.withMosaicProvider, elementsCore.withQueryClientProvider)(APIImpl);
|
|
551
562
|
|
|
552
563
|
exports.API = API;
|
|
564
|
+
exports.APIWithStackedLayout = APIWithStackedLayout;
|
|
553
565
|
exports.transformOasToServiceNode = transformOasToServiceNode;
|
|
554
566
|
exports.useExportDocumentProps = useExportDocumentProps;
|
package/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { isHttpOperation, isHttpService,
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
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';
|
|
2
|
+
import { Box, Flex, Icon, Tabs, TabList, Tab, TabPanels, TabPanel, Heading } from '@stoplight/mosaic';
|
|
3
|
+
import { NodeType } from '@stoplight/types';
|
|
4
|
+
import cn from 'classnames';
|
|
4
5
|
import * as React from 'react';
|
|
6
|
+
import defaults from 'lodash/defaults.js';
|
|
7
|
+
import flow from 'lodash/flow.js';
|
|
5
8
|
import { useQuery } from 'react-query';
|
|
6
|
-
import { NodeType } from '@stoplight/types';
|
|
7
9
|
import { useLocation, Redirect, Link } from 'react-router-dom';
|
|
8
|
-
import defaults from 'lodash/defaults.js';
|
|
9
|
-
import cn from 'classnames';
|
|
10
10
|
import { safeStringify } from '@stoplight/yaml';
|
|
11
11
|
import saver from 'file-saver';
|
|
12
12
|
import { transformOas2Service, transformOas2Operation } from '@stoplight/http-spec/oas2';
|
|
@@ -157,59 +157,37 @@ const isInternal = (node) => {
|
|
|
157
157
|
return !!data['x-internal'];
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
161
|
-
const container = React.useRef(null);
|
|
162
|
-
const tree = React.useMemo(() => computeAPITree(serviceNode, { hideSchemas, hideInternal }), [serviceNode, hideSchemas, hideInternal]);
|
|
163
|
-
const location = useLocation();
|
|
164
|
-
const { pathname } = location;
|
|
165
|
-
const isRootPath = !pathname || pathname === '/';
|
|
166
|
-
const node = isRootPath ? serviceNode : serviceNode.children.find(child => child.uri === pathname);
|
|
167
|
-
const layoutOptions = React.useMemo(() => ({ hideTryIt: hideTryIt, hideExport: hideExport || (node === null || node === void 0 ? void 0 : node.type) !== NodeType.HttpService }), [hideTryIt, hideExport, node]);
|
|
168
|
-
if (!node) {
|
|
169
|
-
const firstSlug = findFirstNodeSlug(tree);
|
|
170
|
-
if (firstSlug) {
|
|
171
|
-
return React.createElement(Redirect, { to: firstSlug });
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (hideInternal && node && isInternal(node)) {
|
|
175
|
-
return React.createElement(Redirect, { to: "/" });
|
|
176
|
-
}
|
|
177
|
-
const handleTocClick = () => {
|
|
178
|
-
if (container.current) {
|
|
179
|
-
container.current.scrollIntoView();
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
const sidebar = (React.createElement(React.Fragment, null,
|
|
183
|
-
React.createElement(Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
184
|
-
logo ? (React.createElement(Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React.createElement(Logo, { logo: serviceNode.data.logo })),
|
|
185
|
-
React.createElement(Heading, { size: 4 }, serviceNode.name)),
|
|
186
|
-
React.createElement(Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
187
|
-
React.createElement(TableOfContents, { tree: tree, activeId: pathname, Link: Link, onLinkClick: handleTocClick })),
|
|
188
|
-
React.createElement(PoweredByLink, { source: serviceNode.name, pathname: pathname, packageType: "elements" })));
|
|
189
|
-
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 }))));
|
|
190
|
-
};
|
|
191
|
-
|
|
192
160
|
const itemMatchesHash = (hash, item) => {
|
|
193
|
-
return hash.substr(1) === `${item.
|
|
161
|
+
return hash.substr(1) === `${item.data.path}-${item.data.method}`;
|
|
194
162
|
};
|
|
195
163
|
const TryItContext = React.createContext({
|
|
196
164
|
hideTryIt: false,
|
|
197
165
|
tryItCredentialsPolicy: 'omit',
|
|
198
166
|
});
|
|
199
167
|
TryItContext.displayName = 'TryItContext';
|
|
200
|
-
const
|
|
201
|
-
|
|
168
|
+
const LocationContext = React.createContext({
|
|
169
|
+
location: {
|
|
170
|
+
hash: '',
|
|
171
|
+
key: '',
|
|
172
|
+
pathname: '',
|
|
173
|
+
search: '',
|
|
174
|
+
state: '',
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
LocationContext.displayName = 'LocationContext';
|
|
178
|
+
const APIWithStackedLayout = ({ serviceNode, hideTryIt, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, showPoweredByLink = true, location, }) => {
|
|
202
179
|
const { groups } = computeTagGroups(serviceNode);
|
|
203
|
-
return (React.createElement(
|
|
204
|
-
React.createElement(
|
|
205
|
-
React.createElement(
|
|
206
|
-
React.createElement(
|
|
207
|
-
|
|
180
|
+
return (React.createElement(LocationContext.Provider, { value: { location } },
|
|
181
|
+
React.createElement(TryItContext.Provider, { value: { hideTryIt, tryItCredentialsPolicy, corsProxy: tryItCorsProxy } },
|
|
182
|
+
React.createElement(Flex, { w: "full", flexDirection: "col", m: "auto", className: "sl-max-w-4xl" },
|
|
183
|
+
React.createElement(Box, { w: "full", borderB: true },
|
|
184
|
+
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 })))))));
|
|
208
186
|
};
|
|
209
187
|
const Group = React.memo(({ group }) => {
|
|
210
188
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
211
|
-
const { hash } = useLocation();
|
|
212
189
|
const scrollRef = React.useRef(null);
|
|
190
|
+
const { location: { hash }, } = React.useContext(LocationContext);
|
|
213
191
|
const urlHashMatches = hash.substr(1) === group.title;
|
|
214
192
|
const onClick = React.useCallback(() => setIsExpanded(!isExpanded), [isExpanded]);
|
|
215
193
|
const shouldExpand = React.useMemo(() => {
|
|
@@ -233,7 +211,7 @@ const Group = React.memo(({ group }) => {
|
|
|
233
211
|
}))));
|
|
234
212
|
});
|
|
235
213
|
const Item = React.memo(({ item }) => {
|
|
236
|
-
const location =
|
|
214
|
+
const { location } = React.useContext(LocationContext);
|
|
237
215
|
const { hash } = location;
|
|
238
216
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
239
217
|
const scrollRef = React.useRef(null);
|
|
@@ -273,6 +251,38 @@ const Collapse = ({ isOpen, children }) => {
|
|
|
273
251
|
return React.createElement(Box, null, children);
|
|
274
252
|
};
|
|
275
253
|
|
|
254
|
+
const APIWithSidebarLayout = ({ serviceNode, logo, hideTryIt, hideSchemas, hideInternal, hideExport, exportProps, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
255
|
+
const container = React.useRef(null);
|
|
256
|
+
const tree = React.useMemo(() => computeAPITree(serviceNode, { hideSchemas, hideInternal }), [serviceNode, hideSchemas, hideInternal]);
|
|
257
|
+
const location = useLocation();
|
|
258
|
+
const { pathname } = location;
|
|
259
|
+
const isRootPath = !pathname || pathname === '/';
|
|
260
|
+
const node = isRootPath ? serviceNode : serviceNode.children.find(child => child.uri === pathname);
|
|
261
|
+
const layoutOptions = React.useMemo(() => ({ hideTryIt: hideTryIt, hideExport: hideExport || (node === null || node === void 0 ? void 0 : node.type) !== NodeType.HttpService }), [hideTryIt, hideExport, node]);
|
|
262
|
+
if (!node) {
|
|
263
|
+
const firstSlug = findFirstNodeSlug(tree);
|
|
264
|
+
if (firstSlug) {
|
|
265
|
+
return React.createElement(Redirect, { to: firstSlug });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (hideInternal && node && isInternal(node)) {
|
|
269
|
+
return React.createElement(Redirect, { to: "/" });
|
|
270
|
+
}
|
|
271
|
+
const handleTocClick = () => {
|
|
272
|
+
if (container.current) {
|
|
273
|
+
container.current.scrollIntoView();
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
const sidebar = (React.createElement(React.Fragment, null,
|
|
277
|
+
React.createElement(Flex, { ml: 4, mb: 5, alignItems: "center" },
|
|
278
|
+
logo ? (React.createElement(Logo, { logo: { url: logo, altText: 'logo' } })) : (serviceNode.data.logo && React.createElement(Logo, { logo: serviceNode.data.logo })),
|
|
279
|
+
React.createElement(Heading, { size: 4 }, serviceNode.name)),
|
|
280
|
+
React.createElement(Flex, { flexGrow: true, flexShrink: true, overflowY: "auto", direction: "col" },
|
|
281
|
+
React.createElement(TableOfContents, { tree: tree, activeId: pathname, Link: Link, onLinkClick: handleTocClick })),
|
|
282
|
+
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
|
+
};
|
|
285
|
+
|
|
276
286
|
var NodeTypes;
|
|
277
287
|
(function (NodeTypes) {
|
|
278
288
|
NodeTypes["Paths"] = "paths";
|
|
@@ -486,6 +496,7 @@ const propsAreWithDocument = (props) => {
|
|
|
486
496
|
};
|
|
487
497
|
const APIImpl = props => {
|
|
488
498
|
const { layout, apiDescriptionUrl = '', logo, hideTryIt, hideSchemas, hideInternal, hideExport, tryItCredentialsPolicy, tryItCorsProxy, maxRefDepth, } = props;
|
|
499
|
+
const location = useLocation();
|
|
489
500
|
const apiDescriptionDocument = propsAreWithDocument(props) ? props.apiDescriptionDocument : undefined;
|
|
490
501
|
const { data: fetchedDocument, error } = useQuery([apiDescriptionUrl], () => fetch(apiDescriptionUrl).then(res => {
|
|
491
502
|
if (res.ok) {
|
|
@@ -512,8 +523,8 @@ const APIImpl = props => {
|
|
|
512
523
|
return (React.createElement(Flex, { justify: "center", alignItems: "center", w: "full", minH: "screen" },
|
|
513
524
|
React.createElement(NonIdealState, { title: "Failed to parse OpenAPI file", description: "Please make sure your OpenAPI file is valid and try again" })));
|
|
514
525
|
}
|
|
515
|
-
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 })) : (React.createElement(APIWithSidebarLayout, { logo: logo, serviceNode: serviceNode, hideTryIt: hideTryIt, hideSchemas: hideSchemas, hideInternal: hideInternal, hideExport: hideExport, exportProps: exportProps, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy }))));
|
|
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 }))));
|
|
516
527
|
};
|
|
517
528
|
const API = flow(withRouter, withStyles, withPersistenceBoundary, withMosaicProvider, withQueryClientProvider)(APIImpl);
|
|
518
529
|
|
|
519
|
-
export { API, transformOasToServiceNode, useExportDocumentProps };
|
|
530
|
+
export { API, APIWithStackedLayout, transformOasToServiceNode, useExportDocumentProps };
|