@stoplight/elements-core 7.4.0 → 7.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/Docs/HttpOperation/Body.d.ts +2 -1
- package/components/Docs/HttpOperation/Parameters.d.ts +0 -5
- package/components/Docs/Sections.d.ts +4 -1
- package/components/MosaicTableOfContents/types.d.ts +0 -1
- package/components/TryIt/Mocking/mocking-utils.d.ts +1 -2
- package/components/TryIt/Servers/ServersDropdown.d.ts +8 -0
- package/components/TryIt/build-request.d.ts +1 -1
- package/components/TryIt/chosenServer.d.ts +18 -0
- package/components/TryIt/index.d.ts +1 -0
- package/constants.d.ts +2 -0
- package/context/Persistence.d.ts +4 -1
- package/hooks/useRouter.d.ts +7 -5
- package/index.d.ts +1 -0
- package/index.esm.js +307 -196
- package/index.js +303 -194
- package/index.mjs +307 -196
- package/package.json +5 -5
- package/styles.min.css +1 -1
- package/types.d.ts +3 -1
- package/utils/http-spec/IServer.d.ts +1 -1
- package/utils/string.d.ts +1 -0
package/index.esm.js
CHANGED
|
@@ -8,14 +8,15 @@ import isPlainObject from 'lodash/isPlainObject.js';
|
|
|
8
8
|
import { parse } from '@stoplight/markdown';
|
|
9
9
|
import { NodeType, HttpParamStyles } from '@stoplight/types';
|
|
10
10
|
import { parse as parse$1 } from '@stoplight/yaml';
|
|
11
|
-
import { isArray as isArray$1, Box, Flex, Icon,
|
|
11
|
+
import { isArray as isArray$1, Box, Flex, Icon, Button, Popover, Panel, CopyButton, Menu, Text, Input, Select, FieldButton, Image, Link, useThemeIsDark, HStack, VStack, InvertTheme, Tooltip, Badge, LinkHeading, Tabs, TabList, Tab, TabPanels, TabPanel, Heading as Heading$1, useClipboard, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
|
|
12
12
|
import { withErrorBoundary } from '@stoplight/react-error-boundary';
|
|
13
13
|
import { MarkdownViewer as MarkdownViewer$1, DefaultSMDComponents, MarkdownViewerProvider } from '@stoplight/markdown-viewer';
|
|
14
14
|
export { DefaultSMDComponents } from '@stoplight/markdown-viewer';
|
|
15
|
-
import { faStream, faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
15
|
+
import { faStream, faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
|
|
16
16
|
import throttle from 'lodash/throttle.js';
|
|
17
17
|
import { selectAll } from 'unist-util-select';
|
|
18
18
|
import cn from 'classnames';
|
|
19
|
+
import { atomWithStorage, useAtomValue } from 'jotai/utils';
|
|
19
20
|
import { atom, useAtom, Provider } from 'jotai';
|
|
20
21
|
import URI from 'urijs';
|
|
21
22
|
import { CodeViewer } from '@stoplight/mosaic-code-viewer';
|
|
@@ -38,15 +39,11 @@ import uniq from 'lodash/uniq.js';
|
|
|
38
39
|
import orderBy from 'lodash/orderBy.js';
|
|
39
40
|
import uniqBy from 'lodash/uniqBy.js';
|
|
40
41
|
import formatXml from 'xml-formatter';
|
|
41
|
-
import { atomWithStorage } from 'jotai/utils';
|
|
42
42
|
import entries from 'lodash/entries.js';
|
|
43
43
|
import keys from 'lodash/keys.js';
|
|
44
|
-
import { JsonSchemaViewer
|
|
45
|
-
import get from 'lodash/get.js';
|
|
46
|
-
import isEmpty from 'lodash/isEmpty.js';
|
|
47
|
-
import omitBy from 'lodash/omitBy.js';
|
|
44
|
+
import { JsonSchemaViewer } from '@stoplight/json-schema-viewer';
|
|
48
45
|
import sortBy from 'lodash/sortBy.js';
|
|
49
|
-
import { useLocation, BrowserRouter, MemoryRouter, HashRouter, Route } from 'react-router-dom';
|
|
46
|
+
import { useLocation, BrowserRouter, MemoryRouter, HashRouter, StaticRouter, Route } from 'react-router-dom';
|
|
50
47
|
import { HashLink } from 'react-router-hash-link';
|
|
51
48
|
import { QueryClient, useQueryClient, QueryClientProvider } from 'react-query';
|
|
52
49
|
import $RefParser from '@stoplight/json-schema-ref-parser';
|
|
@@ -270,7 +267,7 @@ const findTitle = (parent) => {
|
|
|
270
267
|
};
|
|
271
268
|
|
|
272
269
|
function useLocationHash() {
|
|
273
|
-
const isBrowser = typeof window !== undefined;
|
|
270
|
+
const isBrowser = typeof window !== 'undefined';
|
|
274
271
|
const [locationHash, setLocationHash] = React.useState(isBrowser && window.location.hash);
|
|
275
272
|
React.useEffect(() => {
|
|
276
273
|
if (!isBrowser)
|
|
@@ -297,9 +294,10 @@ const Headings = ({ headings, className, title = 'On This Page', minimal, maxWid
|
|
|
297
294
|
React.createElement(Box, { as: Icon, icon: faStream, mr: 2 }),
|
|
298
295
|
title)),
|
|
299
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 } });
|
|
300
298
|
if (minimal) {
|
|
301
|
-
return (React.createElement(Box, { pos: "
|
|
302
|
-
React.createElement(Popover, { renderTrigger:
|
|
299
|
+
return (React.createElement(Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
|
|
300
|
+
React.createElement(Popover, { renderTrigger: button, placement: "bottom" },
|
|
303
301
|
React.createElement(Box, { className: className }, component))));
|
|
304
302
|
}
|
|
305
303
|
return (React.createElement(Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
|
|
@@ -321,20 +319,6 @@ const ArticleComponent = React.memo(({ data }) => {
|
|
|
321
319
|
});
|
|
322
320
|
const Article = withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
|
|
323
321
|
|
|
324
|
-
const MockingContext = createNamedContext('MockingContext', { mockUrl: undefined, hideMocking: undefined });
|
|
325
|
-
const MockingProvider = ({ mockUrl, hideMocking, children }) => {
|
|
326
|
-
const info = {
|
|
327
|
-
mockUrl,
|
|
328
|
-
hideMocking: hideMocking || !mockUrl,
|
|
329
|
-
};
|
|
330
|
-
return React.createElement(MockingContext.Provider, { value: info }, children);
|
|
331
|
-
};
|
|
332
|
-
function createNamedContext(name, defaultValue) {
|
|
333
|
-
const context = React.createContext(defaultValue);
|
|
334
|
-
context.displayName = name;
|
|
335
|
-
return context;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
322
|
const NodeTypeColors = {
|
|
339
323
|
http_operation: '#6a6acb',
|
|
340
324
|
http_service: '#e056fd',
|
|
@@ -451,10 +435,36 @@ const HttpCodeDescriptions = {
|
|
|
451
435
|
const badgeDefaultBackgroundColor = '#293742';
|
|
452
436
|
const badgeDefaultColor = '#FFFFFF';
|
|
453
437
|
|
|
454
|
-
const
|
|
455
|
-
|
|
456
|
-
|
|
438
|
+
const MockingContext = createNamedContext('MockingContext', { mockUrl: undefined, hideMocking: undefined });
|
|
439
|
+
const MockingProvider = ({ mockUrl, hideMocking, children }) => {
|
|
440
|
+
const info = {
|
|
441
|
+
mockUrl,
|
|
442
|
+
hideMocking: hideMocking || !mockUrl,
|
|
443
|
+
};
|
|
444
|
+
return React.createElement(MockingContext.Provider, { value: info }, children);
|
|
445
|
+
};
|
|
446
|
+
function createNamedContext(name, defaultValue) {
|
|
447
|
+
const context = React.createContext(defaultValue);
|
|
448
|
+
context.displayName = name;
|
|
449
|
+
return context;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const chosenServerAtom = atom(undefined);
|
|
453
|
+
|
|
454
|
+
const getServersToDisplay = (originalServers, mockUrl) => {
|
|
455
|
+
const servers = originalServers
|
|
456
|
+
.map((server, i) => {
|
|
457
|
+
const fallbackDescription = originalServers.length === 1 ? 'Live Server' : `Server ${i + 1}`;
|
|
458
|
+
return Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || fallbackDescription });
|
|
459
|
+
})
|
|
457
460
|
.filter(server => isProperUrl(server.url));
|
|
461
|
+
if (mockUrl) {
|
|
462
|
+
servers.push({
|
|
463
|
+
description: 'Mock Server',
|
|
464
|
+
url: mockUrl,
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
return servers;
|
|
458
468
|
};
|
|
459
469
|
const getServerUrlWithDefaultValues = (server) => {
|
|
460
470
|
var _a;
|
|
@@ -720,7 +730,12 @@ const RequestSamples = React__default.memo(({ request, embeddedInMd = false }) =
|
|
|
720
730
|
" ",
|
|
721
731
|
selectedLibrary ? ` / ${selectedLibrary}` : '')) }))),
|
|
722
732
|
React__default.createElement(Panel.Content, { p: 0 },
|
|
723
|
-
React__default.createElement(CodeViewer, { "aria-label": requestSample !== null && requestSample !== void 0 ? requestSample : fallbackText, noCopyButton: true, maxHeight: "400px", language: mosaicCodeViewerLanguage, value: requestSample || fallbackText
|
|
733
|
+
React__default.createElement(CodeViewer, { "aria-label": requestSample !== null && requestSample !== void 0 ? requestSample : fallbackText, noCopyButton: true, maxHeight: "400px", language: mosaicCodeViewerLanguage, value: requestSample || fallbackText, style: embeddedInMd
|
|
734
|
+
? undefined
|
|
735
|
+
:
|
|
736
|
+
{
|
|
737
|
+
'--fs-code': 12,
|
|
738
|
+
} }))));
|
|
724
739
|
});
|
|
725
740
|
|
|
726
741
|
function getReadableSecurityName(securityScheme, includeKey = false) {
|
|
@@ -885,7 +900,14 @@ const SecuritySchemeComponent = (_a) => {
|
|
|
885
900
|
};
|
|
886
901
|
const securitySchemeKeys = ['apiKey', 'http', 'oauth2', 'openIdConnect'];
|
|
887
902
|
|
|
888
|
-
const caseInsensitivelyEquals = curry((a, b) => a.toUpperCase() === b.toUpperCase());
|
|
903
|
+
const caseInsensitivelyEquals = curry((a, b) => a.toUpperCase() === b.toUpperCase());
|
|
904
|
+
function slugify(name) {
|
|
905
|
+
return name
|
|
906
|
+
.replace(/\/|{|}|\s/g, '-')
|
|
907
|
+
.replace(/-{2,}/, '-')
|
|
908
|
+
.replace(/^-/, '')
|
|
909
|
+
.replace(/-$/, '');
|
|
910
|
+
}
|
|
889
911
|
|
|
890
912
|
const isApiKeySecurityScheme = (maybeIApiKey) => isObject(maybeIApiKey) && maybeIApiKey.type === 'apiKey';
|
|
891
913
|
const isOAuth2SecurityScheme = (maybeIOAuth2) => isObject(maybeIOAuth2) && maybeIOAuth2.type === 'oauth2';
|
|
@@ -996,10 +1018,10 @@ function exampleValue(example) {
|
|
|
996
1018
|
}
|
|
997
1019
|
function getPlaceholderForParameter(parameter) {
|
|
998
1020
|
var _a, _b;
|
|
999
|
-
const parameterValue = getValueForParameter(parameter);
|
|
1021
|
+
const { value: parameterValue, isDefault } = getValueForParameter(parameter);
|
|
1000
1022
|
if (parameterValue)
|
|
1001
|
-
return
|
|
1002
|
-
return
|
|
1023
|
+
return `${isDefault ? 'defaults to' : 'example'}: ${parameterValue}`;
|
|
1024
|
+
return String((_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : '');
|
|
1003
1025
|
}
|
|
1004
1026
|
function retrieveDefaultFromSchema(parameter) {
|
|
1005
1027
|
var _a;
|
|
@@ -1008,22 +1030,25 @@ function retrieveDefaultFromSchema(parameter) {
|
|
|
1008
1030
|
}
|
|
1009
1031
|
const getValueForParameter = (parameter) => {
|
|
1010
1032
|
var _a, _b, _c;
|
|
1011
|
-
const examples = (_a = parameter.examples) !== null && _a !== void 0 ? _a : [];
|
|
1012
|
-
if (examples.length > 0)
|
|
1013
|
-
return exampleValue(examples[0]);
|
|
1014
1033
|
const defaultValue = retrieveDefaultFromSchema(parameter);
|
|
1015
|
-
if (defaultValue)
|
|
1016
|
-
return String(defaultValue);
|
|
1034
|
+
if (typeof defaultValue !== 'undefined') {
|
|
1035
|
+
return { value: String(defaultValue), isDefault: true };
|
|
1036
|
+
}
|
|
1037
|
+
const examples = (_a = parameter.examples) !== null && _a !== void 0 ? _a : [];
|
|
1038
|
+
if (examples.length > 0) {
|
|
1039
|
+
return { value: exampleValue(examples[0]) };
|
|
1040
|
+
}
|
|
1017
1041
|
const enums = (_c = (_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.enum) !== null && _c !== void 0 ? _c : [];
|
|
1018
|
-
if (enums.length > 0)
|
|
1019
|
-
return String(enums[0]);
|
|
1020
|
-
|
|
1042
|
+
if (enums.length > 0) {
|
|
1043
|
+
return { value: String(enums[0]) };
|
|
1044
|
+
}
|
|
1045
|
+
return { value: '' };
|
|
1021
1046
|
};
|
|
1022
1047
|
const getInitialValueForParameter = (parameter) => {
|
|
1023
1048
|
const isRequired = !!parameter.required;
|
|
1024
1049
|
if (!isRequired)
|
|
1025
1050
|
return '';
|
|
1026
|
-
return getValueForParameter(parameter);
|
|
1051
|
+
return getValueForParameter(parameter).value;
|
|
1027
1052
|
};
|
|
1028
1053
|
const initialParameterValues = params => {
|
|
1029
1054
|
const paramsByName = keyBy(params, (param) => param.name);
|
|
@@ -1168,7 +1193,9 @@ const RequestBody = ({ examples, requestBody, onChange }) => {
|
|
|
1168
1193
|
return (React.createElement(Panel, { defaultIsOpen: true },
|
|
1169
1194
|
React.createElement(Panel.Titlebar, { rightComponent: examples.length > 1 && React.createElement(ExampleMenu, { examples: examples, requestBody: requestBody, onChange: onChange }) }, "Body"),
|
|
1170
1195
|
React.createElement(Panel.Content, { className: "TextRequestBody" },
|
|
1171
|
-
React.createElement(CodeEditor, { onChange: onChange, language: "json", value: requestBody, showLineNumbers: true, padding: 0
|
|
1196
|
+
React.createElement(CodeEditor, { onChange: onChange, language: "json", value: requestBody, showLineNumbers: true, padding: 0, style: {
|
|
1197
|
+
fontSize: 12,
|
|
1198
|
+
} }))));
|
|
1172
1199
|
};
|
|
1173
1200
|
function ExampleMenu({ examples, requestBody, onChange }) {
|
|
1174
1201
|
const handleClick = React.useCallback((example) => {
|
|
@@ -1426,8 +1453,8 @@ const formatMultiValueHeader = (...keyValuePairs) => {
|
|
|
1426
1453
|
.join(', ');
|
|
1427
1454
|
};
|
|
1428
1455
|
|
|
1429
|
-
function getMockData(url, httpOperation, {
|
|
1430
|
-
return
|
|
1456
|
+
function getMockData(url, httpOperation, { code, dynamic, example }) {
|
|
1457
|
+
return url ? { url, header: buildPreferHeader({ code, dynamic, example }, httpOperation) } : undefined;
|
|
1431
1458
|
}
|
|
1432
1459
|
function buildPreferHeader({ code, example, dynamic }, httpOperation) {
|
|
1433
1460
|
if (!code) {
|
|
@@ -1460,23 +1487,14 @@ function supportsExample(httpOperation, code, exampleKey) {
|
|
|
1460
1487
|
return exampleKeys.includes(exampleKey);
|
|
1461
1488
|
}
|
|
1462
1489
|
|
|
1463
|
-
const MockingButton = ({ operation, options: {
|
|
1464
|
-
const toggleEnabled = React.useCallback(() => {
|
|
1465
|
-
onOptionsChange({ isEnabled: !isEnabled });
|
|
1466
|
-
}, [isEnabled, onOptionsChange]);
|
|
1490
|
+
const MockingButton = ({ operation, options: { code, example, dynamic }, onOptionsChange, }) => {
|
|
1467
1491
|
const operationResponses = operation.responses;
|
|
1468
1492
|
const setMockingOptions = React.useCallback(({ code, example, dynamic }) => {
|
|
1469
|
-
onOptionsChange({
|
|
1470
|
-
}, [
|
|
1493
|
+
onOptionsChange({ code, example, dynamic });
|
|
1494
|
+
}, [onOptionsChange]);
|
|
1471
1495
|
const menuItems = React.useMemo(() => {
|
|
1472
1496
|
var _a;
|
|
1473
|
-
const items =
|
|
1474
|
-
{ id: 'mocking-enabled', title: 'Enabled', isChecked: isEnabled, onPress: toggleEnabled },
|
|
1475
|
-
{
|
|
1476
|
-
type: 'group',
|
|
1477
|
-
children: (_a = operationResponses === null || operationResponses === void 0 ? void 0 : operationResponses.filter(operationResponse => Number.isInteger(parseFloat(operationResponse.code)))) === null || _a === void 0 ? void 0 : _a.map(generateOperationResponseMenu),
|
|
1478
|
-
},
|
|
1479
|
-
];
|
|
1497
|
+
const items = (_a = operationResponses === null || operationResponses === void 0 ? void 0 : operationResponses.filter(operationResponse => Number.isInteger(parseFloat(operationResponse.code)))) === null || _a === void 0 ? void 0 : _a.map(generateOperationResponseMenu);
|
|
1480
1498
|
function generateOperationResponseMenu(operationResponse) {
|
|
1481
1499
|
var _a;
|
|
1482
1500
|
const menuId = `response-${operationResponse.code}`;
|
|
@@ -1510,7 +1528,6 @@ const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic
|
|
|
1510
1528
|
];
|
|
1511
1529
|
const menuItem = {
|
|
1512
1530
|
id: menuId,
|
|
1513
|
-
isDisabled: !isEnabled,
|
|
1514
1531
|
isChecked: isActive,
|
|
1515
1532
|
title: operationResponse.code,
|
|
1516
1533
|
onPress: () => {
|
|
@@ -1524,13 +1541,13 @@ const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic
|
|
|
1524
1541
|
return menuItem;
|
|
1525
1542
|
}
|
|
1526
1543
|
return items;
|
|
1527
|
-
}, [code, dynamic, example,
|
|
1544
|
+
}, [code, dynamic, example, operationResponses, setMockingOptions]);
|
|
1528
1545
|
return (React.createElement(Box, null,
|
|
1529
|
-
React.createElement(Menu, { "aria-label": "
|
|
1546
|
+
React.createElement(Menu, { "aria-label": "Mock settings", items: menuItems, renderTrigger: ({ isOpen }) => (React.createElement(FieldButton, { active: isOpen, size: "sm" }, "Mock Settings")) })));
|
|
1530
1547
|
};
|
|
1531
1548
|
|
|
1532
|
-
const
|
|
1533
|
-
const useMockingOptions = () => useAtom(
|
|
1549
|
+
const mockingOptionsAtom = atom({});
|
|
1550
|
+
const useMockingOptions = () => useAtom(mockingOptionsAtom);
|
|
1534
1551
|
|
|
1535
1552
|
const OperationParameters = ({ parameters, values, onChangeValue, validate, }) => {
|
|
1536
1553
|
return (React.createElement(Panel, { defaultIsOpen: true },
|
|
@@ -1659,7 +1676,32 @@ class NetworkError extends Error {
|
|
|
1659
1676
|
}
|
|
1660
1677
|
const isNetworkError = (error) => error instanceof NetworkError;
|
|
1661
1678
|
|
|
1662
|
-
const
|
|
1679
|
+
const ServersDropdown = ({ servers }) => {
|
|
1680
|
+
const [chosenServer, setChosenServer] = useAtom(chosenServerAtom);
|
|
1681
|
+
const serverItems = [
|
|
1682
|
+
{
|
|
1683
|
+
type: 'option_group',
|
|
1684
|
+
title: 'Servers',
|
|
1685
|
+
value: (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || '',
|
|
1686
|
+
onChange: url => {
|
|
1687
|
+
const server = servers.find(server => server.url === url);
|
|
1688
|
+
setChosenServer(server);
|
|
1689
|
+
},
|
|
1690
|
+
children: [
|
|
1691
|
+
...servers.map((server, i) => ({
|
|
1692
|
+
id: server.url,
|
|
1693
|
+
title: server.name || server.description,
|
|
1694
|
+
description: server.name ? server.description || server.url : server.description ? server.url : undefined,
|
|
1695
|
+
value: server.url,
|
|
1696
|
+
})),
|
|
1697
|
+
],
|
|
1698
|
+
},
|
|
1699
|
+
];
|
|
1700
|
+
return (React.createElement(Menu, { "aria-label": "Server", items: serverItems, closeOnPress: true, renderTrigger: ({ isOpen }) => (React.createElement(FieldButton, { icon: faServer, size: "sm", active: isOpen }, (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.name) || (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.description) || 'Server')) }));
|
|
1701
|
+
};
|
|
1702
|
+
ServersDropdown.displayName = 'ServersDropdown';
|
|
1703
|
+
|
|
1704
|
+
const defaultServers = [];
|
|
1663
1705
|
const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embeddedInMd = false, tryItCredentialsPolicy, corsProxy, }) => {
|
|
1664
1706
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1665
1707
|
const isDark = useThemeIsDark();
|
|
@@ -1673,18 +1715,28 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1673
1715
|
const [bodyParameterValues, setBodyParameterValues, formDataState] = useBodyParameterState(mediaTypeContent);
|
|
1674
1716
|
const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
|
|
1675
1717
|
const [operationAuthValue, setOperationAuthValue] = usePersistedSecuritySchemeWithValues();
|
|
1676
|
-
const servers =
|
|
1718
|
+
const servers = React.useMemo(() => {
|
|
1719
|
+
const toDisplay = getServersToDisplay(httpOperation.servers || defaultServers, mockUrl);
|
|
1720
|
+
return toDisplay;
|
|
1721
|
+
}, [httpOperation.servers, mockUrl]);
|
|
1722
|
+
const firstServer = servers[0] || null;
|
|
1677
1723
|
const [chosenServer, setChosenServer] = useAtom(chosenServerAtom);
|
|
1724
|
+
const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
|
|
1678
1725
|
const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
|
|
1679
1726
|
React.useEffect(() => {
|
|
1680
|
-
|
|
1681
|
-
|
|
1727
|
+
const currentUrl = chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url;
|
|
1728
|
+
const exists = currentUrl && servers.find(s => s.url === currentUrl);
|
|
1729
|
+
if (!exists) {
|
|
1730
|
+
setChosenServer(firstServer);
|
|
1682
1731
|
}
|
|
1683
|
-
|
|
1732
|
+
else if (exists !== chosenServer) {
|
|
1733
|
+
setChosenServer(exists);
|
|
1734
|
+
}
|
|
1735
|
+
}, [servers, firstServer, chosenServer, setChosenServer]);
|
|
1684
1736
|
React.useEffect(() => {
|
|
1685
1737
|
let isMounted = true;
|
|
1686
1738
|
if (onRequestChange || embeddedInMd) {
|
|
1687
|
-
buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody, auth: operationAuthValue }, (
|
|
1739
|
+
buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
|
|
1688
1740
|
corsProxy })).then(request => {
|
|
1689
1741
|
if (isMounted) {
|
|
1690
1742
|
if (onRequestChange) {
|
|
@@ -1711,13 +1763,13 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1711
1763
|
corsProxy,
|
|
1712
1764
|
embeddedInMd,
|
|
1713
1765
|
]);
|
|
1714
|
-
const
|
|
1766
|
+
const handleSendRequest = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1715
1767
|
setValidateParameters(true);
|
|
1716
1768
|
if (hasRequiredButEmptyParameters)
|
|
1717
1769
|
return;
|
|
1718
1770
|
try {
|
|
1719
1771
|
setLoading(true);
|
|
1720
|
-
const mockData = getMockData(mockUrl, httpOperation, mockingOptions);
|
|
1772
|
+
const mockData = isMockingEnabled ? getMockData(mockUrl, httpOperation, mockingOptions) : undefined;
|
|
1721
1773
|
const request = yield buildFetchRequest({
|
|
1722
1774
|
parameterValues: parameterValuesWithDefaults,
|
|
1723
1775
|
httpOperation,
|
|
@@ -1754,29 +1806,32 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1754
1806
|
setLoading(false);
|
|
1755
1807
|
}
|
|
1756
1808
|
});
|
|
1757
|
-
const
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1809
|
+
const isOnlySendButton = !((_d = httpOperation.security) === null || _d === void 0 ? void 0 : _d.length) && !allParameters.length && !formDataState.isFormDataBody && !mediaTypeContent;
|
|
1810
|
+
const tryItPanelContents = (React.createElement(React.Fragment, null,
|
|
1811
|
+
((_e = httpOperation.security) === null || _e === void 0 ? void 0 : _e.length) ? (React.createElement(TryItAuth, { onChange: setOperationAuthValue, operationSecurityScheme: (_f = httpOperation.security) !== null && _f !== void 0 ? _f : [], value: operationAuthValue })) : null,
|
|
1812
|
+
allParameters.length > 0 && (React.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
|
|
1813
|
+
formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
|
|
1814
|
+
React.createElement(Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
|
|
1815
|
+
React.createElement(HStack, { alignItems: "center", spacing: 2 },
|
|
1816
|
+
React.createElement(Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
|
|
1817
|
+
servers.length > 1 && React.createElement(ServersDropdown, { servers: servers }),
|
|
1818
|
+
isMockingEnabled && (React.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
|
|
1819
|
+
validateParameters && hasRequiredButEmptyParameters && (React.createElement(Box, { mt: 4, color: "danger-light", fontSize: "sm" },
|
|
1820
|
+
React.createElement(Icon, { icon: faExclamationTriangle, className: "sl-mr-1" }),
|
|
1821
|
+
"You didn't provide all of the required parameters!")))));
|
|
1822
|
+
let tryItPanelElem;
|
|
1823
|
+
if (embeddedInMd) {
|
|
1824
|
+
tryItPanelElem = (React.createElement(Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
|
|
1825
|
+
React.createElement(Panel.Titlebar, { bg: "canvas-300" },
|
|
1826
|
+
React.createElement(Box, { fontWeight: "bold", color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
|
|
1827
|
+
React.createElement(Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${httpOperation.path}`)),
|
|
1828
|
+
tryItPanelContents));
|
|
1829
|
+
}
|
|
1830
|
+
else {
|
|
1831
|
+
tryItPanelElem = (React.createElement(Box, { className: "TryItPanel", bg: "canvas-100", rounded: "lg" }, tryItPanelContents));
|
|
1832
|
+
}
|
|
1764
1833
|
return (React.createElement(Box, { rounded: "lg", overflowY: "hidden" },
|
|
1765
|
-
|
|
1766
|
-
React.createElement(Panel.Titlebar, { rightComponent: servers.length > 1 ? serversSelect : serverDescription, bg: "canvas-300" },
|
|
1767
|
-
React.createElement("div", { role: "heading", className: "sl-font-bold" },
|
|
1768
|
-
React.createElement(Text, { color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
|
|
1769
|
-
React.createElement(Text, { ml: 2 }, httpOperation.path))),
|
|
1770
|
-
React.createElement(TryItAuth, { onChange: setOperationAuthValue, operationSecurityScheme: (_f = httpOperation.security) !== null && _f !== void 0 ? _f : [], value: operationAuthValue }),
|
|
1771
|
-
allParameters.length > 0 && (React.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
|
|
1772
|
-
formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
|
|
1773
|
-
React.createElement(Panel.Content, { className: "SendButtonHolder" },
|
|
1774
|
-
React.createElement(Flex, { alignItems: "center" },
|
|
1775
|
-
React.createElement(Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleClick, size: "sm" }, "Send Request"),
|
|
1776
|
-
mockUrl && (React.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
|
|
1777
|
-
validateParameters && hasRequiredButEmptyParameters && (React.createElement(Box, { mt: 4, color: "danger-light", fontSize: "sm" },
|
|
1778
|
-
React.createElement(Icon, { icon: faExclamationTriangle, className: "sl-mr-1" }),
|
|
1779
|
-
"You didn't provide all of the required parameters!")))),
|
|
1834
|
+
tryItPanelElem,
|
|
1780
1835
|
requestData && embeddedInMd && React.createElement(RequestSamples, { request: requestData, embeddedInMd: true }),
|
|
1781
1836
|
response && !('error' in response) && React.createElement(TryItResponse, { response: response }),
|
|
1782
1837
|
response && 'error' in response && React.createElement(ResponseError, { state: response })));
|
|
@@ -1813,7 +1868,9 @@ const ResponseExamples = ({ httpOperation, responseMediaType, responseStatusCode
|
|
|
1813
1868
|
const examplesSelect = userDefinedExamples && userDefinedExamples.length > 1 && (React__default.createElement(Select, { "aria-label": "Response Example", value: String(chosenExampleIndex), options: userDefinedExamples.map((example, index) => ({ value: index, label: example.key })), onChange: (value) => setChosenExampleIndex(parseInt(String(value), 10)), size: "sm", triggerTextPrefix: "Response Example: " }));
|
|
1814
1869
|
return (React__default.createElement(Panel, { rounded: true, isCollapsible: false },
|
|
1815
1870
|
React__default.createElement(Panel.Titlebar, null, examplesSelect || React__default.createElement(Text, { color: "body" }, "Response Example")),
|
|
1816
|
-
React__default.createElement(Panel.Content, { p: 0 }, show || !exceedsSize(responseExample) ? (React__default.createElement(CodeViewer, { "aria-label": responseExample, noCopyButton: true, maxHeight: "
|
|
1871
|
+
React__default.createElement(Panel.Content, { p: 0 }, show || !exceedsSize(responseExample) ? (React__default.createElement(CodeViewer, { "aria-label": responseExample, noCopyButton: true, maxHeight: "500px", language: "json", value: responseExample, showLineNumbers: true, style: {
|
|
1872
|
+
'--fs-code': 12,
|
|
1873
|
+
} })) : (React__default.createElement(LoadMore, { loading: loading, onClick: handleLoadMore })))));
|
|
1817
1874
|
};
|
|
1818
1875
|
|
|
1819
1876
|
const TryItWithRequestSamples = (_a) => {
|
|
@@ -1827,14 +1884,14 @@ const TryItWithRequestSamples = (_a) => {
|
|
|
1827
1884
|
React.createElement(ResponseExamples, Object.assign({}, props))));
|
|
1828
1885
|
};
|
|
1829
1886
|
|
|
1830
|
-
const TwoColumnLayout = ({ header, right, left, className }) => (React__default.createElement(
|
|
1887
|
+
const TwoColumnLayout = ({ header, right, left, className }) => (React__default.createElement(VStack, { w: "full", className: className, spacing: 8 },
|
|
1831
1888
|
header,
|
|
1832
|
-
React__default.createElement(Flex,
|
|
1889
|
+
React__default.createElement(Flex, null,
|
|
1833
1890
|
React__default.createElement(Box, { w: 0, flex: 1 }, left),
|
|
1834
1891
|
right && (React__default.createElement(Box, { ml: 16, pos: "relative", w: "2/5", style: { maxWidth: 500 } }, right)))));
|
|
1835
1892
|
|
|
1836
1893
|
const DeprecatedBadge = () => (React__default.createElement(Tooltip, { renderTrigger: React__default.createElement(Badge, { intent: "warning", icon: faExclamationCircle, "data-testid": "badge-deprecated" }, "Deprecated") }, "This operation has been marked as deprecated, which means it could be removed at some point in the future."));
|
|
1837
|
-
const InternalBadge = ({ isHttpService }) => (React__default.createElement(Tooltip, { renderTrigger: React__default.createElement(Badge, { icon: faEye, "data-testid": "badge-internal", bg: "danger"
|
|
1894
|
+
const InternalBadge = ({ isHttpService }) => (React__default.createElement(Tooltip, { renderTrigger: React__default.createElement(Badge, { icon: faEye, "data-testid": "badge-internal", bg: "danger" }, "Internal") }, `This ${isHttpService ? 'operation' : 'model'} is marked as internal and won't be visible in public docs.`));
|
|
1838
1895
|
const VersionBadge = ({ value, backgroundColor }) => (React__default.createElement(Badge, { appearance: "solid", size: "sm", border: 0, style: {
|
|
1839
1896
|
backgroundColor: backgroundColor || badgeDefaultBackgroundColor,
|
|
1840
1897
|
color: badgeDefaultColor,
|
|
@@ -1914,32 +1971,43 @@ ${scopes.map(([key, value]) => `- \`${key}\` - ${value}`).join('\n')}`;
|
|
|
1914
1971
|
return description;
|
|
1915
1972
|
}
|
|
1916
1973
|
|
|
1917
|
-
const SectionTitle = ({ title, children }) => {
|
|
1918
|
-
return (React.createElement(
|
|
1919
|
-
React.createElement(
|
|
1974
|
+
const SectionTitle = ({ title, id, size = 2, children }) => {
|
|
1975
|
+
return (React.createElement(HStack, { spacing: 6 },
|
|
1976
|
+
React.createElement(Box, { as: LinkHeading, size: size, "aria-label": title, id: id || slugify(title) }, title),
|
|
1920
1977
|
children));
|
|
1921
1978
|
};
|
|
1979
|
+
const SectionSubtitle = props => {
|
|
1980
|
+
return React.createElement(SectionTitle, Object.assign({}, props, { size: 3 }));
|
|
1981
|
+
};
|
|
1922
1982
|
const SubSectionPanel = ({ title, children, hasContent, rightComponent, defaultIsOpen = true, onChange, }) => {
|
|
1923
|
-
return (React.createElement(Panel, {
|
|
1983
|
+
return (React.createElement(Panel, { isCollapsible: hasContent, defaultIsOpen: defaultIsOpen, onChange: onChange, appearance: "outlined" },
|
|
1924
1984
|
React.createElement(Panel.Titlebar, { fontWeight: "medium", rightComponent: rightComponent },
|
|
1925
1985
|
React.createElement("div", { role: "heading" }, title)),
|
|
1926
|
-
hasContent !== false &&
|
|
1986
|
+
hasContent !== false && React.createElement(Panel.Content, null, children)));
|
|
1927
1987
|
};
|
|
1928
1988
|
|
|
1929
|
-
const
|
|
1989
|
+
const isBodyEmpty = (body) => {
|
|
1990
|
+
if (!body)
|
|
1991
|
+
return true;
|
|
1992
|
+
const { contents = [], description } = body;
|
|
1993
|
+
return contents.length === 0 && !(description === null || description === void 0 ? void 0 : description.trim());
|
|
1994
|
+
};
|
|
1995
|
+
const Body = ({ body, onChange }) => {
|
|
1930
1996
|
var _a;
|
|
1931
1997
|
const refResolver = useInlineRefResolver();
|
|
1932
1998
|
const [chosenContent, setChosenContent] = React.useState(0);
|
|
1933
1999
|
React.useEffect(() => {
|
|
1934
2000
|
onChange(chosenContent);
|
|
1935
2001
|
}, [chosenContent]);
|
|
1936
|
-
if (
|
|
2002
|
+
if (isBodyEmpty(body))
|
|
1937
2003
|
return null;
|
|
2004
|
+
const { contents = [], description } = body;
|
|
1938
2005
|
const schema = (_a = contents[chosenContent]) === null || _a === void 0 ? void 0 : _a.schema;
|
|
1939
|
-
return (React.createElement(
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
2006
|
+
return (React.createElement(VStack, { spacing: 6 },
|
|
2007
|
+
React.createElement(SectionSubtitle, { title: "Body", id: "request-body" }, contents.length > 0 && (React.createElement(Flex, { flex: 1, justify: "end" },
|
|
2008
|
+
React.createElement(Select, { "aria-label": "Request Body Content Type", value: String(chosenContent), onChange: (value) => setChosenContent(parseInt(String(value), 10)), options: contents.map((content, index) => ({ label: content.mediaType, value: index })), size: "sm" })))),
|
|
2009
|
+
description && React.createElement(MarkdownViewer, { markdown: description }),
|
|
2010
|
+
isJSONSchema(schema) && (React.createElement(JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", hideExamples: true, renderRootTreeLines: true }))));
|
|
1943
2011
|
};
|
|
1944
2012
|
Body.displayName = 'HttpOperation.Body';
|
|
1945
2013
|
|
|
@@ -1963,66 +2031,71 @@ const defaultStyle = {
|
|
|
1963
2031
|
cookie: HttpParamStyles.Form,
|
|
1964
2032
|
};
|
|
1965
2033
|
const Parameters = ({ parameters, parameterType }) => {
|
|
1966
|
-
|
|
2034
|
+
const schema = React.useMemo(() => httpOperationParamsToSchema({ parameters, parameterType }), [parameters, parameterType]);
|
|
2035
|
+
if (!schema)
|
|
1967
2036
|
return null;
|
|
1968
|
-
return
|
|
1969
|
-
return React.createElement(Parameter, { key: parameter.name, parameter: parameter, parameterType: parameterType });
|
|
1970
|
-
})));
|
|
2037
|
+
return React.createElement(JsonSchemaViewer, { schema: schema, disableCrumbs: true });
|
|
1971
2038
|
};
|
|
1972
2039
|
Parameters.displayName = 'HttpOperation.Parameters';
|
|
1973
|
-
const
|
|
1974
|
-
var _a
|
|
1975
|
-
if (!
|
|
2040
|
+
const httpOperationParamsToSchema = ({ parameters, parameterType }) => {
|
|
2041
|
+
var _a;
|
|
2042
|
+
if (!parameters || !parameters.length)
|
|
1976
2043
|
return null;
|
|
1977
|
-
const
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
const
|
|
1982
|
-
const
|
|
1983
|
-
if (
|
|
1984
|
-
|
|
2044
|
+
const schema = {
|
|
2045
|
+
properties: {},
|
|
2046
|
+
required: [],
|
|
2047
|
+
};
|
|
2048
|
+
const sortedParams = sortBy(parameters, ['required', 'name']);
|
|
2049
|
+
for (const p of sortedParams) {
|
|
2050
|
+
if (!p.schema)
|
|
2051
|
+
continue;
|
|
2052
|
+
const { name, description, required, deprecated, examples, style } = p;
|
|
2053
|
+
const paramExamples = (examples === null || examples === void 0 ? void 0 : examples.map(example => {
|
|
2054
|
+
if (isNodeExample(example)) {
|
|
2055
|
+
return example.value;
|
|
2056
|
+
}
|
|
2057
|
+
return example.externalValue;
|
|
2058
|
+
})) || [];
|
|
2059
|
+
const schemaExamples = (_a = p.schema) === null || _a === void 0 ? void 0 : _a.examples;
|
|
2060
|
+
const schemaExamplesArray = Array.isArray(schemaExamples) ? schemaExamples : [];
|
|
2061
|
+
const paramDescription = description || p.schema.description;
|
|
2062
|
+
const paramDeprecated = deprecated || p.schema.deprecated;
|
|
2063
|
+
const paramStyle = style && defaultStyle[parameterType] !== style ? readableStyles[style] || style : undefined;
|
|
2064
|
+
schema.properties[p.name] = Object.assign(Object.assign({}, p.schema), { description: paramDescription, examples: [...paramExamples, ...schemaExamplesArray], deprecated: paramDeprecated, style: paramStyle });
|
|
2065
|
+
if (required) {
|
|
2066
|
+
schema.required.push(name);
|
|
1985
2067
|
}
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
const schemaExamplesArray = Array.isArray(schemaExamples) ? schemaExamples : [];
|
|
1990
|
-
const validations = omitBy(Object.assign(Object.assign(Object.assign(Object.assign({}, omit(parameter, ['name', 'required', 'deprecated', 'description', 'schema', 'style', 'examples'])), omit(get(parameter, 'schema'), ['description', 'type', 'deprecated'])), omit(get(parameter, 'schema.items'), ['description', 'type', 'deprecated'])), { examples: [...parameterExamples, ...schemaExamplesArray] }), value => (typeof value === 'object' && isEmpty(value)) || typeof value === 'undefined');
|
|
1991
|
-
return (React.createElement(Box, { className: "HttpOperation__Parameters" },
|
|
1992
|
-
React.createElement(Flex, { alignItems: "center", my: 2 },
|
|
1993
|
-
React.createElement(Flex, { alignItems: "baseline", fontSize: "base", flex: 1 },
|
|
1994
|
-
React.createElement(Box, { fontFamily: "mono", fontWeight: "bold" }, parameter.name),
|
|
1995
|
-
React.createElement(Box, { ml: 2, color: "muted" }, format ? `${type}<${format}>` : type)),
|
|
1996
|
-
React.createElement(Box, { fontSize: "sm", color: "warning" },
|
|
1997
|
-
deprecated && (React.createElement(Box, { as: "span", ml: 2 }, "deprecated")),
|
|
1998
|
-
parameter.required && (React.createElement(Box, { as: "span", ml: 2 }, "required")))),
|
|
1999
|
-
description && (React.createElement(Box, { w: "full", color: "muted", fontSize: "sm", my: 2 },
|
|
2000
|
-
React.createElement(MarkdownViewer$1, { markdown: description }))),
|
|
2001
|
-
React.createElement(Box, { fontSize: "sm" },
|
|
2002
|
-
React.createElement(Validations, { validations: validations })),
|
|
2003
|
-
parameter.style && defaultStyle[parameterType] !== parameter.style && (React.createElement(Flex, { my: 2 },
|
|
2004
|
-
React.createElement(Box, { as: "span", px: 1, color: "muted", fontFamily: "mono", rounded: "lg", fontSize: "sm", textTransform: "capitalize", style: { backgroundColor: '#EDF2F7' } }, readableStyles[parameter.style] || parameter.style)))));
|
|
2005
|
-
};
|
|
2006
|
-
Parameter.displayName = 'HttpOperation.Parameter';
|
|
2068
|
+
}
|
|
2069
|
+
return schema;
|
|
2070
|
+
};
|
|
2007
2071
|
|
|
2008
|
-
const Request = ({ operation: {
|
|
2072
|
+
const Request = ({ operation: { request, request: { path: pathParams = [], headers: headerParams = [], cookie: cookieParams = [], body, query: queryParams = [], } = {}, security, }, onChange, }) => {
|
|
2009
2073
|
if (!request || typeof request !== 'object')
|
|
2010
2074
|
return null;
|
|
2075
|
+
const bodyIsEmpty = isBodyEmpty(body);
|
|
2011
2076
|
const securitySchemes = flatten(security);
|
|
2012
|
-
const
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2077
|
+
const hasRequestData = Boolean(securitySchemes.length ||
|
|
2078
|
+
pathParams.length ||
|
|
2079
|
+
queryParams.length ||
|
|
2080
|
+
headerParams.length ||
|
|
2081
|
+
cookieParams.length ||
|
|
2082
|
+
!bodyIsEmpty);
|
|
2083
|
+
if (!hasRequestData)
|
|
2084
|
+
return null;
|
|
2085
|
+
return (React.createElement(VStack, { spacing: 8 },
|
|
2017
2086
|
React.createElement(SectionTitle, { title: "Request" }),
|
|
2018
|
-
securitySchemes.map((scheme, i) => (React.createElement(SecurityPanel, { key: i, scheme: scheme, includeKey: shouldIncludeKey(securitySchemes, scheme.type) }))),
|
|
2019
|
-
React.createElement(
|
|
2020
|
-
React.createElement(
|
|
2021
|
-
|
|
2087
|
+
securitySchemes.length > 0 && (React.createElement(VStack, { spacing: 3 }, securitySchemes.map((scheme, i) => (React.createElement(SecurityPanel, { key: i, scheme: scheme, includeKey: shouldIncludeKey(securitySchemes, scheme.type) }))))),
|
|
2088
|
+
pathParams.length > 0 && (React.createElement(VStack, { spacing: 5 },
|
|
2089
|
+
React.createElement(SectionSubtitle, { title: "Path Parameters" }),
|
|
2090
|
+
React.createElement(Parameters, { parameterType: "path", parameters: pathParams }))),
|
|
2091
|
+
queryParams.length > 0 && (React.createElement(VStack, { spacing: 5 },
|
|
2092
|
+
React.createElement(SectionSubtitle, { title: "Query Parameters" }),
|
|
2022
2093
|
React.createElement(Parameters, { parameterType: "query", parameters: queryParams }))),
|
|
2023
|
-
headerParams.length > 0 && (React.createElement(
|
|
2094
|
+
headerParams.length > 0 && (React.createElement(VStack, { spacing: 5 },
|
|
2095
|
+
React.createElement(SectionSubtitle, { title: "Headers", id: "request-headers" }),
|
|
2024
2096
|
React.createElement(Parameters, { parameterType: "header", parameters: headerParams }))),
|
|
2025
|
-
cookieParams.length > 0 && (React.createElement(
|
|
2097
|
+
cookieParams.length > 0 && (React.createElement(VStack, { spacing: 5 },
|
|
2098
|
+
React.createElement(SectionSubtitle, { title: "Cookies", id: "request-cookies" }),
|
|
2026
2099
|
React.createElement(Parameters, { parameterType: "cookie", parameters: cookieParams }))),
|
|
2027
2100
|
body && React.createElement(Body, { onChange: onChange, body: body })));
|
|
2028
2101
|
};
|
|
@@ -2043,15 +2116,15 @@ const Responses = ({ responses: unsortedResponses, onStatusCodeChange, onMediaTy
|
|
|
2043
2116
|
}, [activeResponseId]);
|
|
2044
2117
|
if (!responses.length)
|
|
2045
2118
|
return null;
|
|
2046
|
-
return (React.createElement(
|
|
2047
|
-
React.createElement(
|
|
2048
|
-
React.createElement(
|
|
2049
|
-
|
|
2050
|
-
React.createElement(
|
|
2051
|
-
React.createElement(Response, { response: response, onMediaTypeChange: onMediaTypeChange }))))))));
|
|
2119
|
+
return (React.createElement(VStack, { spacing: 8, as: Tabs, selectedId: activeResponseId, onChange: setActiveResponseId, appearance: "pill" },
|
|
2120
|
+
React.createElement(SectionTitle, { title: "Responses" },
|
|
2121
|
+
React.createElement(TabList, { density: "compact" }, responses.map(({ code }) => (React.createElement(Tab, { key: code, id: code, intent: codeToIntentVal(code) }, code))))),
|
|
2122
|
+
React.createElement(TabPanels, { p: 0 }, responses.map(response => (React.createElement(TabPanel, { key: response.code, id: response.code },
|
|
2123
|
+
React.createElement(Response, { response: response, onMediaTypeChange: onMediaTypeChange })))))));
|
|
2052
2124
|
};
|
|
2053
2125
|
Responses.displayName = 'HttpOperation.Responses';
|
|
2054
|
-
const Response = ({ response
|
|
2126
|
+
const Response = ({ response, onMediaTypeChange }) => {
|
|
2127
|
+
const { contents = [], headers = [], description } = response;
|
|
2055
2128
|
const [chosenContent, setChosenContent] = React.useState(0);
|
|
2056
2129
|
const refResolver = useInlineRefResolver();
|
|
2057
2130
|
const responseContent = contents[chosenContent];
|
|
@@ -2059,14 +2132,31 @@ const Response = ({ response: { contents = [], headers = [], description }, onMe
|
|
|
2059
2132
|
React.useEffect(() => {
|
|
2060
2133
|
responseContent && onMediaTypeChange(responseContent.mediaType);
|
|
2061
2134
|
}, [responseContent]);
|
|
2062
|
-
return (React.createElement(
|
|
2063
|
-
description && React.createElement(MarkdownViewer, {
|
|
2064
|
-
headers.length > 0 && (React.createElement(
|
|
2135
|
+
return (React.createElement(VStack, { spacing: 8, pt: 8 },
|
|
2136
|
+
description && React.createElement(MarkdownViewer, { markdown: description }),
|
|
2137
|
+
headers.length > 0 && (React.createElement(VStack, { spacing: 5 },
|
|
2138
|
+
React.createElement(SectionSubtitle, { title: "Headers", id: "response-headers" }),
|
|
2065
2139
|
React.createElement(Parameters, { parameterType: "header", parameters: headers }))),
|
|
2066
|
-
contents.length > 0 && (React.createElement(
|
|
2067
|
-
React.createElement(
|
|
2140
|
+
contents.length > 0 && (React.createElement(React.Fragment, null,
|
|
2141
|
+
React.createElement(SectionSubtitle, { title: "Body", id: "response-body" },
|
|
2142
|
+
React.createElement(Flex, { flex: 1, justify: "end" },
|
|
2143
|
+
React.createElement(Select, { "aria-label": "Response Body Content Type", value: String(chosenContent), onChange: (value) => setChosenContent(parseInt(String(value), 10)), options: contents.map((content, index) => ({ label: content.mediaType, value: index })), size: "sm" }))),
|
|
2144
|
+
schema && (React.createElement(JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", hideExamples: true, parentCrumbs: ['responses', response.code], renderRootTreeLines: true }))))));
|
|
2068
2145
|
};
|
|
2069
|
-
Response.displayName = 'HttpOperation.Response';
|
|
2146
|
+
Response.displayName = 'HttpOperation.Response';
|
|
2147
|
+
const codeToIntentVal = (code) => {
|
|
2148
|
+
const firstChar = code.charAt(0);
|
|
2149
|
+
switch (firstChar) {
|
|
2150
|
+
case '2':
|
|
2151
|
+
return 'success';
|
|
2152
|
+
case '4':
|
|
2153
|
+
return 'warning';
|
|
2154
|
+
case '5':
|
|
2155
|
+
return 'danger';
|
|
2156
|
+
default:
|
|
2157
|
+
return 'default';
|
|
2158
|
+
}
|
|
2159
|
+
};
|
|
2070
2160
|
|
|
2071
2161
|
const HttpOperationComponent = React.memo(({ className, data: unresolvedData, layoutOptions, tryItCredentialsPolicy, tryItCorsProxy }) => {
|
|
2072
2162
|
const data = useResolvedObject(unresolvedData);
|
|
@@ -2076,13 +2166,16 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, la
|
|
|
2076
2166
|
const [responseMediaType, setResponseMediaType] = React.useState('');
|
|
2077
2167
|
const [responseStatusCode, setResponseStatusCode] = React.useState('');
|
|
2078
2168
|
const [requestBodyIndex, setTextRequestBodyIndex] = React.useState(0);
|
|
2169
|
+
const prettyName = (data.summary || data.iid || '').trim();
|
|
2079
2170
|
const hasBadges = isDeprecated || isInternal;
|
|
2080
|
-
const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React.createElement(
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2171
|
+
const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React.createElement(VStack, { spacing: 5 },
|
|
2172
|
+
React.createElement(HStack, { spacing: 5 },
|
|
2173
|
+
!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading$1, { size: 1, fontWeight: "semibold" }, prettyName)) : null,
|
|
2174
|
+
React.createElement(HStack, { spacing: 2 },
|
|
2175
|
+
isDeprecated && React.createElement(DeprecatedBadge, null),
|
|
2176
|
+
isInternal && React.createElement(InternalBadge, { isHttpService: true }))),
|
|
2177
|
+
React.createElement(MethodPath, { method: data.method, path: data.path })));
|
|
2178
|
+
const description = (React.createElement(VStack, { spacing: 10 },
|
|
2086
2179
|
data.description && React.createElement(MarkdownViewer, { className: "HttpOperation__Description", markdown: data.description }),
|
|
2087
2180
|
React.createElement(Request, { onChange: setTextRequestBodyIndex, operation: data }),
|
|
2088
2181
|
data.responses && (React.createElement(Responses, { responses: data.responses, onMediaTypeChange: setResponseMediaType, onStatusCodeChange: setResponseStatusCode }))));
|
|
@@ -2092,7 +2185,26 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, la
|
|
|
2092
2185
|
HttpOperationComponent.displayName = 'HttpOperation.Component';
|
|
2093
2186
|
const HttpOperation = withErrorBoundary(HttpOperationComponent, {
|
|
2094
2187
|
recoverableProps: ['data'],
|
|
2095
|
-
});
|
|
2188
|
+
});
|
|
2189
|
+
function MethodPath({ method, path }) {
|
|
2190
|
+
const chosenServer = useAtomValue(chosenServerAtom);
|
|
2191
|
+
let chosenServerUrl = '';
|
|
2192
|
+
if (chosenServer) {
|
|
2193
|
+
chosenServerUrl = chosenServer.url.endsWith('/') ? chosenServer.url.slice(0, -1) : chosenServer.url;
|
|
2194
|
+
}
|
|
2195
|
+
return (React.createElement(Box, null,
|
|
2196
|
+
React.createElement(MethodPathInner, { method: method, path: path, chosenServerUrl: chosenServerUrl })));
|
|
2197
|
+
}
|
|
2198
|
+
function MethodPathInner({ method, path, chosenServerUrl }) {
|
|
2199
|
+
const isDark = useThemeIsDark();
|
|
2200
|
+
const fullUrl = `${chosenServerUrl}${path}`;
|
|
2201
|
+
const pathElem = (React.createElement(Flex, { overflowX: "hidden" },
|
|
2202
|
+
chosenServerUrl ? (React.createElement(Box, { dir: "rtl", color: "muted", fontSize: "lg", textOverflow: "truncate", overflowX: "hidden" }, chosenServerUrl)) : null,
|
|
2203
|
+
React.createElement(Box, { fontSize: "lg", fontWeight: "semibold", flex: 1 }, path)));
|
|
2204
|
+
return (React.createElement(HStack, { spacing: 3, pl: 2.5, pr: 4, py: 2, bg: "canvas-50", rounded: "lg", fontFamily: "mono", display: "inline-flex", maxW: "full", title: fullUrl },
|
|
2205
|
+
React.createElement(Box, { py: 1, px: 2.5, rounded: "lg", bg: !isDark ? HttpMethodColors[method] : 'canvas-100', color: !isDark ? 'on-primary' : 'body', fontSize: "lg", fontWeight: "semibold", textTransform: "uppercase" }, method),
|
|
2206
|
+
pathElem));
|
|
2207
|
+
}
|
|
2096
2208
|
|
|
2097
2209
|
const PoweredByLink = ({ source, pathname, packageType, layout = 'sidebar' }) => {
|
|
2098
2210
|
return (React.createElement(Flex, { as: "a", align: "center", borderT: layout === 'stacked' ? undefined : true, px: layout === 'stacked' ? 1 : 4, py: 3, justify: layout === 'stacked' ? 'end' : undefined, href: `https://stoplight.io/?utm_source=${packageType}&utm_medium=${source}&utm_campaign=powered_by&utm_content=${pathname}`, target: "_blank", rel: "noopener noreferrer" },
|
|
@@ -2128,7 +2240,7 @@ const ExportButton = ({ original, bundled }) => {
|
|
|
2128
2240
|
return items;
|
|
2129
2241
|
}, [original, bundled]);
|
|
2130
2242
|
return (React.createElement(Box, null,
|
|
2131
|
-
React.createElement(Menu, { "aria-label": "Export", items: menuItems, renderTrigger: ({ isOpen }) => (React.createElement(Button, { iconRight: "chevron-down", appearance: "default", ml: 2, active: isOpen, size: "sm" }, "Export")) })));
|
|
2243
|
+
React.createElement(Menu, { "aria-label": "Export", items: menuItems, placement: "bottom right", renderTrigger: ({ isOpen }) => (React.createElement(Button, { iconRight: "chevron-down", appearance: "default", ml: 2, active: isOpen, size: "sm" }, "Export")) })));
|
|
2132
2244
|
};
|
|
2133
2245
|
|
|
2134
2246
|
const SecuritySchemes = ({ schemes, defaultScheme, defaultCollapsed = false, }) => {
|
|
@@ -2148,7 +2260,8 @@ const SecurityScheme = ({ scheme, defaultIsOpen, isCollapsible, showSchemeKey })
|
|
|
2148
2260
|
const ServerInfo = ({ servers, mockUrl }) => {
|
|
2149
2261
|
const mocking = React.useContext(MockingContext);
|
|
2150
2262
|
const showMocking = !mocking.hideMocking && mockUrl && isProperUrl(mockUrl);
|
|
2151
|
-
const
|
|
2263
|
+
const $mockUrl = showMocking ? mockUrl || mocking.mockUrl : undefined;
|
|
2264
|
+
const serversToDisplay = getServersToDisplay(servers, $mockUrl);
|
|
2152
2265
|
if (!showMocking && serversToDisplay.length === 0) {
|
|
2153
2266
|
return null;
|
|
2154
2267
|
}
|
|
@@ -2157,14 +2270,11 @@ const ServerInfo = ({ servers, mockUrl }) => {
|
|
|
2157
2270
|
React.createElement(Panel.Titlebar, { whitespace: "nowrap" }, "API Base URL"),
|
|
2158
2271
|
React.createElement(Box, { overflowX: "auto" },
|
|
2159
2272
|
React.createElement(Panel.Content, { w: "full", className: "sl-flex sl-flex-col" },
|
|
2160
|
-
serversToDisplay.map((server, index) => (React.createElement(ServerUrl, Object.assign({}, server, { key: index }))))
|
|
2161
|
-
showMocking && (React.createElement(React.Fragment, null,
|
|
2162
|
-
React.createElement(Box, { borderT: 2, pt: 2, borderColor: "light", w: "full" }),
|
|
2163
|
-
React.createElement(ServerUrl, { description: "Mock Server", url: mockUrl || '', marginBottom: false }))))))));
|
|
2273
|
+
React.createElement(VStack, { spacing: 1, divider: true }, serversToDisplay.map((server, index) => (React.createElement(ServerUrl, Object.assign({}, server, { key: index }))))))))));
|
|
2164
2274
|
};
|
|
2165
2275
|
const ServerUrl = ({ description, url, marginBottom = true }) => {
|
|
2166
2276
|
const { onCopy, hasCopied } = useClipboard(url);
|
|
2167
|
-
return (React.createElement(Box, { whitespace: "nowrap"
|
|
2277
|
+
return (React.createElement(Box, { whitespace: "nowrap" },
|
|
2168
2278
|
React.createElement(Text, { pr: 2, fontWeight: "bold" },
|
|
2169
2279
|
description,
|
|
2170
2280
|
":"),
|
|
@@ -2213,14 +2323,13 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
|
|
|
2213
2323
|
};
|
|
2214
2324
|
const examples = React.useMemo(() => generateExamplesFromJsonSchema(data), [data]);
|
|
2215
2325
|
const shouldDisplayHeader = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (title !== undefined || (exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport)));
|
|
2216
|
-
const header = (shouldDisplayHeader || isInternal) && (React.createElement(
|
|
2217
|
-
|
|
2218
|
-
React.createElement(Heading$1, { size: 1,
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
data.description && data.type === 'object' && (React.createElement(MarkdownViewer, { className: "sl-mb-6", role: "textbox", markdown: data.description })),
|
|
2326
|
+
const header = (shouldDisplayHeader || isInternal) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
|
|
2327
|
+
React.createElement(HStack, { spacing: 5 },
|
|
2328
|
+
title && (React.createElement(Heading$1, { size: 1, fontWeight: "semibold" }, title)),
|
|
2329
|
+
React.createElement(HStack, { spacing: 2 }, isInternal && React.createElement(InternalBadge, null))),
|
|
2330
|
+
exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps))));
|
|
2331
|
+
const description = (React.createElement(VStack, { spacing: 10 },
|
|
2332
|
+
data.description && data.type === 'object' && React.createElement(MarkdownViewer, { role: "textbox", markdown: data.description }),
|
|
2224
2333
|
React.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(data) })));
|
|
2225
2334
|
const examplesSelect = examples.length > 1 && (React.createElement(Select, { "aria-label": "Example", value: String(chosenExampleIndex), options: examples.map(({ label }, index) => ({ value: index, label })), onChange: (value) => setChosenExampleIndex(parseInt(String(value), 10)), size: "sm", triggerTextPrefix: "Example: " }));
|
|
2226
2335
|
const modelExamples = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideModelExamples) && (React.createElement(Panel, { rounded: true, isCollapsible: false },
|
|
@@ -2605,10 +2714,11 @@ const RouterComponent = {
|
|
|
2605
2714
|
history: BrowserRouter,
|
|
2606
2715
|
memory: MemoryRouter,
|
|
2607
2716
|
hash: HashRouter,
|
|
2717
|
+
static: StaticRouter,
|
|
2608
2718
|
};
|
|
2609
|
-
const useRouter = (router, basePath) => {
|
|
2719
|
+
const useRouter = (router, basePath, staticRouterPath) => {
|
|
2610
2720
|
const Router = RouterComponent[router];
|
|
2611
|
-
const routerProps = Object.assign({}, (router !== 'memory' && { basename: basePath }));
|
|
2721
|
+
const routerProps = Object.assign(Object.assign({}, (router !== 'memory' && { basename: basePath })), (router === 'static' && { location: staticRouterPath }));
|
|
2612
2722
|
return {
|
|
2613
2723
|
Router,
|
|
2614
2724
|
routerProps,
|
|
@@ -2617,9 +2727,10 @@ const useRouter = (router, basePath) => {
|
|
|
2617
2727
|
|
|
2618
2728
|
function withRouter(WrappedComponent) {
|
|
2619
2729
|
const WithRouter = (props) => {
|
|
2620
|
-
var _a, _b;
|
|
2730
|
+
var _a, _b, _c;
|
|
2621
2731
|
const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
|
|
2622
|
-
const
|
|
2732
|
+
const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
|
|
2733
|
+
const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
|
|
2623
2734
|
return (React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
|
|
2624
2735
|
React.createElement(Route, { path: "/" },
|
|
2625
2736
|
React.createElement(MarkdownComponentsProvider, { value: { link: ReactRouterMarkdownLink } },
|
|
@@ -2793,4 +2904,4 @@ const createElementClass = (Component, propDescriptors) => {
|
|
|
2793
2904
|
};
|
|
2794
2905
|
};
|
|
2795
2906
|
|
|
2796
|
-
export { DeprecatedBadge, Docs, ExportButton, HttpMethodColors, InlineRefResolverProvider, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, useBundleRefsIntoDocument, useParsedData, useParsedValue, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
|
|
2907
|
+
export { DeprecatedBadge, Docs, ExportButton, HttpMethodColors, InlineRefResolverProvider, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
|