@stoplight/elements-core 7.5.5 → 7.5.9
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/Docs/Article/index.d.ts +2 -2
- package/components/Docs/Docs.d.ts +2 -0
- package/components/MarkdownViewer/CustomComponents/ReactRouterLink.d.ts +3 -2
- package/components/MarkdownViewer/CustomComponents/ResolvedImage.d.ts +1 -1
- package/index.esm.js +29 -116
- package/index.js +21 -109
- package/index.mjs +29 -116
- package/package.json +3 -5
- package/types.d.ts +2 -14
- package/utils/guards.d.ts +2 -2
- package/components/Docs/Article/Headings.d.ts +0 -5
- package/hooks/useComponentSize.d.ts +0 -4
- package/hooks/useComputeMarkdownHeadings.d.ts +0 -4
- package/hooks/useLocationHash.d.ts +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IMarkdownViewerProps } from '@stoplight/markdown-viewer';
|
|
2
2
|
import { DocsComponentProps } from '..';
|
|
3
|
-
declare type ArticleProps = DocsComponentProps<
|
|
3
|
+
declare type ArticleProps = DocsComponentProps<IMarkdownViewerProps['markdown']>;
|
|
4
4
|
export declare const Article: import("react").FunctionComponent<ArticleProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
|
|
5
5
|
export {};
|
|
@@ -2,6 +2,7 @@ import { NodeType } from '@stoplight/types';
|
|
|
2
2
|
import { Location } from 'history';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { ParsedNode } from '../../types';
|
|
5
|
+
import { ReferenceResolver } from '../../utils/ref-resolving/ReferenceResolver';
|
|
5
6
|
import { ExportButtonProps } from './HttpService/ExportButton';
|
|
6
7
|
interface BaseDocsProps {
|
|
7
8
|
className?: string;
|
|
@@ -27,6 +28,7 @@ export interface DocsProps extends BaseDocsProps {
|
|
|
27
28
|
nodeType: NodeType;
|
|
28
29
|
nodeData: unknown;
|
|
29
30
|
useNodeForRefResolving?: boolean;
|
|
31
|
+
refResolver?: ReferenceResolver;
|
|
30
32
|
}
|
|
31
33
|
export interface DocsComponentProps<T = unknown> extends BaseDocsProps {
|
|
32
34
|
data: T;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare const ReactRouterMarkdownLink: ({ title, to, href: _href, children, }: import("react").ClassAttributes<HTMLAnchorElement> & import("react").AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
2
|
+
to?: string | undefined;
|
|
3
|
+
}) => JSX.Element;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BundledBranchNode } from '../../../types';
|
|
3
|
-
export declare const createResolvedImageComponent: (branchNode: BundledBranchNode) => React.NamedExoticComponent<import("react").ImgHTMLAttributes<
|
|
3
|
+
export declare const createResolvedImageComponent: (branchNode: BundledBranchNode) => React.NamedExoticComponent<import("react").ImgHTMLAttributes<HTMLImageElement> & import("@stoplight/markdown/ast-types/hast").ImageProperties>;
|
package/index.esm.js
CHANGED
|
@@ -5,18 +5,15 @@ import { resolveInlineRef, isPlainObject as isPlainObject$1, safeParse, safeStri
|
|
|
5
5
|
import isArray from 'lodash/isArray.js';
|
|
6
6
|
import isObject from 'lodash/isObject.js';
|
|
7
7
|
import isPlainObject from 'lodash/isPlainObject.js';
|
|
8
|
-
import { parse } from '@stoplight/markdown';
|
|
9
8
|
import { NodeType, HttpParamStyles } from '@stoplight/types';
|
|
10
|
-
import { parse
|
|
11
|
-
import { isArray as isArray$1, Box,
|
|
9
|
+
import { parse } from '@stoplight/yaml';
|
|
10
|
+
import { isArray as isArray$1, Box, Panel, CopyButton, Menu, Button, Text, Flex, Input, Icon, Select, FieldButton, Image, Link, useThemeIsDark, HStack, VStack, InvertTheme, Tooltip, Badge, LinkHeading, Tabs, TabList, Tab, TabPanels, TabPanel, Heading, useClipboard, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
|
|
12
11
|
import { withErrorBoundary } from '@stoplight/react-error-boundary';
|
|
13
12
|
import { MarkdownViewer as MarkdownViewer$1, DefaultSMDComponents, MarkdownViewerProvider } from '@stoplight/markdown-viewer';
|
|
14
13
|
export { DefaultSMDComponents } from '@stoplight/markdown-viewer';
|
|
15
|
-
import { faStream, faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
16
|
-
import throttle from 'lodash/throttle.js';
|
|
17
|
-
import { selectAll } from 'unist-util-select';
|
|
18
14
|
import cn from 'classnames';
|
|
19
15
|
import { atomWithStorage, useAtomValue } from 'jotai/utils';
|
|
16
|
+
import { faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
20
17
|
import { atom, useAtom, Provider } from 'jotai';
|
|
21
18
|
import URI from 'urijs';
|
|
22
19
|
import { CodeViewer } from '@stoplight/mosaic-code-viewer';
|
|
@@ -164,13 +161,7 @@ const parserMap = {
|
|
|
164
161
|
[NodeType.Unknown]: parseUnknown,
|
|
165
162
|
};
|
|
166
163
|
function parseArticleData(rawData) {
|
|
167
|
-
if (typeof rawData === 'string') {
|
|
168
|
-
return {
|
|
169
|
-
type: NodeType.Article,
|
|
170
|
-
data: parse(rawData),
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
if (isSMDASTRoot(rawData)) {
|
|
164
|
+
if (typeof rawData === 'string' || isSMDASTRoot(rawData)) {
|
|
174
165
|
return {
|
|
175
166
|
type: NodeType.Article,
|
|
176
167
|
data: rawData,
|
|
@@ -213,7 +204,7 @@ function tryParseYamlOrObject(yamlOrObject) {
|
|
|
213
204
|
return yamlOrObject;
|
|
214
205
|
if (typeof yamlOrObject === 'string') {
|
|
215
206
|
try {
|
|
216
|
-
return parse
|
|
207
|
+
return parse(yamlOrObject);
|
|
217
208
|
}
|
|
218
209
|
catch (e) { }
|
|
219
210
|
}
|
|
@@ -228,94 +219,9 @@ const MarkdownViewer = (props) => {
|
|
|
228
219
|
};
|
|
229
220
|
MarkdownViewer.displayName = 'MarkdownViewer';
|
|
230
221
|
|
|
231
|
-
function useComponentSize(container) {
|
|
232
|
-
const [componentSize, setComponentSize] = React.useState({ width: 0, height: 0 });
|
|
233
|
-
React.useEffect(() => {
|
|
234
|
-
if (!container) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
const updateComponentSize = throttle(() => (container ? setComponentSize(container.getBoundingClientRect()) : { width: 0, height: 0 }), 1000, {
|
|
238
|
-
trailing: true,
|
|
239
|
-
});
|
|
240
|
-
updateComponentSize();
|
|
241
|
-
window.addEventListener('resize', updateComponentSize);
|
|
242
|
-
return () => {
|
|
243
|
-
updateComponentSize.cancel();
|
|
244
|
-
window.removeEventListener('resize', updateComponentSize);
|
|
245
|
-
};
|
|
246
|
-
}, [container]);
|
|
247
|
-
return componentSize;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function useComputeMarkdownHeadings(tree) {
|
|
251
|
-
return React.useMemo(() => computeMarkdownHeadings(tree), [tree]);
|
|
252
|
-
}
|
|
253
|
-
function computeMarkdownHeadings(tree) {
|
|
254
|
-
return selectAll(':root > [type=heading]', tree)
|
|
255
|
-
.map((heading) => {
|
|
256
|
-
var _a;
|
|
257
|
-
return ({
|
|
258
|
-
title: findTitle(heading),
|
|
259
|
-
id: ((_a = heading.data) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
260
|
-
depth: heading.depth - 1,
|
|
261
|
-
});
|
|
262
|
-
})
|
|
263
|
-
.filter((item) => item.depth >= 1 && item.depth <= 2);
|
|
264
|
-
}
|
|
265
|
-
const findTitle = (parent) => {
|
|
266
|
-
return selectAll('[type=text]', parent).map(textNode => String(textNode.value)).join(' ');
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
function useLocationHash() {
|
|
270
|
-
const isBrowser = typeof window !== 'undefined';
|
|
271
|
-
const [locationHash, setLocationHash] = React.useState(isBrowser && window.location.hash);
|
|
272
|
-
React.useEffect(() => {
|
|
273
|
-
if (!isBrowser)
|
|
274
|
-
return;
|
|
275
|
-
const hashChange = () => setLocationHash(window.location.hash);
|
|
276
|
-
window.addEventListener('hashchange', hashChange, false);
|
|
277
|
-
return () => window.removeEventListener('hashchange', hashChange);
|
|
278
|
-
}, [isBrowser]);
|
|
279
|
-
return locationHash;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const ArticleHeadings = ({ tree, container }) => {
|
|
283
|
-
const { width } = useComponentSize(container);
|
|
284
|
-
const showHeadings = width >= 768;
|
|
285
|
-
const headings = useComputeMarkdownHeadings(tree);
|
|
286
|
-
return React.createElement(Headings, { className: "ArticleHeadings", headings: headings, minimal: !showHeadings, maxWidth: 300 });
|
|
287
|
-
};
|
|
288
|
-
const Headings = ({ headings, className, title = 'On This Page', minimal, maxWidth }) => {
|
|
289
|
-
const locationHash = useLocationHash();
|
|
290
|
-
if (!headings || !headings.length)
|
|
291
|
-
return null;
|
|
292
|
-
const component = (React.createElement(Box, { overflowY: "auto", style: { maxHeight: '85vh', maxWidth } },
|
|
293
|
-
title && (React.createElement(Flex, { py: 2, alignItems: "center", fontSize: "sm", fontWeight: "medium", color: "muted", style: { paddingLeft: 18 } },
|
|
294
|
-
React.createElement(Box, { as: Icon, icon: faStream, mr: 2 }),
|
|
295
|
-
title)),
|
|
296
|
-
headings.map((heading, i) => (React.createElement(Heading, { key: i, item: heading, isSelected: locationHash === `#${heading.id}` })))));
|
|
297
|
-
const button = React.createElement(Button, { pos: "sticky", size: "sm", borderColor: "light", icon: faStream, style: { top: 10 } });
|
|
298
|
-
if (minimal) {
|
|
299
|
-
return (React.createElement(Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
|
|
300
|
-
React.createElement(Popover, { renderTrigger: button, placement: "bottom" },
|
|
301
|
-
React.createElement(Box, { className: className }, component))));
|
|
302
|
-
}
|
|
303
|
-
return (React.createElement(Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
|
|
304
|
-
React.createElement(Box, { borderL: true, borderColor: "light" }, component)));
|
|
305
|
-
};
|
|
306
|
-
const Heading = ({ item, isSelected }) => {
|
|
307
|
-
return (React.createElement(Box, { as: "a", href: `#${item.id}`, textOverflow: "truncate", display: "block", py: 2, pr: 8, fontWeight: "medium", fontSize: "sm", color: isSelected ? 'primary' : 'muted', style: { paddingLeft: `${3 + item.depth * 15}px` } }, item.title));
|
|
308
|
-
};
|
|
309
|
-
|
|
310
222
|
const ArticleComponent = React.memo(({ data }) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (tree === null)
|
|
314
|
-
return null;
|
|
315
|
-
return (React.createElement(Flex, { className: "sl-elements-article", justifyContent: "evenly", w: "full", pos: "relative", ref: setContainer },
|
|
316
|
-
React.createElement(Box, { className: "sl-elements-article-content", style: { width: 0 }, flex: 1 },
|
|
317
|
-
React.createElement(MarkdownViewer, { markdown: tree })),
|
|
318
|
-
React.createElement(ArticleHeadings, { tree: tree, container: container })));
|
|
223
|
+
return (React.createElement(Box, { className: "sl-elements-article" },
|
|
224
|
+
React.createElement(MarkdownViewer, { className: "sl-elements-article-content", markdown: data, includeToc: true })));
|
|
319
225
|
});
|
|
320
226
|
const Article = withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
|
|
321
227
|
|
|
@@ -1015,7 +921,11 @@ function parameterSupportsFileUpload(parameter) {
|
|
|
1015
921
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1016
922
|
}
|
|
1017
923
|
function exampleValue(example) {
|
|
1018
|
-
|
|
924
|
+
const value = 'value' in example ? example.value : example.externalValue;
|
|
925
|
+
return escapeQuotes(String(value));
|
|
926
|
+
}
|
|
927
|
+
function escapeQuotes(value) {
|
|
928
|
+
return value.replace(/"/g, '\\"');
|
|
1019
929
|
}
|
|
1020
930
|
function getPlaceholderForParameter(parameter) {
|
|
1021
931
|
var _a, _b;
|
|
@@ -1316,7 +1226,9 @@ function buildFetchRequest({ httpOperation, mediaTypeContent, bodyInput, paramet
|
|
|
1316
1226
|
const serverUrl = getServerUrl({ httpOperation, mockData, chosenServer, corsProxy });
|
|
1317
1227
|
const shouldIncludeBody = ['PUT', 'POST', 'PATCH'].includes(httpOperation.method.toUpperCase());
|
|
1318
1228
|
const queryParams = (_c = (_b = (_a = httpOperation.request) === null || _a === void 0 ? void 0 : _a.query) === null || _b === void 0 ? void 0 : _b.map(param => { var _a; return ({ name: param.name, value: (_a = parameterValues[param.name]) !== null && _a !== void 0 ? _a : '' }); }).filter(({ value }) => value.length > 0)) !== null && _c !== void 0 ? _c : [];
|
|
1319
|
-
const rawHeaders = filterOutAuthorizationParams((_e = (_d = httpOperation.request) === null || _d === void 0 ? void 0 : _d.headers) !== null && _e !== void 0 ? _e : [], httpOperation.security)
|
|
1229
|
+
const rawHeaders = filterOutAuthorizationParams((_e = (_d = httpOperation.request) === null || _d === void 0 ? void 0 : _d.headers) !== null && _e !== void 0 ? _e : [], httpOperation.security)
|
|
1230
|
+
.map(header => { var _a; return ({ name: header.name, value: (_a = parameterValues[header.name]) !== null && _a !== void 0 ? _a : '' }); })
|
|
1231
|
+
.filter(({ value }) => value.length > 0);
|
|
1320
1232
|
const [queryParamsWithAuth, headersWithAuth] = runAuthRequestEhancements(auth, queryParams, rawHeaders);
|
|
1321
1233
|
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1322
1234
|
const url = new URL(URI(serverUrl).segment(expandedPath).toString());
|
|
@@ -1604,9 +1516,9 @@ const bodyFormatMap = {
|
|
|
1604
1516
|
text: ['raw'],
|
|
1605
1517
|
};
|
|
1606
1518
|
const regex = {
|
|
1607
|
-
image: /image\/(
|
|
1608
|
-
json: /application\/(
|
|
1609
|
-
xml: /(text|application)\/(
|
|
1519
|
+
image: /image\/(.?)*(jpeg|gif|png|svg)/,
|
|
1520
|
+
json: /application\/(.?)*json/,
|
|
1521
|
+
xml: /(text|application)\/(.?)*(xml|html)/,
|
|
1610
1522
|
text: /text\/.*/,
|
|
1611
1523
|
};
|
|
1612
1524
|
function getResponseType(contentType) {
|
|
@@ -2171,7 +2083,7 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, la
|
|
|
2171
2083
|
const hasBadges = isDeprecated || isInternal;
|
|
2172
2084
|
const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React.createElement(VStack, { spacing: 5 },
|
|
2173
2085
|
React.createElement(HStack, { spacing: 5 },
|
|
2174
|
-
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading
|
|
2086
|
+
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading, { size: 1, fontWeight: "semibold" }, prettyName)) : null,
|
|
2175
2087
|
React.createElement(HStack, { spacing: 2 },
|
|
2176
2088
|
isDeprecated && React.createElement(DeprecatedBadge, null),
|
|
2177
2089
|
isInternal && React.createElement(InternalBadge, { isHttpService: true }))),
|
|
@@ -2295,7 +2207,7 @@ const HttpServiceComponent = React.memo(({ data, location = {}, layoutOptions, e
|
|
|
2295
2207
|
const query = new URLSearchParams(search);
|
|
2296
2208
|
return (React.createElement(Box, { mb: 10 },
|
|
2297
2209
|
data.name && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2298
|
-
React.createElement(Heading
|
|
2210
|
+
React.createElement(Heading, { size: 1, mb: 4, fontWeight: "semibold" }, data.name),
|
|
2299
2211
|
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps)))),
|
|
2300
2212
|
data.version && (React.createElement(Box, { mb: 5 },
|
|
2301
2213
|
React.createElement(VersionBadge, { value: data.version }))),
|
|
@@ -2326,7 +2238,7 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2326
2238
|
const shouldDisplayHeader = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (title !== undefined || (exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport)));
|
|
2327
2239
|
const header = (shouldDisplayHeader || isInternal) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2328
2240
|
React.createElement(HStack, { spacing: 5 },
|
|
2329
|
-
title && (React.createElement(Heading
|
|
2241
|
+
title && (React.createElement(Heading, { size: 1, fontWeight: "semibold" }, title)),
|
|
2330
2242
|
React.createElement(HStack, { spacing: 2 }, isInternal && React.createElement(InternalBadge, null))),
|
|
2331
2243
|
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps))));
|
|
2332
2244
|
const description = (React.createElement(VStack, { spacing: 10 },
|
|
@@ -2341,14 +2253,14 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2341
2253
|
const Model = withErrorBoundary(ModelComponent, { recoverableProps: ['data'] });
|
|
2342
2254
|
|
|
2343
2255
|
const Docs = React.memo((_a) => {
|
|
2344
|
-
var { nodeType, nodeData, useNodeForRefResolving = false } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving"]);
|
|
2256
|
+
var { nodeType, nodeData, useNodeForRefResolving = false, refResolver } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver"]);
|
|
2345
2257
|
const parsedNode = useParsedData(nodeType, nodeData);
|
|
2346
2258
|
if (!parsedNode) {
|
|
2347
2259
|
return null;
|
|
2348
2260
|
}
|
|
2349
2261
|
const parsedDocs = React.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
|
|
2350
2262
|
if (useNodeForRefResolving) {
|
|
2351
|
-
return React.createElement(InlineRefResolverProvider, { document: parsedNode.data }, parsedDocs);
|
|
2263
|
+
return (React.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, parsedDocs));
|
|
2352
2264
|
}
|
|
2353
2265
|
return parsedDocs;
|
|
2354
2266
|
});
|
|
@@ -2383,7 +2295,7 @@ const SidebarLayout = React.forwardRef(({ sidebar, children, maxContentWidth = M
|
|
|
2383
2295
|
paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
|
|
2384
2296
|
minWidth: `${sidebarWidth}px`,
|
|
2385
2297
|
} }, sidebar),
|
|
2386
|
-
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1,
|
|
2298
|
+
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full" },
|
|
2387
2299
|
React.createElement(Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
|
|
2388
2300
|
});
|
|
2389
2301
|
|
|
@@ -2412,7 +2324,7 @@ function useParsedValue(value) {
|
|
|
2412
2324
|
let parsedValue = value;
|
|
2413
2325
|
if (typeof value === 'string') {
|
|
2414
2326
|
try {
|
|
2415
|
-
parsedValue = parse
|
|
2327
|
+
parsedValue = parse(value);
|
|
2416
2328
|
}
|
|
2417
2329
|
catch (error) {
|
|
2418
2330
|
}
|
|
@@ -2506,7 +2418,8 @@ const MarkdownComponentsProvider = ({ value, children }) => {
|
|
|
2506
2418
|
};
|
|
2507
2419
|
|
|
2508
2420
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
2509
|
-
const ReactRouterMarkdownLink = ({ title, href, children }) => {
|
|
2421
|
+
const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
2422
|
+
const href = to || _href;
|
|
2510
2423
|
const isExternal = href !== undefined && externalRegex.test(href);
|
|
2511
2424
|
if (isExternal) {
|
|
2512
2425
|
return (React__default.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
@@ -2685,7 +2598,7 @@ const Version = ({ value }) => {
|
|
|
2685
2598
|
const NonIdealState = ({ description, icon, title }) => {
|
|
2686
2599
|
return (React.createElement(Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
|
|
2687
2600
|
React.createElement(Box, { as: Icon, icon: icon || faExclamationTriangle, color: "light", fontSize: "6xl", mb: 4 }),
|
|
2688
|
-
React.createElement(Heading
|
|
2601
|
+
React.createElement(Heading, { size: 4, mb: 4 }, title),
|
|
2689
2602
|
React.createElement(Text, null, description)));
|
|
2690
2603
|
};
|
|
2691
2604
|
|
|
@@ -2752,7 +2665,7 @@ function withRouter(WrappedComponent) {
|
|
|
2752
2665
|
const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
|
|
2753
2666
|
return (React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
2754
2667
|
React.createElement(Route, { path: "/" },
|
|
2755
|
-
React.createElement(MarkdownComponentsProvider, { value: {
|
|
2668
|
+
React.createElement(MarkdownComponentsProvider, { value: { a: ReactRouterMarkdownLink } },
|
|
2756
2669
|
React.createElement(WrappedComponent, Object.assign({}, props))))));
|
|
2757
2670
|
};
|
|
2758
2671
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
package/index.js
CHANGED
|
@@ -8,17 +8,14 @@ var json = require('@stoplight/json');
|
|
|
8
8
|
var isArray = require('lodash/isArray.js');
|
|
9
9
|
var isObject = require('lodash/isObject.js');
|
|
10
10
|
var isPlainObject = require('lodash/isPlainObject.js');
|
|
11
|
-
var markdown = require('@stoplight/markdown');
|
|
12
11
|
var types = require('@stoplight/types');
|
|
13
12
|
var yaml = require('@stoplight/yaml');
|
|
14
13
|
var mosaic = require('@stoplight/mosaic');
|
|
15
14
|
var reactErrorBoundary = require('@stoplight/react-error-boundary');
|
|
16
15
|
var markdownViewer = require('@stoplight/markdown-viewer');
|
|
17
|
-
var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
|
|
18
|
-
var throttle = require('lodash/throttle.js');
|
|
19
|
-
var unistUtilSelect = require('unist-util-select');
|
|
20
16
|
var cn = require('classnames');
|
|
21
17
|
var utils = require('jotai/utils');
|
|
18
|
+
var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
|
|
22
19
|
var jotai = require('jotai');
|
|
23
20
|
var URI = require('urijs');
|
|
24
21
|
var mosaicCodeViewer = require('@stoplight/mosaic-code-viewer');
|
|
@@ -78,7 +75,6 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
|
78
75
|
var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
|
|
79
76
|
var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
|
|
80
77
|
var isPlainObject__default = /*#__PURE__*/_interopDefaultLegacy(isPlainObject);
|
|
81
|
-
var throttle__default = /*#__PURE__*/_interopDefaultLegacy(throttle);
|
|
82
78
|
var cn__default = /*#__PURE__*/_interopDefaultLegacy(cn);
|
|
83
79
|
var URI__default = /*#__PURE__*/_interopDefaultLegacy(URI);
|
|
84
80
|
var HTTPSnippet__default = /*#__PURE__*/_interopDefaultLegacy(HTTPSnippet);
|
|
@@ -219,13 +215,7 @@ const parserMap = {
|
|
|
219
215
|
[types.NodeType.Unknown]: parseUnknown,
|
|
220
216
|
};
|
|
221
217
|
function parseArticleData(rawData) {
|
|
222
|
-
if (typeof rawData === 'string') {
|
|
223
|
-
return {
|
|
224
|
-
type: types.NodeType.Article,
|
|
225
|
-
data: markdown.parse(rawData),
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
if (isSMDASTRoot(rawData)) {
|
|
218
|
+
if (typeof rawData === 'string' || isSMDASTRoot(rawData)) {
|
|
229
219
|
return {
|
|
230
220
|
type: types.NodeType.Article,
|
|
231
221
|
data: rawData,
|
|
@@ -283,94 +273,9 @@ const MarkdownViewer = (props) => {
|
|
|
283
273
|
};
|
|
284
274
|
MarkdownViewer.displayName = 'MarkdownViewer';
|
|
285
275
|
|
|
286
|
-
function useComponentSize(container) {
|
|
287
|
-
const [componentSize, setComponentSize] = React__namespace.useState({ width: 0, height: 0 });
|
|
288
|
-
React__namespace.useEffect(() => {
|
|
289
|
-
if (!container) {
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
const updateComponentSize = throttle__default["default"](() => (container ? setComponentSize(container.getBoundingClientRect()) : { width: 0, height: 0 }), 1000, {
|
|
293
|
-
trailing: true,
|
|
294
|
-
});
|
|
295
|
-
updateComponentSize();
|
|
296
|
-
window.addEventListener('resize', updateComponentSize);
|
|
297
|
-
return () => {
|
|
298
|
-
updateComponentSize.cancel();
|
|
299
|
-
window.removeEventListener('resize', updateComponentSize);
|
|
300
|
-
};
|
|
301
|
-
}, [container]);
|
|
302
|
-
return componentSize;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
function useComputeMarkdownHeadings(tree) {
|
|
306
|
-
return React__namespace.useMemo(() => computeMarkdownHeadings(tree), [tree]);
|
|
307
|
-
}
|
|
308
|
-
function computeMarkdownHeadings(tree) {
|
|
309
|
-
return unistUtilSelect.selectAll(':root > [type=heading]', tree)
|
|
310
|
-
.map((heading) => {
|
|
311
|
-
var _a;
|
|
312
|
-
return ({
|
|
313
|
-
title: findTitle(heading),
|
|
314
|
-
id: ((_a = heading.data) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
315
|
-
depth: heading.depth - 1,
|
|
316
|
-
});
|
|
317
|
-
})
|
|
318
|
-
.filter((item) => item.depth >= 1 && item.depth <= 2);
|
|
319
|
-
}
|
|
320
|
-
const findTitle = (parent) => {
|
|
321
|
-
return unistUtilSelect.selectAll('[type=text]', parent).map(textNode => String(textNode.value)).join(' ');
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
function useLocationHash() {
|
|
325
|
-
const isBrowser = typeof window !== 'undefined';
|
|
326
|
-
const [locationHash, setLocationHash] = React__namespace.useState(isBrowser && window.location.hash);
|
|
327
|
-
React__namespace.useEffect(() => {
|
|
328
|
-
if (!isBrowser)
|
|
329
|
-
return;
|
|
330
|
-
const hashChange = () => setLocationHash(window.location.hash);
|
|
331
|
-
window.addEventListener('hashchange', hashChange, false);
|
|
332
|
-
return () => window.removeEventListener('hashchange', hashChange);
|
|
333
|
-
}, [isBrowser]);
|
|
334
|
-
return locationHash;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const ArticleHeadings = ({ tree, container }) => {
|
|
338
|
-
const { width } = useComponentSize(container);
|
|
339
|
-
const showHeadings = width >= 768;
|
|
340
|
-
const headings = useComputeMarkdownHeadings(tree);
|
|
341
|
-
return React__namespace.createElement(Headings, { className: "ArticleHeadings", headings: headings, minimal: !showHeadings, maxWidth: 300 });
|
|
342
|
-
};
|
|
343
|
-
const Headings = ({ headings, className, title = 'On This Page', minimal, maxWidth }) => {
|
|
344
|
-
const locationHash = useLocationHash();
|
|
345
|
-
if (!headings || !headings.length)
|
|
346
|
-
return null;
|
|
347
|
-
const component = (React__namespace.createElement(mosaic.Box, { overflowY: "auto", style: { maxHeight: '85vh', maxWidth } },
|
|
348
|
-
title && (React__namespace.createElement(mosaic.Flex, { py: 2, alignItems: "center", fontSize: "sm", fontWeight: "medium", color: "muted", style: { paddingLeft: 18 } },
|
|
349
|
-
React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, icon: freeSolidSvgIcons.faStream, mr: 2 }),
|
|
350
|
-
title)),
|
|
351
|
-
headings.map((heading, i) => (React__namespace.createElement(Heading, { key: i, item: heading, isSelected: locationHash === `#${heading.id}` })))));
|
|
352
|
-
const button = React__namespace.createElement(mosaic.Button, { pos: "sticky", size: "sm", borderColor: "light", icon: freeSolidSvgIcons.faStream, style: { top: 10 } });
|
|
353
|
-
if (minimal) {
|
|
354
|
-
return (React__namespace.createElement(mosaic.Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
|
|
355
|
-
React__namespace.createElement(mosaic.Popover, { renderTrigger: button, placement: "bottom" },
|
|
356
|
-
React__namespace.createElement(mosaic.Box, { className: className }, component))));
|
|
357
|
-
}
|
|
358
|
-
return (React__namespace.createElement(mosaic.Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
|
|
359
|
-
React__namespace.createElement(mosaic.Box, { borderL: true, borderColor: "light" }, component)));
|
|
360
|
-
};
|
|
361
|
-
const Heading = ({ item, isSelected }) => {
|
|
362
|
-
return (React__namespace.createElement(mosaic.Box, { as: "a", href: `#${item.id}`, textOverflow: "truncate", display: "block", py: 2, pr: 8, fontWeight: "medium", fontSize: "sm", color: isSelected ? 'primary' : 'muted', style: { paddingLeft: `${3 + item.depth * 15}px` } }, item.title));
|
|
363
|
-
};
|
|
364
|
-
|
|
365
276
|
const ArticleComponent = React__namespace.memo(({ data }) => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (tree === null)
|
|
369
|
-
return null;
|
|
370
|
-
return (React__namespace.createElement(mosaic.Flex, { className: "sl-elements-article", justifyContent: "evenly", w: "full", pos: "relative", ref: setContainer },
|
|
371
|
-
React__namespace.createElement(mosaic.Box, { className: "sl-elements-article-content", style: { width: 0 }, flex: 1 },
|
|
372
|
-
React__namespace.createElement(MarkdownViewer, { markdown: tree })),
|
|
373
|
-
React__namespace.createElement(ArticleHeadings, { tree: tree, container: container })));
|
|
277
|
+
return (React__namespace.createElement(mosaic.Box, { className: "sl-elements-article" },
|
|
278
|
+
React__namespace.createElement(MarkdownViewer, { className: "sl-elements-article-content", markdown: data, includeToc: true })));
|
|
374
279
|
});
|
|
375
280
|
const Article = reactErrorBoundary.withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
|
|
376
281
|
|
|
@@ -1070,7 +975,11 @@ function parameterSupportsFileUpload(parameter) {
|
|
|
1070
975
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1071
976
|
}
|
|
1072
977
|
function exampleValue(example) {
|
|
1073
|
-
|
|
978
|
+
const value = 'value' in example ? example.value : example.externalValue;
|
|
979
|
+
return escapeQuotes(String(value));
|
|
980
|
+
}
|
|
981
|
+
function escapeQuotes(value) {
|
|
982
|
+
return value.replace(/"/g, '\\"');
|
|
1074
983
|
}
|
|
1075
984
|
function getPlaceholderForParameter(parameter) {
|
|
1076
985
|
var _a, _b;
|
|
@@ -1371,7 +1280,9 @@ function buildFetchRequest({ httpOperation, mediaTypeContent, bodyInput, paramet
|
|
|
1371
1280
|
const serverUrl = getServerUrl({ httpOperation, mockData, chosenServer, corsProxy });
|
|
1372
1281
|
const shouldIncludeBody = ['PUT', 'POST', 'PATCH'].includes(httpOperation.method.toUpperCase());
|
|
1373
1282
|
const queryParams = (_c = (_b = (_a = httpOperation.request) === null || _a === void 0 ? void 0 : _a.query) === null || _b === void 0 ? void 0 : _b.map(param => { var _a; return ({ name: param.name, value: (_a = parameterValues[param.name]) !== null && _a !== void 0 ? _a : '' }); }).filter(({ value }) => value.length > 0)) !== null && _c !== void 0 ? _c : [];
|
|
1374
|
-
const rawHeaders = filterOutAuthorizationParams((_e = (_d = httpOperation.request) === null || _d === void 0 ? void 0 : _d.headers) !== null && _e !== void 0 ? _e : [], httpOperation.security)
|
|
1283
|
+
const rawHeaders = filterOutAuthorizationParams((_e = (_d = httpOperation.request) === null || _d === void 0 ? void 0 : _d.headers) !== null && _e !== void 0 ? _e : [], httpOperation.security)
|
|
1284
|
+
.map(header => { var _a; return ({ name: header.name, value: (_a = parameterValues[header.name]) !== null && _a !== void 0 ? _a : '' }); })
|
|
1285
|
+
.filter(({ value }) => value.length > 0);
|
|
1375
1286
|
const [queryParamsWithAuth, headersWithAuth] = runAuthRequestEhancements(auth, queryParams, rawHeaders);
|
|
1376
1287
|
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1377
1288
|
const url = new URL(URI__default["default"](serverUrl).segment(expandedPath).toString());
|
|
@@ -1659,9 +1570,9 @@ const bodyFormatMap = {
|
|
|
1659
1570
|
text: ['raw'],
|
|
1660
1571
|
};
|
|
1661
1572
|
const regex = {
|
|
1662
|
-
image: /image\/(
|
|
1663
|
-
json: /application\/(
|
|
1664
|
-
xml: /(text|application)\/(
|
|
1573
|
+
image: /image\/(.?)*(jpeg|gif|png|svg)/,
|
|
1574
|
+
json: /application\/(.?)*json/,
|
|
1575
|
+
xml: /(text|application)\/(.?)*(xml|html)/,
|
|
1665
1576
|
text: /text\/.*/,
|
|
1666
1577
|
};
|
|
1667
1578
|
function getResponseType(contentType) {
|
|
@@ -2396,14 +2307,14 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2396
2307
|
const Model = reactErrorBoundary.withErrorBoundary(ModelComponent, { recoverableProps: ['data'] });
|
|
2397
2308
|
|
|
2398
2309
|
const Docs = React__namespace.memo((_a) => {
|
|
2399
|
-
var { nodeType, nodeData, useNodeForRefResolving = false } = _a, commonProps = tslib.__rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving"]);
|
|
2310
|
+
var { nodeType, nodeData, useNodeForRefResolving = false, refResolver } = _a, commonProps = tslib.__rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver"]);
|
|
2400
2311
|
const parsedNode = useParsedData(nodeType, nodeData);
|
|
2401
2312
|
if (!parsedNode) {
|
|
2402
2313
|
return null;
|
|
2403
2314
|
}
|
|
2404
2315
|
const parsedDocs = React__namespace.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
|
|
2405
2316
|
if (useNodeForRefResolving) {
|
|
2406
|
-
return React__namespace.createElement(InlineRefResolverProvider, { document: parsedNode.data }, parsedDocs);
|
|
2317
|
+
return (React__namespace.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, parsedDocs));
|
|
2407
2318
|
}
|
|
2408
2319
|
return parsedDocs;
|
|
2409
2320
|
});
|
|
@@ -2438,7 +2349,7 @@ const SidebarLayout = React__namespace.forwardRef(({ sidebar, children, maxConte
|
|
|
2438
2349
|
paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
|
|
2439
2350
|
minWidth: `${sidebarWidth}px`,
|
|
2440
2351
|
} }, sidebar),
|
|
2441
|
-
React__namespace.createElement(mosaic.Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1,
|
|
2352
|
+
React__namespace.createElement(mosaic.Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full" },
|
|
2442
2353
|
React__namespace.createElement(mosaic.Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
|
|
2443
2354
|
});
|
|
2444
2355
|
|
|
@@ -2561,7 +2472,8 @@ const MarkdownComponentsProvider = ({ value, children }) => {
|
|
|
2561
2472
|
};
|
|
2562
2473
|
|
|
2563
2474
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
2564
|
-
const ReactRouterMarkdownLink = ({ title, href, children }) => {
|
|
2475
|
+
const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
2476
|
+
const href = to || _href;
|
|
2565
2477
|
const isExternal = href !== undefined && externalRegex.test(href);
|
|
2566
2478
|
if (isExternal) {
|
|
2567
2479
|
return (React__default["default"].createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
@@ -2807,7 +2719,7 @@ function withRouter(WrappedComponent) {
|
|
|
2807
2719
|
const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
|
|
2808
2720
|
return (React__namespace.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
2809
2721
|
React__namespace.createElement(reactRouterDom.Route, { path: "/" },
|
|
2810
|
-
React__namespace.createElement(MarkdownComponentsProvider, { value: {
|
|
2722
|
+
React__namespace.createElement(MarkdownComponentsProvider, { value: { a: ReactRouterMarkdownLink } },
|
|
2811
2723
|
React__namespace.createElement(WrappedComponent, Object.assign({}, props))))));
|
|
2812
2724
|
};
|
|
2813
2725
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
package/index.mjs
CHANGED
|
@@ -5,18 +5,15 @@ import { resolveInlineRef, isPlainObject as isPlainObject$1, safeParse, safeStri
|
|
|
5
5
|
import isArray from 'lodash/isArray.js';
|
|
6
6
|
import isObject from 'lodash/isObject.js';
|
|
7
7
|
import isPlainObject from 'lodash/isPlainObject.js';
|
|
8
|
-
import { parse } from '@stoplight/markdown';
|
|
9
8
|
import { NodeType, HttpParamStyles } from '@stoplight/types';
|
|
10
|
-
import { parse
|
|
11
|
-
import { isArray as isArray$1, Box,
|
|
9
|
+
import { parse } from '@stoplight/yaml';
|
|
10
|
+
import { isArray as isArray$1, Box, Panel, CopyButton, Menu, Button, Text, Flex, Input, Icon, Select, FieldButton, Image, Link, useThemeIsDark, HStack, VStack, InvertTheme, Tooltip, Badge, LinkHeading, Tabs, TabList, Tab, TabPanels, TabPanel, Heading, useClipboard, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
|
|
12
11
|
import { withErrorBoundary } from '@stoplight/react-error-boundary';
|
|
13
12
|
import { MarkdownViewer as MarkdownViewer$1, DefaultSMDComponents, MarkdownViewerProvider } from '@stoplight/markdown-viewer';
|
|
14
13
|
export { DefaultSMDComponents } from '@stoplight/markdown-viewer';
|
|
15
|
-
import { faStream, faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
16
|
-
import throttle from 'lodash/throttle.js';
|
|
17
|
-
import { selectAll } from 'unist-util-select';
|
|
18
14
|
import cn from 'classnames';
|
|
19
15
|
import { atomWithStorage, useAtomValue } from 'jotai/utils';
|
|
16
|
+
import { faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
20
17
|
import { atom, useAtom, Provider } from 'jotai';
|
|
21
18
|
import URI from 'urijs';
|
|
22
19
|
import { CodeViewer } from '@stoplight/mosaic-code-viewer';
|
|
@@ -164,13 +161,7 @@ const parserMap = {
|
|
|
164
161
|
[NodeType.Unknown]: parseUnknown,
|
|
165
162
|
};
|
|
166
163
|
function parseArticleData(rawData) {
|
|
167
|
-
if (typeof rawData === 'string') {
|
|
168
|
-
return {
|
|
169
|
-
type: NodeType.Article,
|
|
170
|
-
data: parse(rawData),
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
if (isSMDASTRoot(rawData)) {
|
|
164
|
+
if (typeof rawData === 'string' || isSMDASTRoot(rawData)) {
|
|
174
165
|
return {
|
|
175
166
|
type: NodeType.Article,
|
|
176
167
|
data: rawData,
|
|
@@ -213,7 +204,7 @@ function tryParseYamlOrObject(yamlOrObject) {
|
|
|
213
204
|
return yamlOrObject;
|
|
214
205
|
if (typeof yamlOrObject === 'string') {
|
|
215
206
|
try {
|
|
216
|
-
return parse
|
|
207
|
+
return parse(yamlOrObject);
|
|
217
208
|
}
|
|
218
209
|
catch (e) { }
|
|
219
210
|
}
|
|
@@ -228,94 +219,9 @@ const MarkdownViewer = (props) => {
|
|
|
228
219
|
};
|
|
229
220
|
MarkdownViewer.displayName = 'MarkdownViewer';
|
|
230
221
|
|
|
231
|
-
function useComponentSize(container) {
|
|
232
|
-
const [componentSize, setComponentSize] = React.useState({ width: 0, height: 0 });
|
|
233
|
-
React.useEffect(() => {
|
|
234
|
-
if (!container) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
const updateComponentSize = throttle(() => (container ? setComponentSize(container.getBoundingClientRect()) : { width: 0, height: 0 }), 1000, {
|
|
238
|
-
trailing: true,
|
|
239
|
-
});
|
|
240
|
-
updateComponentSize();
|
|
241
|
-
window.addEventListener('resize', updateComponentSize);
|
|
242
|
-
return () => {
|
|
243
|
-
updateComponentSize.cancel();
|
|
244
|
-
window.removeEventListener('resize', updateComponentSize);
|
|
245
|
-
};
|
|
246
|
-
}, [container]);
|
|
247
|
-
return componentSize;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function useComputeMarkdownHeadings(tree) {
|
|
251
|
-
return React.useMemo(() => computeMarkdownHeadings(tree), [tree]);
|
|
252
|
-
}
|
|
253
|
-
function computeMarkdownHeadings(tree) {
|
|
254
|
-
return selectAll(':root > [type=heading]', tree)
|
|
255
|
-
.map((heading) => {
|
|
256
|
-
var _a;
|
|
257
|
-
return ({
|
|
258
|
-
title: findTitle(heading),
|
|
259
|
-
id: ((_a = heading.data) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
260
|
-
depth: heading.depth - 1,
|
|
261
|
-
});
|
|
262
|
-
})
|
|
263
|
-
.filter((item) => item.depth >= 1 && item.depth <= 2);
|
|
264
|
-
}
|
|
265
|
-
const findTitle = (parent) => {
|
|
266
|
-
return selectAll('[type=text]', parent).map(textNode => String(textNode.value)).join(' ');
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
function useLocationHash() {
|
|
270
|
-
const isBrowser = typeof window !== 'undefined';
|
|
271
|
-
const [locationHash, setLocationHash] = React.useState(isBrowser && window.location.hash);
|
|
272
|
-
React.useEffect(() => {
|
|
273
|
-
if (!isBrowser)
|
|
274
|
-
return;
|
|
275
|
-
const hashChange = () => setLocationHash(window.location.hash);
|
|
276
|
-
window.addEventListener('hashchange', hashChange, false);
|
|
277
|
-
return () => window.removeEventListener('hashchange', hashChange);
|
|
278
|
-
}, [isBrowser]);
|
|
279
|
-
return locationHash;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const ArticleHeadings = ({ tree, container }) => {
|
|
283
|
-
const { width } = useComponentSize(container);
|
|
284
|
-
const showHeadings = width >= 768;
|
|
285
|
-
const headings = useComputeMarkdownHeadings(tree);
|
|
286
|
-
return React.createElement(Headings, { className: "ArticleHeadings", headings: headings, minimal: !showHeadings, maxWidth: 300 });
|
|
287
|
-
};
|
|
288
|
-
const Headings = ({ headings, className, title = 'On This Page', minimal, maxWidth }) => {
|
|
289
|
-
const locationHash = useLocationHash();
|
|
290
|
-
if (!headings || !headings.length)
|
|
291
|
-
return null;
|
|
292
|
-
const component = (React.createElement(Box, { overflowY: "auto", style: { maxHeight: '85vh', maxWidth } },
|
|
293
|
-
title && (React.createElement(Flex, { py: 2, alignItems: "center", fontSize: "sm", fontWeight: "medium", color: "muted", style: { paddingLeft: 18 } },
|
|
294
|
-
React.createElement(Box, { as: Icon, icon: faStream, mr: 2 }),
|
|
295
|
-
title)),
|
|
296
|
-
headings.map((heading, i) => (React.createElement(Heading, { key: i, item: heading, isSelected: locationHash === `#${heading.id}` })))));
|
|
297
|
-
const button = React.createElement(Button, { pos: "sticky", size: "sm", borderColor: "light", icon: faStream, style: { top: 10 } });
|
|
298
|
-
if (minimal) {
|
|
299
|
-
return (React.createElement(Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
|
|
300
|
-
React.createElement(Popover, { renderTrigger: button, placement: "bottom" },
|
|
301
|
-
React.createElement(Box, { className: className }, component))));
|
|
302
|
-
}
|
|
303
|
-
return (React.createElement(Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
|
|
304
|
-
React.createElement(Box, { borderL: true, borderColor: "light" }, component)));
|
|
305
|
-
};
|
|
306
|
-
const Heading = ({ item, isSelected }) => {
|
|
307
|
-
return (React.createElement(Box, { as: "a", href: `#${item.id}`, textOverflow: "truncate", display: "block", py: 2, pr: 8, fontWeight: "medium", fontSize: "sm", color: isSelected ? 'primary' : 'muted', style: { paddingLeft: `${3 + item.depth * 15}px` } }, item.title));
|
|
308
|
-
};
|
|
309
|
-
|
|
310
222
|
const ArticleComponent = React.memo(({ data }) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (tree === null)
|
|
314
|
-
return null;
|
|
315
|
-
return (React.createElement(Flex, { className: "sl-elements-article", justifyContent: "evenly", w: "full", pos: "relative", ref: setContainer },
|
|
316
|
-
React.createElement(Box, { className: "sl-elements-article-content", style: { width: 0 }, flex: 1 },
|
|
317
|
-
React.createElement(MarkdownViewer, { markdown: tree })),
|
|
318
|
-
React.createElement(ArticleHeadings, { tree: tree, container: container })));
|
|
223
|
+
return (React.createElement(Box, { className: "sl-elements-article" },
|
|
224
|
+
React.createElement(MarkdownViewer, { className: "sl-elements-article-content", markdown: data, includeToc: true })));
|
|
319
225
|
});
|
|
320
226
|
const Article = withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
|
|
321
227
|
|
|
@@ -1015,7 +921,11 @@ function parameterSupportsFileUpload(parameter) {
|
|
|
1015
921
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1016
922
|
}
|
|
1017
923
|
function exampleValue(example) {
|
|
1018
|
-
|
|
924
|
+
const value = 'value' in example ? example.value : example.externalValue;
|
|
925
|
+
return escapeQuotes(String(value));
|
|
926
|
+
}
|
|
927
|
+
function escapeQuotes(value) {
|
|
928
|
+
return value.replace(/"/g, '\\"');
|
|
1019
929
|
}
|
|
1020
930
|
function getPlaceholderForParameter(parameter) {
|
|
1021
931
|
var _a, _b;
|
|
@@ -1316,7 +1226,9 @@ function buildFetchRequest({ httpOperation, mediaTypeContent, bodyInput, paramet
|
|
|
1316
1226
|
const serverUrl = getServerUrl({ httpOperation, mockData, chosenServer, corsProxy });
|
|
1317
1227
|
const shouldIncludeBody = ['PUT', 'POST', 'PATCH'].includes(httpOperation.method.toUpperCase());
|
|
1318
1228
|
const queryParams = (_c = (_b = (_a = httpOperation.request) === null || _a === void 0 ? void 0 : _a.query) === null || _b === void 0 ? void 0 : _b.map(param => { var _a; return ({ name: param.name, value: (_a = parameterValues[param.name]) !== null && _a !== void 0 ? _a : '' }); }).filter(({ value }) => value.length > 0)) !== null && _c !== void 0 ? _c : [];
|
|
1319
|
-
const rawHeaders = filterOutAuthorizationParams((_e = (_d = httpOperation.request) === null || _d === void 0 ? void 0 : _d.headers) !== null && _e !== void 0 ? _e : [], httpOperation.security)
|
|
1229
|
+
const rawHeaders = filterOutAuthorizationParams((_e = (_d = httpOperation.request) === null || _d === void 0 ? void 0 : _d.headers) !== null && _e !== void 0 ? _e : [], httpOperation.security)
|
|
1230
|
+
.map(header => { var _a; return ({ name: header.name, value: (_a = parameterValues[header.name]) !== null && _a !== void 0 ? _a : '' }); })
|
|
1231
|
+
.filter(({ value }) => value.length > 0);
|
|
1320
1232
|
const [queryParamsWithAuth, headersWithAuth] = runAuthRequestEhancements(auth, queryParams, rawHeaders);
|
|
1321
1233
|
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1322
1234
|
const url = new URL(URI(serverUrl).segment(expandedPath).toString());
|
|
@@ -1604,9 +1516,9 @@ const bodyFormatMap = {
|
|
|
1604
1516
|
text: ['raw'],
|
|
1605
1517
|
};
|
|
1606
1518
|
const regex = {
|
|
1607
|
-
image: /image\/(
|
|
1608
|
-
json: /application\/(
|
|
1609
|
-
xml: /(text|application)\/(
|
|
1519
|
+
image: /image\/(.?)*(jpeg|gif|png|svg)/,
|
|
1520
|
+
json: /application\/(.?)*json/,
|
|
1521
|
+
xml: /(text|application)\/(.?)*(xml|html)/,
|
|
1610
1522
|
text: /text\/.*/,
|
|
1611
1523
|
};
|
|
1612
1524
|
function getResponseType(contentType) {
|
|
@@ -2171,7 +2083,7 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, la
|
|
|
2171
2083
|
const hasBadges = isDeprecated || isInternal;
|
|
2172
2084
|
const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React.createElement(VStack, { spacing: 5 },
|
|
2173
2085
|
React.createElement(HStack, { spacing: 5 },
|
|
2174
|
-
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading
|
|
2086
|
+
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading, { size: 1, fontWeight: "semibold" }, prettyName)) : null,
|
|
2175
2087
|
React.createElement(HStack, { spacing: 2 },
|
|
2176
2088
|
isDeprecated && React.createElement(DeprecatedBadge, null),
|
|
2177
2089
|
isInternal && React.createElement(InternalBadge, { isHttpService: true }))),
|
|
@@ -2295,7 +2207,7 @@ const HttpServiceComponent = React.memo(({ data, location = {}, layoutOptions, e
|
|
|
2295
2207
|
const query = new URLSearchParams(search);
|
|
2296
2208
|
return (React.createElement(Box, { mb: 10 },
|
|
2297
2209
|
data.name && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2298
|
-
React.createElement(Heading
|
|
2210
|
+
React.createElement(Heading, { size: 1, mb: 4, fontWeight: "semibold" }, data.name),
|
|
2299
2211
|
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps)))),
|
|
2300
2212
|
data.version && (React.createElement(Box, { mb: 5 },
|
|
2301
2213
|
React.createElement(VersionBadge, { value: data.version }))),
|
|
@@ -2326,7 +2238,7 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2326
2238
|
const shouldDisplayHeader = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (title !== undefined || (exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport)));
|
|
2327
2239
|
const header = (shouldDisplayHeader || isInternal) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2328
2240
|
React.createElement(HStack, { spacing: 5 },
|
|
2329
|
-
title && (React.createElement(Heading
|
|
2241
|
+
title && (React.createElement(Heading, { size: 1, fontWeight: "semibold" }, title)),
|
|
2330
2242
|
React.createElement(HStack, { spacing: 2 }, isInternal && React.createElement(InternalBadge, null))),
|
|
2331
2243
|
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps))));
|
|
2332
2244
|
const description = (React.createElement(VStack, { spacing: 10 },
|
|
@@ -2341,14 +2253,14 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2341
2253
|
const Model = withErrorBoundary(ModelComponent, { recoverableProps: ['data'] });
|
|
2342
2254
|
|
|
2343
2255
|
const Docs = React.memo((_a) => {
|
|
2344
|
-
var { nodeType, nodeData, useNodeForRefResolving = false } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving"]);
|
|
2256
|
+
var { nodeType, nodeData, useNodeForRefResolving = false, refResolver } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver"]);
|
|
2345
2257
|
const parsedNode = useParsedData(nodeType, nodeData);
|
|
2346
2258
|
if (!parsedNode) {
|
|
2347
2259
|
return null;
|
|
2348
2260
|
}
|
|
2349
2261
|
const parsedDocs = React.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
|
|
2350
2262
|
if (useNodeForRefResolving) {
|
|
2351
|
-
return React.createElement(InlineRefResolverProvider, { document: parsedNode.data }, parsedDocs);
|
|
2263
|
+
return (React.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, parsedDocs));
|
|
2352
2264
|
}
|
|
2353
2265
|
return parsedDocs;
|
|
2354
2266
|
});
|
|
@@ -2383,7 +2295,7 @@ const SidebarLayout = React.forwardRef(({ sidebar, children, maxContentWidth = M
|
|
|
2383
2295
|
paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
|
|
2384
2296
|
minWidth: `${sidebarWidth}px`,
|
|
2385
2297
|
} }, sidebar),
|
|
2386
|
-
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1,
|
|
2298
|
+
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full" },
|
|
2387
2299
|
React.createElement(Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
|
|
2388
2300
|
});
|
|
2389
2301
|
|
|
@@ -2412,7 +2324,7 @@ function useParsedValue(value) {
|
|
|
2412
2324
|
let parsedValue = value;
|
|
2413
2325
|
if (typeof value === 'string') {
|
|
2414
2326
|
try {
|
|
2415
|
-
parsedValue = parse
|
|
2327
|
+
parsedValue = parse(value);
|
|
2416
2328
|
}
|
|
2417
2329
|
catch (error) {
|
|
2418
2330
|
}
|
|
@@ -2506,7 +2418,8 @@ const MarkdownComponentsProvider = ({ value, children }) => {
|
|
|
2506
2418
|
};
|
|
2507
2419
|
|
|
2508
2420
|
const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
2509
|
-
const ReactRouterMarkdownLink = ({ title, href, children }) => {
|
|
2421
|
+
const ReactRouterMarkdownLink = ({ title, to, href: _href, children, }) => {
|
|
2422
|
+
const href = to || _href;
|
|
2510
2423
|
const isExternal = href !== undefined && externalRegex.test(href);
|
|
2511
2424
|
if (isExternal) {
|
|
2512
2425
|
return (React__default.createElement("a", { target: "_blank", rel: "noreferrer noopener", href: href, title: title }, children));
|
|
@@ -2685,7 +2598,7 @@ const Version = ({ value }) => {
|
|
|
2685
2598
|
const NonIdealState = ({ description, icon, title }) => {
|
|
2686
2599
|
return (React.createElement(Flex, { flexDirection: "col", alignItems: "center", justifyContent: "center", textAlign: "center", w: "full", h: "full" },
|
|
2687
2600
|
React.createElement(Box, { as: Icon, icon: icon || faExclamationTriangle, color: "light", fontSize: "6xl", mb: 4 }),
|
|
2688
|
-
React.createElement(Heading
|
|
2601
|
+
React.createElement(Heading, { size: 4, mb: 4 }, title),
|
|
2689
2602
|
React.createElement(Text, null, description)));
|
|
2690
2603
|
};
|
|
2691
2604
|
|
|
@@ -2752,7 +2665,7 @@ function withRouter(WrappedComponent) {
|
|
|
2752
2665
|
const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
|
|
2753
2666
|
return (React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
2754
2667
|
React.createElement(Route, { path: "/" },
|
|
2755
|
-
React.createElement(MarkdownComponentsProvider, { value: {
|
|
2668
|
+
React.createElement(MarkdownComponentsProvider, { value: { a: ReactRouterMarkdownLink } },
|
|
2756
2669
|
React.createElement(WrappedComponent, Object.assign({}, props))))));
|
|
2757
2670
|
};
|
|
2758
2671
|
WithRouter.displayName = `WithRouter(${getDisplayName(WrappedComponent)})`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stoplight/elements-core",
|
|
3
|
-
"version": "7.5.
|
|
3
|
+
"version": "7.5.9",
|
|
4
4
|
"main": "./index.js",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"web-components.min.js",
|
|
@@ -28,9 +28,8 @@
|
|
|
28
28
|
"@stoplight/json": "^3.10.0",
|
|
29
29
|
"@stoplight/json-schema-ref-parser": "^9.0.5",
|
|
30
30
|
"@stoplight/json-schema-sampler": "0.2.2",
|
|
31
|
-
"@stoplight/json-schema-viewer": "^4.
|
|
32
|
-
"@stoplight/markdown": "^
|
|
33
|
-
"@stoplight/markdown-viewer": "^5.3.2",
|
|
31
|
+
"@stoplight/json-schema-viewer": "^4.5.0",
|
|
32
|
+
"@stoplight/markdown-viewer": "^5.4.1",
|
|
34
33
|
"@stoplight/mosaic": "^1.15.2",
|
|
35
34
|
"@stoplight/mosaic-code-editor": "^1.15.2",
|
|
36
35
|
"@stoplight/mosaic-code-viewer": "^1.15.2",
|
|
@@ -49,7 +48,6 @@
|
|
|
49
48
|
"react-router-dom": "^5.2.0",
|
|
50
49
|
"react-router-hash-link": "^2.1.0",
|
|
51
50
|
"tslib": "^2.1.0",
|
|
52
|
-
"unist-util-select": "^3.0.1",
|
|
53
51
|
"urijs": "^1.19.6",
|
|
54
52
|
"util": "^0.12.4",
|
|
55
53
|
"xml-formatter": "^2.4.0"
|
package/types.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { IMarkdownViewerProps } from '@stoplight/markdown-viewer';
|
|
2
2
|
import { IHttpOperation, IHttpService, NodeType } from '@stoplight/types';
|
|
3
3
|
import { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
|
|
4
4
|
export declare type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
|
|
5
5
|
export declare type ParsedNode = {
|
|
6
6
|
type: NodeType.Article;
|
|
7
|
-
data:
|
|
7
|
+
data: IMarkdownViewerProps['markdown'];
|
|
8
8
|
} | {
|
|
9
9
|
type: NodeType.HttpOperation;
|
|
10
10
|
data: IHttpOperation;
|
|
@@ -105,15 +105,3 @@ export declare type ParamField = {
|
|
|
105
105
|
description: string;
|
|
106
106
|
example: string;
|
|
107
107
|
};
|
|
108
|
-
export interface IArticleHeading {
|
|
109
|
-
id: string;
|
|
110
|
-
title: string;
|
|
111
|
-
depth: number;
|
|
112
|
-
}
|
|
113
|
-
export interface IArticleHeadings {
|
|
114
|
-
headings: IArticleHeading[];
|
|
115
|
-
title?: string;
|
|
116
|
-
className?: string;
|
|
117
|
-
minimal?: boolean;
|
|
118
|
-
maxWidth?: number;
|
|
119
|
-
}
|
package/utils/guards.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { IMarkdownViewerProps } from '@stoplight/markdown-viewer';
|
|
2
2
|
import { IHttpOperation, IHttpService } from '@stoplight/types';
|
|
3
3
|
import { JSONSchema7 } from 'json-schema';
|
|
4
|
-
export declare function isSMDASTRoot(maybeAst: unknown): maybeAst is
|
|
4
|
+
export declare function isSMDASTRoot(maybeAst: unknown): maybeAst is IMarkdownViewerProps['markdown'];
|
|
5
5
|
export declare function isJSONSchema(maybeSchema: unknown): maybeSchema is JSONSchema7;
|
|
6
6
|
export declare function isHttpService(maybeHttpService: unknown): maybeHttpService is IHttpService;
|
|
7
7
|
export declare function isHttpOperation(maybeHttpOperation: unknown): maybeHttpOperation is IHttpOperation;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function useLocationHash(): string | false;
|