@stoplight/elements-dev-portal 2.5.1 → 3.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/index.esm.js +62 -46
- package/index.js +61 -45
- package/index.mjs +62 -46
- package/package.json +3 -3
- package/version.d.ts +1 -1
- package/web-components.min.js +1 -1
- package/web-components.min.js.LICENSE.txt +30 -6
package/index.esm.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Menu, FieldButton, Modal, Input, Box, Icon, ListBox, ListBoxItem, Flex, VStack, Heading } from '@stoplight/mosaic';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default, { useRef, useEffect, useMemo, useCallback, useState } from 'react';
|
|
4
|
-
import { withPersistenceBoundary, withQueryClientProvider, withMosaicProvider, MarkdownComponentsProvider, LinkHeading, MockingProvider, Docs, withStyles, NodeTypeIconDefs, NodeTypeColors, TableOfContents as TableOfContents$1, PoweredByLink, useRouter,
|
|
4
|
+
import { withPersistenceBoundary, withQueryClientProvider, withMosaicProvider, MarkdownComponentsProvider, LinkHeading, MockingProvider, Docs, RouterTypeContext, withStyles, NodeTypeIconDefs, NodeTypeColors, TableOfContents as TableOfContents$1, PoweredByLink, useRouter, findFirstNode, SidebarLayout, ScrollToHashElement, ReactRouterMarkdownLink } from '@stoplight/elements-core';
|
|
5
5
|
import { resolve, dirname } from '@stoplight/path';
|
|
6
6
|
import { NodeType } from '@stoplight/types';
|
|
7
|
+
import { useLocation, useInRouterContext, Routes, Route, useParams, useNavigate, Navigate, Link, Outlet, useOutletContext } from 'react-router-dom';
|
|
7
8
|
import flow from 'lodash/flow.js';
|
|
8
|
-
import { Switch, Route, useParams, useHistory, Redirect, Link } from 'react-router-dom';
|
|
9
9
|
import { useQuery } from 'react-query';
|
|
10
10
|
|
|
11
11
|
const BranchSelector = ({ branchSlug, branches, onChange }) => {
|
|
@@ -125,6 +125,9 @@ const NodeLinkContext = React.createContext(undefined);
|
|
|
125
125
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
126
126
|
const LinkComponent = ({ children, href, title }) => {
|
|
127
127
|
const ctx = React.useContext(NodeLinkContext);
|
|
128
|
+
const routerKind = React.useContext(RouterTypeContext);
|
|
129
|
+
const { pathname } = useLocation();
|
|
130
|
+
const route = pathname.split('#')[0];
|
|
128
131
|
try {
|
|
129
132
|
if (href && externalRegex.test(href)) {
|
|
130
133
|
const baseURL = window.location.host;
|
|
@@ -152,15 +155,18 @@ const LinkComponent = ({ children, href, title }) => {
|
|
|
152
155
|
const [resolvedUriWithoutAnchor, hash] = resolvedUri.split('#');
|
|
153
156
|
const decodedUrl = decodeURIComponent(href);
|
|
154
157
|
const decodedResolvedUriWithoutAnchor = decodeURIComponent(resolvedUriWithoutAnchor);
|
|
155
|
-
const [pagePathWithoutHash] =
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
pagePathWithoutHash === `/${edge.slug}`);
|
|
158
|
+
const [pagePathWithoutHash] = pathname.split('#');
|
|
159
|
+
let edge = node.outbound_edges.find(edge => edge.uri === decodedUrl || edge.uri === decodedResolvedUriWithoutAnchor);
|
|
160
|
+
if (!edge) {
|
|
161
|
+
edge = node.outbound_edges.find(edge => pagePathWithoutHash === `/${edge.slug}`);
|
|
162
|
+
}
|
|
159
163
|
if (edge) {
|
|
160
|
-
|
|
164
|
+
const slug = routerKind === 'hash' ? `#${route.replace(node.slug, edge.slug)}` : edge.slug;
|
|
165
|
+
return React.createElement(Link, { to: `${slug}${hash ? `#${hash}` : ''}` }, children);
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
|
-
|
|
168
|
+
const fullHref = routerKind === 'hash' ? `#${route}${href}` : href;
|
|
169
|
+
return React.createElement("a", { href: fullHref }, children);
|
|
164
170
|
};
|
|
165
171
|
function getBundledUrl(url) {
|
|
166
172
|
if (url === undefined)
|
|
@@ -286,7 +292,7 @@ const UpgradeToStarter = () => (React__default.createElement(Flex, { as: "a", hr
|
|
|
286
292
|
React__default.createElement(Icon, { icon: ['fas', 'exclamation-triangle'], size: "4x" }),
|
|
287
293
|
React__default.createElement(Box, { pt: 3 }, "Please upgrade your Stoplight Workspace to the Starter Plan to use Elements Dev Portal in production.")));
|
|
288
294
|
|
|
289
|
-
const appVersion = '
|
|
295
|
+
const appVersion = '3.0.0';
|
|
290
296
|
|
|
291
297
|
class ResponseError extends Error {
|
|
292
298
|
constructor(message, responseCode) {
|
|
@@ -361,10 +367,10 @@ function useGetTableOfContents({ projectId, branchSlug }) {
|
|
|
361
367
|
return useQuery([...devPortalCacheKeys.branchTOC(projectId, branchSlug !== null && branchSlug !== void 0 ? branchSlug : ''), platformUrl, isLoggedIn], () => getTableOfContents({ projectId, branchSlug, platformUrl, platformAuthToken }), { enabled: projectId ? true : false });
|
|
362
368
|
}
|
|
363
369
|
|
|
364
|
-
const StoplightProjectImpl = ({ projectId,
|
|
370
|
+
const StoplightProjectImpl = ({ projectId, collapseTableOfContents = false }) => {
|
|
365
371
|
const { branchSlug: encodedBranchSlug = '', nodeSlug = '' } = useParams();
|
|
366
372
|
const branchSlug = decodeURIComponent(encodedBranchSlug);
|
|
367
|
-
const
|
|
373
|
+
const navigate = useNavigate();
|
|
368
374
|
const { data: tableOfContents, isFetched: isTocFetched } = useGetTableOfContents({ projectId, branchSlug });
|
|
369
375
|
const { data: branches } = useGetBranches({ projectId });
|
|
370
376
|
const { data: node, isLoading: isLoadingNode, isError, error: nodeError, } = useGetNodeContent({
|
|
@@ -376,63 +382,73 @@ const StoplightProjectImpl = ({ projectId, hideTryIt, hideSecurityInfo, hideServ
|
|
|
376
382
|
if (!nodeSlug && isTocFetched && (tableOfContents === null || tableOfContents === void 0 ? void 0 : tableOfContents.items)) {
|
|
377
383
|
const firstNode = findFirstNode(tableOfContents.items);
|
|
378
384
|
if (firstNode) {
|
|
379
|
-
return React.createElement(
|
|
385
|
+
return React.createElement(Navigate, { to: branchSlug ? `branches/${branchSlug}/${firstNode.slug}` : `${firstNode.slug}`, replace: true });
|
|
380
386
|
}
|
|
381
387
|
}
|
|
382
|
-
|
|
388
|
+
const handleTocClick = () => {
|
|
389
|
+
if (container.current) {
|
|
390
|
+
container.current.scrollIntoView();
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
return (React.createElement(SidebarLayout, { ref: container, sidebar: React.createElement(React.Fragment, null,
|
|
394
|
+
branches && branches.items.length > 1 ? (React.createElement(BranchSelector, { branchSlug: branchSlug, branches: branches.items, onChange: branch => {
|
|
395
|
+
const encodedBranchSlug = encodeURIComponent(branch.slug);
|
|
396
|
+
navigate(branch.is_default ? `${nodeSlug}` : `branches/${encodedBranchSlug}/${nodeSlug}`);
|
|
397
|
+
} })) : null,
|
|
398
|
+
tableOfContents ? (React.createElement(TableOfContents, { activeId: (node === null || node === void 0 ? void 0 : node.id) || (nodeSlug === null || nodeSlug === void 0 ? void 0 : nodeSlug.split('-')[0]) || '', tableOfContents: tableOfContents, Link: Link, collapseTableOfContents: collapseTableOfContents, onLinkClick: handleTocClick })) : null) },
|
|
399
|
+
React.createElement(Outlet, { context: [isLoadingNode, isTocFetched, isError, nodeError, node] })));
|
|
400
|
+
};
|
|
401
|
+
const ProjectNode = ({ hideTryIt, hideSecurityInfo, hideServerInfo, hideMocking, hideExport, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
402
|
+
const { branchSlug: encodedBranchSlug = '', nodeSlug = '' } = useParams();
|
|
403
|
+
const branchSlug = decodeURIComponent(encodedBranchSlug);
|
|
404
|
+
const [isLoadingNode, isTocFetched, isError, nodeError, node] = useOutletContext();
|
|
383
405
|
if (isLoadingNode || !isTocFetched) {
|
|
384
|
-
|
|
406
|
+
return React.createElement(Loading, null);
|
|
385
407
|
}
|
|
386
|
-
|
|
408
|
+
if (isError) {
|
|
387
409
|
if (nodeError instanceof ResponseError) {
|
|
388
410
|
if (nodeError.code === 402) {
|
|
389
|
-
|
|
411
|
+
return React.createElement(UpgradeToStarter, null);
|
|
390
412
|
}
|
|
391
413
|
else if (nodeError.code === 403) {
|
|
392
|
-
|
|
414
|
+
return React.createElement(Forbidden, null);
|
|
393
415
|
}
|
|
394
416
|
else {
|
|
395
|
-
|
|
417
|
+
return React.createElement(NotFound, null);
|
|
396
418
|
}
|
|
397
419
|
}
|
|
398
420
|
else {
|
|
399
|
-
|
|
421
|
+
return React.createElement(NotFound, null);
|
|
400
422
|
}
|
|
401
423
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
else if ((node === null || node === void 0 ? void 0 : node.slug) && nodeSlug !== node.slug) {
|
|
406
|
-
return React.createElement(Redirect, { to: branchSlug ? `/branches/${branchSlug}/${node.slug}` : `/${node.slug}` });
|
|
424
|
+
if (!node) {
|
|
425
|
+
return React.createElement(NotFound, null);
|
|
407
426
|
}
|
|
408
|
-
|
|
409
|
-
|
|
427
|
+
if ((node === null || node === void 0 ? void 0 : node.slug) && nodeSlug !== node.slug) {
|
|
428
|
+
return React.createElement(Navigate, { to: branchSlug ? `/branches/${branchSlug}/${node.slug}` : `/${node.slug}`, replace: true });
|
|
410
429
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
return (React.createElement(SidebarLayout, { ref: container, sidebar: React.createElement(React.Fragment, null,
|
|
417
|
-
branches && branches.items.length > 1 ? (React.createElement(BranchSelector, { branchSlug: branchSlug, branches: branches.items, onChange: branch => {
|
|
418
|
-
const encodedBranchSlug = encodeURIComponent(branch.slug);
|
|
419
|
-
history.push(branch.is_default ? `/${nodeSlug}` : `/branches/${encodedBranchSlug}/${nodeSlug}`);
|
|
420
|
-
} })) : null,
|
|
421
|
-
tableOfContents ? (React.createElement(TableOfContents, { activeId: (node === null || node === void 0 ? void 0 : node.id) || (nodeSlug === null || nodeSlug === void 0 ? void 0 : nodeSlug.split('-')[0]) || '', tableOfContents: tableOfContents, Link: Link, collapseTableOfContents: collapseTableOfContents, onLinkClick: handleTocClick })) : null) }, elem));
|
|
430
|
+
return (React.createElement(React.Fragment, null,
|
|
431
|
+
React.createElement(ScrollToHashElement, null),
|
|
432
|
+
React.createElement(NodeContent, { node: node, Link: ReactRouterMarkdownLink, hideTryIt: hideTryIt, hideMocking: hideMocking, hideExport: hideExport, hideSecurityInfo: hideSecurityInfo, hideServerInfo: hideServerInfo, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy })));
|
|
422
433
|
};
|
|
423
434
|
const StoplightProjectRouter = (_a) => {
|
|
424
|
-
var { platformUrl, basePath = '/', staticRouterPath = '', router = '
|
|
435
|
+
var { platformUrl, basePath = '/', staticRouterPath = '', router = 'hash' } = _a, props = __rest(_a, ["platformUrl", "basePath", "staticRouterPath", "router"]);
|
|
425
436
|
const { Router, routerProps } = useRouter(router, basePath, staticRouterPath);
|
|
437
|
+
const outerRouter = useInRouterContext();
|
|
438
|
+
const InternalRoutes = () => (React.createElement(Routes, null,
|
|
439
|
+
React.createElement(Route, { path: "/", element: React.createElement(StoplightProjectImpl, Object.assign({}, props)) },
|
|
440
|
+
React.createElement(Route, { path: "/branches/:branchSlug/:nodeSlug/*", element: React.createElement(ProjectNode, Object.assign({}, props)) }),
|
|
441
|
+
React.createElement(Route, { path: "/:nodeSlug/*", element: React.createElement(ProjectNode, Object.assign({}, props)) }),
|
|
442
|
+
React.createElement(Route, { element: React.createElement(ProjectNode, Object.assign({}, props)) }))));
|
|
443
|
+
if (!outerRouter) {
|
|
444
|
+
return (React.createElement(DevPortalProvider, { platformUrl: platformUrl },
|
|
445
|
+
React.createElement(RouterTypeContext.Provider, { value: router },
|
|
446
|
+
React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
447
|
+
React.createElement(InternalRoutes, null)))));
|
|
448
|
+
}
|
|
426
449
|
return (React.createElement(DevPortalProvider, { platformUrl: platformUrl },
|
|
427
450
|
React.createElement(RouterTypeContext.Provider, { value: router },
|
|
428
|
-
React.createElement(
|
|
429
|
-
React.createElement(Switch, null,
|
|
430
|
-
React.createElement(Route, { path: "/branches/:branchSlug/:nodeSlug+", exact: true },
|
|
431
|
-
React.createElement(StoplightProjectImpl, Object.assign({}, props))),
|
|
432
|
-
React.createElement(Route, { path: "/:nodeSlug+", exact: true },
|
|
433
|
-
React.createElement(StoplightProjectImpl, Object.assign({}, props))),
|
|
434
|
-
React.createElement(Route, { path: "/", exact: true },
|
|
435
|
-
React.createElement(StoplightProjectImpl, Object.assign({}, props))))))));
|
|
451
|
+
React.createElement(InternalRoutes, null))));
|
|
436
452
|
};
|
|
437
453
|
const StoplightProject = withStyles(StoplightProjectRouter);
|
|
438
454
|
|
package/index.js
CHANGED
|
@@ -5,8 +5,8 @@ var React = require('react');
|
|
|
5
5
|
var elementsCore = require('@stoplight/elements-core');
|
|
6
6
|
var path = require('@stoplight/path');
|
|
7
7
|
var types = require('@stoplight/types');
|
|
8
|
-
var flow = require('lodash/flow.js');
|
|
9
8
|
var reactRouterDom = require('react-router-dom');
|
|
9
|
+
var flow = require('lodash/flow.js');
|
|
10
10
|
var reactQuery = require('react-query');
|
|
11
11
|
|
|
12
12
|
function _interopNamespaceDefault(e) {
|
|
@@ -145,6 +145,9 @@ const NodeLinkContext = React__namespace.createContext(undefined);
|
|
|
145
145
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
146
146
|
const LinkComponent = ({ children, href, title }) => {
|
|
147
147
|
const ctx = React__namespace.useContext(NodeLinkContext);
|
|
148
|
+
const routerKind = React__namespace.useContext(elementsCore.RouterTypeContext);
|
|
149
|
+
const { pathname } = reactRouterDom.useLocation();
|
|
150
|
+
const route = pathname.split('#')[0];
|
|
148
151
|
try {
|
|
149
152
|
if (href && externalRegex.test(href)) {
|
|
150
153
|
const baseURL = window.location.host;
|
|
@@ -172,15 +175,18 @@ const LinkComponent = ({ children, href, title }) => {
|
|
|
172
175
|
const [resolvedUriWithoutAnchor, hash] = resolvedUri.split('#');
|
|
173
176
|
const decodedUrl = decodeURIComponent(href);
|
|
174
177
|
const decodedResolvedUriWithoutAnchor = decodeURIComponent(resolvedUriWithoutAnchor);
|
|
175
|
-
const [pagePathWithoutHash] =
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
pagePathWithoutHash === `/${edge.slug}`);
|
|
178
|
+
const [pagePathWithoutHash] = pathname.split('#');
|
|
179
|
+
let edge = node.outbound_edges.find(edge => edge.uri === decodedUrl || edge.uri === decodedResolvedUriWithoutAnchor);
|
|
180
|
+
if (!edge) {
|
|
181
|
+
edge = node.outbound_edges.find(edge => pagePathWithoutHash === `/${edge.slug}`);
|
|
182
|
+
}
|
|
179
183
|
if (edge) {
|
|
180
|
-
|
|
184
|
+
const slug = routerKind === 'hash' ? `#${route.replace(node.slug, edge.slug)}` : edge.slug;
|
|
185
|
+
return React__namespace.createElement(Link, { to: `${slug}${hash ? `#${hash}` : ''}` }, children);
|
|
181
186
|
}
|
|
182
187
|
}
|
|
183
|
-
|
|
188
|
+
const fullHref = routerKind === 'hash' ? `#${route}${href}` : href;
|
|
189
|
+
return React__namespace.createElement("a", { href: fullHref }, children);
|
|
184
190
|
};
|
|
185
191
|
function getBundledUrl(url) {
|
|
186
192
|
if (url === undefined)
|
|
@@ -306,7 +312,7 @@ const UpgradeToStarter = () => (React.createElement(mosaic.Flex, { as: "a", href
|
|
|
306
312
|
React.createElement(mosaic.Icon, { icon: ['fas', 'exclamation-triangle'], size: "4x" }),
|
|
307
313
|
React.createElement(mosaic.Box, { pt: 3 }, "Please upgrade your Stoplight Workspace to the Starter Plan to use Elements Dev Portal in production.")));
|
|
308
314
|
|
|
309
|
-
const appVersion = '
|
|
315
|
+
const appVersion = '3.0.0';
|
|
310
316
|
|
|
311
317
|
class ResponseError extends Error {
|
|
312
318
|
constructor(message, responseCode) {
|
|
@@ -381,10 +387,10 @@ function useGetTableOfContents({ projectId, branchSlug }) {
|
|
|
381
387
|
return reactQuery.useQuery([...devPortalCacheKeys.branchTOC(projectId, branchSlug !== null && branchSlug !== void 0 ? branchSlug : ''), platformUrl, isLoggedIn], () => getTableOfContents({ projectId, branchSlug, platformUrl, platformAuthToken }), { enabled: projectId ? true : false });
|
|
382
388
|
}
|
|
383
389
|
|
|
384
|
-
const StoplightProjectImpl = ({ projectId,
|
|
390
|
+
const StoplightProjectImpl = ({ projectId, collapseTableOfContents = false }) => {
|
|
385
391
|
const { branchSlug: encodedBranchSlug = '', nodeSlug = '' } = reactRouterDom.useParams();
|
|
386
392
|
const branchSlug = decodeURIComponent(encodedBranchSlug);
|
|
387
|
-
const
|
|
393
|
+
const navigate = reactRouterDom.useNavigate();
|
|
388
394
|
const { data: tableOfContents, isFetched: isTocFetched } = useGetTableOfContents({ projectId, branchSlug });
|
|
389
395
|
const { data: branches } = useGetBranches({ projectId });
|
|
390
396
|
const { data: node, isLoading: isLoadingNode, isError, error: nodeError, } = useGetNodeContent({
|
|
@@ -396,63 +402,73 @@ const StoplightProjectImpl = ({ projectId, hideTryIt, hideSecurityInfo, hideServ
|
|
|
396
402
|
if (!nodeSlug && isTocFetched && (tableOfContents === null || tableOfContents === void 0 ? void 0 : tableOfContents.items)) {
|
|
397
403
|
const firstNode = elementsCore.findFirstNode(tableOfContents.items);
|
|
398
404
|
if (firstNode) {
|
|
399
|
-
return React__namespace.createElement(reactRouterDom.
|
|
405
|
+
return React__namespace.createElement(reactRouterDom.Navigate, { to: branchSlug ? `branches/${branchSlug}/${firstNode.slug}` : `${firstNode.slug}`, replace: true });
|
|
400
406
|
}
|
|
401
407
|
}
|
|
402
|
-
|
|
408
|
+
const handleTocClick = () => {
|
|
409
|
+
if (container.current) {
|
|
410
|
+
container.current.scrollIntoView();
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
return (React__namespace.createElement(elementsCore.SidebarLayout, { ref: container, sidebar: React__namespace.createElement(React__namespace.Fragment, null,
|
|
414
|
+
branches && branches.items.length > 1 ? (React__namespace.createElement(BranchSelector, { branchSlug: branchSlug, branches: branches.items, onChange: branch => {
|
|
415
|
+
const encodedBranchSlug = encodeURIComponent(branch.slug);
|
|
416
|
+
navigate(branch.is_default ? `${nodeSlug}` : `branches/${encodedBranchSlug}/${nodeSlug}`);
|
|
417
|
+
} })) : null,
|
|
418
|
+
tableOfContents ? (React__namespace.createElement(TableOfContents, { activeId: (node === null || node === void 0 ? void 0 : node.id) || (nodeSlug === null || nodeSlug === void 0 ? void 0 : nodeSlug.split('-')[0]) || '', tableOfContents: tableOfContents, Link: reactRouterDom.Link, collapseTableOfContents: collapseTableOfContents, onLinkClick: handleTocClick })) : null) },
|
|
419
|
+
React__namespace.createElement(reactRouterDom.Outlet, { context: [isLoadingNode, isTocFetched, isError, nodeError, node] })));
|
|
420
|
+
};
|
|
421
|
+
const ProjectNode = ({ hideTryIt, hideSecurityInfo, hideServerInfo, hideMocking, hideExport, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
422
|
+
const { branchSlug: encodedBranchSlug = '', nodeSlug = '' } = reactRouterDom.useParams();
|
|
423
|
+
const branchSlug = decodeURIComponent(encodedBranchSlug);
|
|
424
|
+
const [isLoadingNode, isTocFetched, isError, nodeError, node] = reactRouterDom.useOutletContext();
|
|
403
425
|
if (isLoadingNode || !isTocFetched) {
|
|
404
|
-
|
|
426
|
+
return React__namespace.createElement(Loading, null);
|
|
405
427
|
}
|
|
406
|
-
|
|
428
|
+
if (isError) {
|
|
407
429
|
if (nodeError instanceof ResponseError) {
|
|
408
430
|
if (nodeError.code === 402) {
|
|
409
|
-
|
|
431
|
+
return React__namespace.createElement(UpgradeToStarter, null);
|
|
410
432
|
}
|
|
411
433
|
else if (nodeError.code === 403) {
|
|
412
|
-
|
|
434
|
+
return React__namespace.createElement(Forbidden, null);
|
|
413
435
|
}
|
|
414
436
|
else {
|
|
415
|
-
|
|
437
|
+
return React__namespace.createElement(NotFound, null);
|
|
416
438
|
}
|
|
417
439
|
}
|
|
418
440
|
else {
|
|
419
|
-
|
|
441
|
+
return React__namespace.createElement(NotFound, null);
|
|
420
442
|
}
|
|
421
443
|
}
|
|
422
|
-
|
|
423
|
-
|
|
444
|
+
if (!node) {
|
|
445
|
+
return React__namespace.createElement(NotFound, null);
|
|
424
446
|
}
|
|
425
|
-
|
|
426
|
-
return React__namespace.createElement(reactRouterDom.
|
|
447
|
+
if ((node === null || node === void 0 ? void 0 : node.slug) && nodeSlug !== node.slug) {
|
|
448
|
+
return React__namespace.createElement(reactRouterDom.Navigate, { to: branchSlug ? `/branches/${branchSlug}/${node.slug}` : `/${node.slug}`, replace: true });
|
|
427
449
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const handleTocClick = () => {
|
|
432
|
-
if (container.current) {
|
|
433
|
-
container.current.scrollIntoView();
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
return (React__namespace.createElement(elementsCore.SidebarLayout, { ref: container, sidebar: React__namespace.createElement(React__namespace.Fragment, null,
|
|
437
|
-
branches && branches.items.length > 1 ? (React__namespace.createElement(BranchSelector, { branchSlug: branchSlug, branches: branches.items, onChange: branch => {
|
|
438
|
-
const encodedBranchSlug = encodeURIComponent(branch.slug);
|
|
439
|
-
history.push(branch.is_default ? `/${nodeSlug}` : `/branches/${encodedBranchSlug}/${nodeSlug}`);
|
|
440
|
-
} })) : null,
|
|
441
|
-
tableOfContents ? (React__namespace.createElement(TableOfContents, { activeId: (node === null || node === void 0 ? void 0 : node.id) || (nodeSlug === null || nodeSlug === void 0 ? void 0 : nodeSlug.split('-')[0]) || '', tableOfContents: tableOfContents, Link: reactRouterDom.Link, collapseTableOfContents: collapseTableOfContents, onLinkClick: handleTocClick })) : null) }, elem));
|
|
450
|
+
return (React__namespace.createElement(React__namespace.Fragment, null,
|
|
451
|
+
React__namespace.createElement(elementsCore.ScrollToHashElement, null),
|
|
452
|
+
React__namespace.createElement(NodeContent, { node: node, Link: elementsCore.ReactRouterMarkdownLink, hideTryIt: hideTryIt, hideMocking: hideMocking, hideExport: hideExport, hideSecurityInfo: hideSecurityInfo, hideServerInfo: hideServerInfo, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy })));
|
|
442
453
|
};
|
|
443
454
|
const StoplightProjectRouter = (_a) => {
|
|
444
|
-
var { platformUrl, basePath = '/', staticRouterPath = '', router = '
|
|
455
|
+
var { platformUrl, basePath = '/', staticRouterPath = '', router = 'hash' } = _a, props = __rest(_a, ["platformUrl", "basePath", "staticRouterPath", "router"]);
|
|
445
456
|
const { Router, routerProps } = elementsCore.useRouter(router, basePath, staticRouterPath);
|
|
457
|
+
const outerRouter = reactRouterDom.useInRouterContext();
|
|
458
|
+
const InternalRoutes = () => (React__namespace.createElement(reactRouterDom.Routes, null,
|
|
459
|
+
React__namespace.createElement(reactRouterDom.Route, { path: "/", element: React__namespace.createElement(StoplightProjectImpl, Object.assign({}, props)) },
|
|
460
|
+
React__namespace.createElement(reactRouterDom.Route, { path: "/branches/:branchSlug/:nodeSlug/*", element: React__namespace.createElement(ProjectNode, Object.assign({}, props)) }),
|
|
461
|
+
React__namespace.createElement(reactRouterDom.Route, { path: "/:nodeSlug/*", element: React__namespace.createElement(ProjectNode, Object.assign({}, props)) }),
|
|
462
|
+
React__namespace.createElement(reactRouterDom.Route, { element: React__namespace.createElement(ProjectNode, Object.assign({}, props)) }))));
|
|
463
|
+
if (!outerRouter) {
|
|
464
|
+
return (React__namespace.createElement(DevPortalProvider, { platformUrl: platformUrl },
|
|
465
|
+
React__namespace.createElement(elementsCore.RouterTypeContext.Provider, { value: router },
|
|
466
|
+
React__namespace.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
467
|
+
React__namespace.createElement(InternalRoutes, null)))));
|
|
468
|
+
}
|
|
446
469
|
return (React__namespace.createElement(DevPortalProvider, { platformUrl: platformUrl },
|
|
447
470
|
React__namespace.createElement(elementsCore.RouterTypeContext.Provider, { value: router },
|
|
448
|
-
React__namespace.createElement(
|
|
449
|
-
React__namespace.createElement(reactRouterDom.Switch, null,
|
|
450
|
-
React__namespace.createElement(reactRouterDom.Route, { path: "/branches/:branchSlug/:nodeSlug+", exact: true },
|
|
451
|
-
React__namespace.createElement(StoplightProjectImpl, Object.assign({}, props))),
|
|
452
|
-
React__namespace.createElement(reactRouterDom.Route, { path: "/:nodeSlug+", exact: true },
|
|
453
|
-
React__namespace.createElement(StoplightProjectImpl, Object.assign({}, props))),
|
|
454
|
-
React__namespace.createElement(reactRouterDom.Route, { path: "/", exact: true },
|
|
455
|
-
React__namespace.createElement(StoplightProjectImpl, Object.assign({}, props))))))));
|
|
471
|
+
React__namespace.createElement(InternalRoutes, null))));
|
|
456
472
|
};
|
|
457
473
|
const StoplightProject = elementsCore.withStyles(StoplightProjectRouter);
|
|
458
474
|
|
package/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Menu, FieldButton, Modal, Input, Box, Icon, ListBox, ListBoxItem, Flex, VStack, Heading } from '@stoplight/mosaic';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default, { useRef, useEffect, useMemo, useCallback, useState } from 'react';
|
|
4
|
-
import { withPersistenceBoundary, withQueryClientProvider, withMosaicProvider, MarkdownComponentsProvider, LinkHeading, MockingProvider, Docs, withStyles, NodeTypeIconDefs, NodeTypeColors, TableOfContents as TableOfContents$1, PoweredByLink, useRouter,
|
|
4
|
+
import { withPersistenceBoundary, withQueryClientProvider, withMosaicProvider, MarkdownComponentsProvider, LinkHeading, MockingProvider, Docs, RouterTypeContext, withStyles, NodeTypeIconDefs, NodeTypeColors, TableOfContents as TableOfContents$1, PoweredByLink, useRouter, findFirstNode, SidebarLayout, ScrollToHashElement, ReactRouterMarkdownLink } from '@stoplight/elements-core';
|
|
5
5
|
import { resolve, dirname } from '@stoplight/path';
|
|
6
6
|
import { NodeType } from '@stoplight/types';
|
|
7
|
+
import { useLocation, useInRouterContext, Routes, Route, useParams, useNavigate, Navigate, Link, Outlet, useOutletContext } from 'react-router-dom';
|
|
7
8
|
import flow from 'lodash/flow.js';
|
|
8
|
-
import { Switch, Route, useParams, useHistory, Redirect, Link } from 'react-router-dom';
|
|
9
9
|
import { useQuery } from 'react-query';
|
|
10
10
|
|
|
11
11
|
const BranchSelector = ({ branchSlug, branches, onChange }) => {
|
|
@@ -125,6 +125,9 @@ const NodeLinkContext = React.createContext(undefined);
|
|
|
125
125
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
126
126
|
const LinkComponent = ({ children, href, title }) => {
|
|
127
127
|
const ctx = React.useContext(NodeLinkContext);
|
|
128
|
+
const routerKind = React.useContext(RouterTypeContext);
|
|
129
|
+
const { pathname } = useLocation();
|
|
130
|
+
const route = pathname.split('#')[0];
|
|
128
131
|
try {
|
|
129
132
|
if (href && externalRegex.test(href)) {
|
|
130
133
|
const baseURL = window.location.host;
|
|
@@ -152,15 +155,18 @@ const LinkComponent = ({ children, href, title }) => {
|
|
|
152
155
|
const [resolvedUriWithoutAnchor, hash] = resolvedUri.split('#');
|
|
153
156
|
const decodedUrl = decodeURIComponent(href);
|
|
154
157
|
const decodedResolvedUriWithoutAnchor = decodeURIComponent(resolvedUriWithoutAnchor);
|
|
155
|
-
const [pagePathWithoutHash] =
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
pagePathWithoutHash === `/${edge.slug}`);
|
|
158
|
+
const [pagePathWithoutHash] = pathname.split('#');
|
|
159
|
+
let edge = node.outbound_edges.find(edge => edge.uri === decodedUrl || edge.uri === decodedResolvedUriWithoutAnchor);
|
|
160
|
+
if (!edge) {
|
|
161
|
+
edge = node.outbound_edges.find(edge => pagePathWithoutHash === `/${edge.slug}`);
|
|
162
|
+
}
|
|
159
163
|
if (edge) {
|
|
160
|
-
|
|
164
|
+
const slug = routerKind === 'hash' ? `#${route.replace(node.slug, edge.slug)}` : edge.slug;
|
|
165
|
+
return React.createElement(Link, { to: `${slug}${hash ? `#${hash}` : ''}` }, children);
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
|
-
|
|
168
|
+
const fullHref = routerKind === 'hash' ? `#${route}${href}` : href;
|
|
169
|
+
return React.createElement("a", { href: fullHref }, children);
|
|
164
170
|
};
|
|
165
171
|
function getBundledUrl(url) {
|
|
166
172
|
if (url === undefined)
|
|
@@ -286,7 +292,7 @@ const UpgradeToStarter = () => (React__default.createElement(Flex, { as: "a", hr
|
|
|
286
292
|
React__default.createElement(Icon, { icon: ['fas', 'exclamation-triangle'], size: "4x" }),
|
|
287
293
|
React__default.createElement(Box, { pt: 3 }, "Please upgrade your Stoplight Workspace to the Starter Plan to use Elements Dev Portal in production.")));
|
|
288
294
|
|
|
289
|
-
const appVersion = '
|
|
295
|
+
const appVersion = '3.0.0';
|
|
290
296
|
|
|
291
297
|
class ResponseError extends Error {
|
|
292
298
|
constructor(message, responseCode) {
|
|
@@ -361,10 +367,10 @@ function useGetTableOfContents({ projectId, branchSlug }) {
|
|
|
361
367
|
return useQuery([...devPortalCacheKeys.branchTOC(projectId, branchSlug !== null && branchSlug !== void 0 ? branchSlug : ''), platformUrl, isLoggedIn], () => getTableOfContents({ projectId, branchSlug, platformUrl, platformAuthToken }), { enabled: projectId ? true : false });
|
|
362
368
|
}
|
|
363
369
|
|
|
364
|
-
const StoplightProjectImpl = ({ projectId,
|
|
370
|
+
const StoplightProjectImpl = ({ projectId, collapseTableOfContents = false }) => {
|
|
365
371
|
const { branchSlug: encodedBranchSlug = '', nodeSlug = '' } = useParams();
|
|
366
372
|
const branchSlug = decodeURIComponent(encodedBranchSlug);
|
|
367
|
-
const
|
|
373
|
+
const navigate = useNavigate();
|
|
368
374
|
const { data: tableOfContents, isFetched: isTocFetched } = useGetTableOfContents({ projectId, branchSlug });
|
|
369
375
|
const { data: branches } = useGetBranches({ projectId });
|
|
370
376
|
const { data: node, isLoading: isLoadingNode, isError, error: nodeError, } = useGetNodeContent({
|
|
@@ -376,63 +382,73 @@ const StoplightProjectImpl = ({ projectId, hideTryIt, hideSecurityInfo, hideServ
|
|
|
376
382
|
if (!nodeSlug && isTocFetched && (tableOfContents === null || tableOfContents === void 0 ? void 0 : tableOfContents.items)) {
|
|
377
383
|
const firstNode = findFirstNode(tableOfContents.items);
|
|
378
384
|
if (firstNode) {
|
|
379
|
-
return React.createElement(
|
|
385
|
+
return React.createElement(Navigate, { to: branchSlug ? `branches/${branchSlug}/${firstNode.slug}` : `${firstNode.slug}`, replace: true });
|
|
380
386
|
}
|
|
381
387
|
}
|
|
382
|
-
|
|
388
|
+
const handleTocClick = () => {
|
|
389
|
+
if (container.current) {
|
|
390
|
+
container.current.scrollIntoView();
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
return (React.createElement(SidebarLayout, { ref: container, sidebar: React.createElement(React.Fragment, null,
|
|
394
|
+
branches && branches.items.length > 1 ? (React.createElement(BranchSelector, { branchSlug: branchSlug, branches: branches.items, onChange: branch => {
|
|
395
|
+
const encodedBranchSlug = encodeURIComponent(branch.slug);
|
|
396
|
+
navigate(branch.is_default ? `${nodeSlug}` : `branches/${encodedBranchSlug}/${nodeSlug}`);
|
|
397
|
+
} })) : null,
|
|
398
|
+
tableOfContents ? (React.createElement(TableOfContents, { activeId: (node === null || node === void 0 ? void 0 : node.id) || (nodeSlug === null || nodeSlug === void 0 ? void 0 : nodeSlug.split('-')[0]) || '', tableOfContents: tableOfContents, Link: Link, collapseTableOfContents: collapseTableOfContents, onLinkClick: handleTocClick })) : null) },
|
|
399
|
+
React.createElement(Outlet, { context: [isLoadingNode, isTocFetched, isError, nodeError, node] })));
|
|
400
|
+
};
|
|
401
|
+
const ProjectNode = ({ hideTryIt, hideSecurityInfo, hideServerInfo, hideMocking, hideExport, tryItCredentialsPolicy, tryItCorsProxy, }) => {
|
|
402
|
+
const { branchSlug: encodedBranchSlug = '', nodeSlug = '' } = useParams();
|
|
403
|
+
const branchSlug = decodeURIComponent(encodedBranchSlug);
|
|
404
|
+
const [isLoadingNode, isTocFetched, isError, nodeError, node] = useOutletContext();
|
|
383
405
|
if (isLoadingNode || !isTocFetched) {
|
|
384
|
-
|
|
406
|
+
return React.createElement(Loading, null);
|
|
385
407
|
}
|
|
386
|
-
|
|
408
|
+
if (isError) {
|
|
387
409
|
if (nodeError instanceof ResponseError) {
|
|
388
410
|
if (nodeError.code === 402) {
|
|
389
|
-
|
|
411
|
+
return React.createElement(UpgradeToStarter, null);
|
|
390
412
|
}
|
|
391
413
|
else if (nodeError.code === 403) {
|
|
392
|
-
|
|
414
|
+
return React.createElement(Forbidden, null);
|
|
393
415
|
}
|
|
394
416
|
else {
|
|
395
|
-
|
|
417
|
+
return React.createElement(NotFound, null);
|
|
396
418
|
}
|
|
397
419
|
}
|
|
398
420
|
else {
|
|
399
|
-
|
|
421
|
+
return React.createElement(NotFound, null);
|
|
400
422
|
}
|
|
401
423
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
else if ((node === null || node === void 0 ? void 0 : node.slug) && nodeSlug !== node.slug) {
|
|
406
|
-
return React.createElement(Redirect, { to: branchSlug ? `/branches/${branchSlug}/${node.slug}` : `/${node.slug}` });
|
|
424
|
+
if (!node) {
|
|
425
|
+
return React.createElement(NotFound, null);
|
|
407
426
|
}
|
|
408
|
-
|
|
409
|
-
|
|
427
|
+
if ((node === null || node === void 0 ? void 0 : node.slug) && nodeSlug !== node.slug) {
|
|
428
|
+
return React.createElement(Navigate, { to: branchSlug ? `/branches/${branchSlug}/${node.slug}` : `/${node.slug}`, replace: true });
|
|
410
429
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
return (React.createElement(SidebarLayout, { ref: container, sidebar: React.createElement(React.Fragment, null,
|
|
417
|
-
branches && branches.items.length > 1 ? (React.createElement(BranchSelector, { branchSlug: branchSlug, branches: branches.items, onChange: branch => {
|
|
418
|
-
const encodedBranchSlug = encodeURIComponent(branch.slug);
|
|
419
|
-
history.push(branch.is_default ? `/${nodeSlug}` : `/branches/${encodedBranchSlug}/${nodeSlug}`);
|
|
420
|
-
} })) : null,
|
|
421
|
-
tableOfContents ? (React.createElement(TableOfContents, { activeId: (node === null || node === void 0 ? void 0 : node.id) || (nodeSlug === null || nodeSlug === void 0 ? void 0 : nodeSlug.split('-')[0]) || '', tableOfContents: tableOfContents, Link: Link, collapseTableOfContents: collapseTableOfContents, onLinkClick: handleTocClick })) : null) }, elem));
|
|
430
|
+
return (React.createElement(React.Fragment, null,
|
|
431
|
+
React.createElement(ScrollToHashElement, null),
|
|
432
|
+
React.createElement(NodeContent, { node: node, Link: ReactRouterMarkdownLink, hideTryIt: hideTryIt, hideMocking: hideMocking, hideExport: hideExport, hideSecurityInfo: hideSecurityInfo, hideServerInfo: hideServerInfo, tryItCredentialsPolicy: tryItCredentialsPolicy, tryItCorsProxy: tryItCorsProxy })));
|
|
422
433
|
};
|
|
423
434
|
const StoplightProjectRouter = (_a) => {
|
|
424
|
-
var { platformUrl, basePath = '/', staticRouterPath = '', router = '
|
|
435
|
+
var { platformUrl, basePath = '/', staticRouterPath = '', router = 'hash' } = _a, props = __rest(_a, ["platformUrl", "basePath", "staticRouterPath", "router"]);
|
|
425
436
|
const { Router, routerProps } = useRouter(router, basePath, staticRouterPath);
|
|
437
|
+
const outerRouter = useInRouterContext();
|
|
438
|
+
const InternalRoutes = () => (React.createElement(Routes, null,
|
|
439
|
+
React.createElement(Route, { path: "/", element: React.createElement(StoplightProjectImpl, Object.assign({}, props)) },
|
|
440
|
+
React.createElement(Route, { path: "/branches/:branchSlug/:nodeSlug/*", element: React.createElement(ProjectNode, Object.assign({}, props)) }),
|
|
441
|
+
React.createElement(Route, { path: "/:nodeSlug/*", element: React.createElement(ProjectNode, Object.assign({}, props)) }),
|
|
442
|
+
React.createElement(Route, { element: React.createElement(ProjectNode, Object.assign({}, props)) }))));
|
|
443
|
+
if (!outerRouter) {
|
|
444
|
+
return (React.createElement(DevPortalProvider, { platformUrl: platformUrl },
|
|
445
|
+
React.createElement(RouterTypeContext.Provider, { value: router },
|
|
446
|
+
React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
447
|
+
React.createElement(InternalRoutes, null)))));
|
|
448
|
+
}
|
|
426
449
|
return (React.createElement(DevPortalProvider, { platformUrl: platformUrl },
|
|
427
450
|
React.createElement(RouterTypeContext.Provider, { value: router },
|
|
428
|
-
React.createElement(
|
|
429
|
-
React.createElement(Switch, null,
|
|
430
|
-
React.createElement(Route, { path: "/branches/:branchSlug/:nodeSlug+", exact: true },
|
|
431
|
-
React.createElement(StoplightProjectImpl, Object.assign({}, props))),
|
|
432
|
-
React.createElement(Route, { path: "/:nodeSlug+", exact: true },
|
|
433
|
-
React.createElement(StoplightProjectImpl, Object.assign({}, props))),
|
|
434
|
-
React.createElement(Route, { path: "/", exact: true },
|
|
435
|
-
React.createElement(StoplightProjectImpl, Object.assign({}, props))))))));
|
|
451
|
+
React.createElement(InternalRoutes, null))));
|
|
436
452
|
};
|
|
437
453
|
const StoplightProject = withStyles(StoplightProjectRouter);
|
|
438
454
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stoplight/elements-dev-portal",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "UI components for composing beautiful developer documentation.",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"main": "./index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"react-dom": ">=16.8"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@stoplight/elements-core": "
|
|
29
|
+
"@stoplight/elements-core": "~9.0.0",
|
|
30
30
|
"@stoplight/markdown-viewer": "^5.7.1",
|
|
31
31
|
"@stoplight/mosaic": "^1.53.4",
|
|
32
32
|
"@stoplight/path": "^1.3.2",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"classnames": "^2.2.6",
|
|
35
35
|
"lodash": "^4.17.21",
|
|
36
36
|
"react-query": "^3.34.19",
|
|
37
|
-
"react-router-dom": "^
|
|
37
|
+
"react-router-dom": "^6.28.0",
|
|
38
38
|
"use-debounce": "^6.0.1"
|
|
39
39
|
},
|
|
40
40
|
"type": "commonjs",
|
package/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const appVersion = "
|
|
1
|
+
export declare const appVersion = "3.0.0";
|