@stoplight/elements-core 7.4.1 → 7.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -18,6 +18,7 @@ var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
18
18
  var throttle = require('lodash/throttle.js');
19
19
  var unistUtilSelect = require('unist-util-select');
20
20
  var cn = require('classnames');
21
+ var utils = require('jotai/utils');
21
22
  var jotai = require('jotai');
22
23
  var URI = require('urijs');
23
24
  var mosaicCodeViewer = require('@stoplight/mosaic-code-viewer');
@@ -40,13 +41,9 @@ var uniq = require('lodash/uniq.js');
40
41
  var orderBy = require('lodash/orderBy.js');
41
42
  var uniqBy = require('lodash/uniqBy.js');
42
43
  var formatXml = require('xml-formatter');
43
- var utils = require('jotai/utils');
44
44
  var entries = require('lodash/entries.js');
45
45
  var keys = require('lodash/keys.js');
46
46
  var jsonSchemaViewer = require('@stoplight/json-schema-viewer');
47
- var get = require('lodash/get.js');
48
- var isEmpty = require('lodash/isEmpty.js');
49
- var omitBy = require('lodash/omitBy.js');
50
47
  var sortBy = require('lodash/sortBy.js');
51
48
  var reactRouterDom = require('react-router-dom');
52
49
  var reactRouterHashLink = require('react-router-hash-link');
@@ -103,9 +100,6 @@ var uniqBy__default = /*#__PURE__*/_interopDefaultLegacy(uniqBy);
103
100
  var formatXml__default = /*#__PURE__*/_interopDefaultLegacy(formatXml);
104
101
  var entries__default = /*#__PURE__*/_interopDefaultLegacy(entries);
105
102
  var keys__default = /*#__PURE__*/_interopDefaultLegacy(keys);
106
- var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
107
- var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
108
- var omitBy__default = /*#__PURE__*/_interopDefaultLegacy(omitBy);
109
103
  var sortBy__default = /*#__PURE__*/_interopDefaultLegacy(sortBy);
110
104
  var $RefParser__default = /*#__PURE__*/_interopDefaultLegacy($RefParser);
111
105
  var PropTypes__namespace = /*#__PURE__*/_interopNamespace(PropTypes);
@@ -328,7 +322,7 @@ const findTitle = (parent) => {
328
322
  };
329
323
 
330
324
  function useLocationHash() {
331
- const isBrowser = typeof window !== undefined;
325
+ const isBrowser = typeof window !== 'undefined';
332
326
  const [locationHash, setLocationHash] = React__namespace.useState(isBrowser && window.location.hash);
333
327
  React__namespace.useEffect(() => {
334
328
  if (!isBrowser)
@@ -379,20 +373,6 @@ const ArticleComponent = React__namespace.memo(({ data }) => {
379
373
  });
380
374
  const Article = reactErrorBoundary.withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
381
375
 
382
- const MockingContext = createNamedContext('MockingContext', { mockUrl: undefined, hideMocking: undefined });
383
- const MockingProvider = ({ mockUrl, hideMocking, children }) => {
384
- const info = {
385
- mockUrl,
386
- hideMocking: hideMocking || !mockUrl,
387
- };
388
- return React__namespace.createElement(MockingContext.Provider, { value: info }, children);
389
- };
390
- function createNamedContext(name, defaultValue) {
391
- const context = React__namespace.createContext(defaultValue);
392
- context.displayName = name;
393
- return context;
394
- }
395
-
396
376
  const NodeTypeColors = {
397
377
  http_operation: '#6a6acb',
398
378
  http_service: '#e056fd',
@@ -509,10 +489,36 @@ const HttpCodeDescriptions = {
509
489
  const badgeDefaultBackgroundColor = '#293742';
510
490
  const badgeDefaultColor = '#FFFFFF';
511
491
 
512
- const getServersToDisplay = (originalServers) => {
513
- return originalServers
514
- .map((server, i) => (Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || `Server ${i + 1}` })))
492
+ const MockingContext = createNamedContext('MockingContext', { mockUrl: undefined, hideMocking: undefined });
493
+ const MockingProvider = ({ mockUrl, hideMocking, children }) => {
494
+ const info = {
495
+ mockUrl,
496
+ hideMocking: hideMocking || !mockUrl,
497
+ };
498
+ return React__namespace.createElement(MockingContext.Provider, { value: info }, children);
499
+ };
500
+ function createNamedContext(name, defaultValue) {
501
+ const context = React__namespace.createContext(defaultValue);
502
+ context.displayName = name;
503
+ return context;
504
+ }
505
+
506
+ const chosenServerAtom = jotai.atom(undefined);
507
+
508
+ const getServersToDisplay = (originalServers, mockUrl) => {
509
+ const servers = originalServers
510
+ .map((server, i) => {
511
+ const fallbackDescription = originalServers.length === 1 ? 'Live Server' : `Server ${i + 1}`;
512
+ return Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || fallbackDescription });
513
+ })
515
514
  .filter(server => isProperUrl(server.url));
515
+ if (mockUrl) {
516
+ servers.push({
517
+ description: 'Mock Server',
518
+ url: mockUrl,
519
+ });
520
+ }
521
+ return servers;
516
522
  };
517
523
  const getServerUrlWithDefaultValues = (server) => {
518
524
  var _a;
@@ -778,7 +784,12 @@ const RequestSamples = React__default["default"].memo(({ request, embeddedInMd =
778
784
  " ",
779
785
  selectedLibrary ? ` / ${selectedLibrary}` : '')) }))),
780
786
  React__default["default"].createElement(mosaic.Panel.Content, { p: 0 },
781
- React__default["default"].createElement(mosaicCodeViewer.CodeViewer, { "aria-label": requestSample !== null && requestSample !== void 0 ? requestSample : fallbackText, noCopyButton: true, maxHeight: "400px", language: mosaicCodeViewerLanguage, value: requestSample || fallbackText }))));
787
+ React__default["default"].createElement(mosaicCodeViewer.CodeViewer, { "aria-label": requestSample !== null && requestSample !== void 0 ? requestSample : fallbackText, noCopyButton: true, maxHeight: "400px", language: mosaicCodeViewerLanguage, value: requestSample || fallbackText, style: embeddedInMd
788
+ ? undefined
789
+ :
790
+ {
791
+ '--fs-code': 12,
792
+ } }))));
782
793
  });
783
794
 
784
795
  function getReadableSecurityName(securityScheme, includeKey = false) {
@@ -943,7 +954,14 @@ const SecuritySchemeComponent = (_a) => {
943
954
  };
944
955
  const securitySchemeKeys = ['apiKey', 'http', 'oauth2', 'openIdConnect'];
945
956
 
946
- const caseInsensitivelyEquals = curry__default["default"]((a, b) => a.toUpperCase() === b.toUpperCase());
957
+ const caseInsensitivelyEquals = curry__default["default"]((a, b) => a.toUpperCase() === b.toUpperCase());
958
+ function slugify(name) {
959
+ return name
960
+ .replace(/\/|{|}|\s/g, '-')
961
+ .replace(/-{2,}/, '-')
962
+ .replace(/^-/, '')
963
+ .replace(/-$/, '');
964
+ }
947
965
 
948
966
  const isApiKeySecurityScheme = (maybeIApiKey) => isObject__default["default"](maybeIApiKey) && maybeIApiKey.type === 'apiKey';
949
967
  const isOAuth2SecurityScheme = (maybeIOAuth2) => isObject__default["default"](maybeIOAuth2) && maybeIOAuth2.type === 'oauth2';
@@ -1054,10 +1072,10 @@ function exampleValue(example) {
1054
1072
  }
1055
1073
  function getPlaceholderForParameter(parameter) {
1056
1074
  var _a, _b;
1057
- const parameterValue = getValueForParameter(parameter);
1075
+ const { value: parameterValue, isDefault } = getValueForParameter(parameter);
1058
1076
  if (parameterValue)
1059
- return `example: ${parameterValue}`;
1060
- return parameterValue || String((_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : '');
1077
+ return `${isDefault ? 'defaults to' : 'example'}: ${parameterValue}`;
1078
+ return String((_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : '');
1061
1079
  }
1062
1080
  function retrieveDefaultFromSchema(parameter) {
1063
1081
  var _a;
@@ -1066,22 +1084,25 @@ function retrieveDefaultFromSchema(parameter) {
1066
1084
  }
1067
1085
  const getValueForParameter = (parameter) => {
1068
1086
  var _a, _b, _c;
1069
- const examples = (_a = parameter.examples) !== null && _a !== void 0 ? _a : [];
1070
- if (examples.length > 0)
1071
- return exampleValue(examples[0]);
1072
1087
  const defaultValue = retrieveDefaultFromSchema(parameter);
1073
- if (defaultValue)
1074
- return String(defaultValue);
1088
+ if (typeof defaultValue !== 'undefined') {
1089
+ return { value: String(defaultValue), isDefault: true };
1090
+ }
1091
+ const examples = (_a = parameter.examples) !== null && _a !== void 0 ? _a : [];
1092
+ if (examples.length > 0) {
1093
+ return { value: exampleValue(examples[0]) };
1094
+ }
1075
1095
  const enums = (_c = (_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.enum) !== null && _c !== void 0 ? _c : [];
1076
- if (enums.length > 0)
1077
- return String(enums[0]);
1078
- return '';
1096
+ if (enums.length > 0) {
1097
+ return { value: String(enums[0]) };
1098
+ }
1099
+ return { value: '' };
1079
1100
  };
1080
1101
  const getInitialValueForParameter = (parameter) => {
1081
1102
  const isRequired = !!parameter.required;
1082
1103
  if (!isRequired)
1083
1104
  return '';
1084
- return getValueForParameter(parameter);
1105
+ return getValueForParameter(parameter).value;
1085
1106
  };
1086
1107
  const initialParameterValues = params => {
1087
1108
  const paramsByName = keyBy__default["default"](params, (param) => param.name);
@@ -1226,7 +1247,9 @@ const RequestBody = ({ examples, requestBody, onChange }) => {
1226
1247
  return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
1227
1248
  React__namespace.createElement(mosaic.Panel.Titlebar, { rightComponent: examples.length > 1 && React__namespace.createElement(ExampleMenu, { examples: examples, requestBody: requestBody, onChange: onChange }) }, "Body"),
1228
1249
  React__namespace.createElement(mosaic.Panel.Content, { className: "TextRequestBody" },
1229
- React__namespace.createElement(mosaicCodeEditor.CodeEditor, { onChange: onChange, language: "json", value: requestBody, showLineNumbers: true, padding: 0 }))));
1250
+ React__namespace.createElement(mosaicCodeEditor.CodeEditor, { onChange: onChange, language: "json", value: requestBody, showLineNumbers: true, padding: 0, style: {
1251
+ fontSize: 12,
1252
+ } }))));
1230
1253
  };
1231
1254
  function ExampleMenu({ examples, requestBody, onChange }) {
1232
1255
  const handleClick = React__namespace.useCallback((example) => {
@@ -1484,8 +1507,8 @@ const formatMultiValueHeader = (...keyValuePairs) => {
1484
1507
  .join(', ');
1485
1508
  };
1486
1509
 
1487
- function getMockData(url, httpOperation, { isEnabled, code, dynamic, example }) {
1488
- return isEnabled && url ? { url, header: buildPreferHeader({ code, dynamic, example }, httpOperation) } : undefined;
1510
+ function getMockData(url, httpOperation, { code, dynamic, example }) {
1511
+ return url ? { url, header: buildPreferHeader({ code, dynamic, example }, httpOperation) } : undefined;
1489
1512
  }
1490
1513
  function buildPreferHeader({ code, example, dynamic }, httpOperation) {
1491
1514
  if (!code) {
@@ -1518,23 +1541,14 @@ function supportsExample(httpOperation, code, exampleKey) {
1518
1541
  return exampleKeys.includes(exampleKey);
1519
1542
  }
1520
1543
 
1521
- const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic }, onOptionsChange, }) => {
1522
- const toggleEnabled = React__namespace.useCallback(() => {
1523
- onOptionsChange({ isEnabled: !isEnabled });
1524
- }, [isEnabled, onOptionsChange]);
1544
+ const MockingButton = ({ operation, options: { code, example, dynamic }, onOptionsChange, }) => {
1525
1545
  const operationResponses = operation.responses;
1526
1546
  const setMockingOptions = React__namespace.useCallback(({ code, example, dynamic }) => {
1527
- onOptionsChange({ isEnabled, code, example, dynamic });
1528
- }, [isEnabled, onOptionsChange]);
1547
+ onOptionsChange({ code, example, dynamic });
1548
+ }, [onOptionsChange]);
1529
1549
  const menuItems = React__namespace.useMemo(() => {
1530
1550
  var _a;
1531
- const items = [
1532
- { id: 'mocking-enabled', title: 'Enabled', isChecked: isEnabled, onPress: toggleEnabled },
1533
- {
1534
- type: 'group',
1535
- 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),
1536
- },
1537
- ];
1551
+ 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);
1538
1552
  function generateOperationResponseMenu(operationResponse) {
1539
1553
  var _a;
1540
1554
  const menuId = `response-${operationResponse.code}`;
@@ -1568,7 +1582,6 @@ const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic
1568
1582
  ];
1569
1583
  const menuItem = {
1570
1584
  id: menuId,
1571
- isDisabled: !isEnabled,
1572
1585
  isChecked: isActive,
1573
1586
  title: operationResponse.code,
1574
1587
  onPress: () => {
@@ -1582,13 +1595,13 @@ const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic
1582
1595
  return menuItem;
1583
1596
  }
1584
1597
  return items;
1585
- }, [code, dynamic, example, isEnabled, operationResponses, setMockingOptions, toggleEnabled]);
1598
+ }, [code, dynamic, example, operationResponses, setMockingOptions]);
1586
1599
  return (React__namespace.createElement(mosaic.Box, null,
1587
- React__namespace.createElement(mosaic.Menu, { "aria-label": "Mocking", items: menuItems, renderTrigger: ({ isOpen }) => (React__namespace.createElement(mosaic.Button, { iconRight: "chevron-down", icon: isEnabled ? 'check' : undefined, appearance: isEnabled ? 'primary' : 'minimal', ml: 2, active: isOpen, size: "sm" }, "Mocking")) })));
1600
+ React__namespace.createElement(mosaic.Menu, { "aria-label": "Mock settings", items: menuItems, renderTrigger: ({ isOpen }) => (React__namespace.createElement(mosaic.FieldButton, { active: isOpen, size: "sm" }, "Mock Settings")) })));
1588
1601
  };
1589
1602
 
1590
- const persistedMockingOptionsAtom = jotai.atom({ isEnabled: false });
1591
- const useMockingOptions = () => jotai.useAtom(persistedMockingOptionsAtom);
1603
+ const mockingOptionsAtom = jotai.atom({});
1604
+ const useMockingOptions = () => jotai.useAtom(mockingOptionsAtom);
1592
1605
 
1593
1606
  const OperationParameters = ({ parameters, values, onChangeValue, validate, }) => {
1594
1607
  return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
@@ -1717,7 +1730,32 @@ class NetworkError extends Error {
1717
1730
  }
1718
1731
  const isNetworkError = (error) => error instanceof NetworkError;
1719
1732
 
1720
- const chosenServerAtom = jotai.atom(undefined);
1733
+ const ServersDropdown = ({ servers }) => {
1734
+ const [chosenServer, setChosenServer] = jotai.useAtom(chosenServerAtom);
1735
+ const serverItems = [
1736
+ {
1737
+ type: 'option_group',
1738
+ title: 'Servers',
1739
+ value: (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || '',
1740
+ onChange: url => {
1741
+ const server = servers.find(server => server.url === url);
1742
+ setChosenServer(server);
1743
+ },
1744
+ children: [
1745
+ ...servers.map((server, i) => ({
1746
+ id: server.url,
1747
+ title: server.name || server.description,
1748
+ description: server.name ? server.description || server.url : server.description ? server.url : undefined,
1749
+ value: server.url,
1750
+ })),
1751
+ ],
1752
+ },
1753
+ ];
1754
+ return (React__namespace.createElement(mosaic.Menu, { "aria-label": "Server", items: serverItems, closeOnPress: true, renderTrigger: ({ isOpen }) => (React__namespace.createElement(mosaic.FieldButton, { icon: freeSolidSvgIcons.faServer, size: "sm", active: isOpen }, (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.name) || (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.description) || 'Server')) }));
1755
+ };
1756
+ ServersDropdown.displayName = 'ServersDropdown';
1757
+
1758
+ const defaultServers = [];
1721
1759
  const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embeddedInMd = false, tryItCredentialsPolicy, corsProxy, }) => {
1722
1760
  var _a, _b, _c, _d, _e, _f, _g;
1723
1761
  const isDark = mosaic.useThemeIsDark();
@@ -1731,18 +1769,28 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1731
1769
  const [bodyParameterValues, setBodyParameterValues, formDataState] = useBodyParameterState(mediaTypeContent);
1732
1770
  const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
1733
1771
  const [operationAuthValue, setOperationAuthValue] = usePersistedSecuritySchemeWithValues();
1734
- const servers = getServersToDisplay(httpOperation.servers || []);
1772
+ const servers = React__namespace.useMemo(() => {
1773
+ const toDisplay = getServersToDisplay(httpOperation.servers || defaultServers, mockUrl);
1774
+ return toDisplay;
1775
+ }, [httpOperation.servers, mockUrl]);
1776
+ const firstServer = servers[0] || null;
1735
1777
  const [chosenServer, setChosenServer] = jotai.useAtom(chosenServerAtom);
1778
+ const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
1736
1779
  const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
1737
1780
  React__namespace.useEffect(() => {
1738
- if (!chosenServer) {
1739
- setChosenServer(servers[0]);
1781
+ const currentUrl = chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url;
1782
+ const exists = currentUrl && servers.find(s => s.url === currentUrl);
1783
+ if (!exists) {
1784
+ setChosenServer(firstServer);
1740
1785
  }
1741
- }, []);
1786
+ else if (exists !== chosenServer) {
1787
+ setChosenServer(exists);
1788
+ }
1789
+ }, [servers, firstServer, chosenServer, setChosenServer]);
1742
1790
  React__namespace.useEffect(() => {
1743
1791
  let isMounted = true;
1744
1792
  if (onRequestChange || embeddedInMd) {
1745
- buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody, auth: operationAuthValue }, (mockingOptions.isEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
1793
+ buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
1746
1794
  corsProxy })).then(request => {
1747
1795
  if (isMounted) {
1748
1796
  if (onRequestChange) {
@@ -1769,13 +1817,13 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1769
1817
  corsProxy,
1770
1818
  embeddedInMd,
1771
1819
  ]);
1772
- const handleClick = () => tslib.__awaiter(void 0, void 0, void 0, function* () {
1820
+ const handleSendRequest = () => tslib.__awaiter(void 0, void 0, void 0, function* () {
1773
1821
  setValidateParameters(true);
1774
1822
  if (hasRequiredButEmptyParameters)
1775
1823
  return;
1776
1824
  try {
1777
1825
  setLoading(true);
1778
- const mockData = getMockData(mockUrl, httpOperation, mockingOptions);
1826
+ const mockData = isMockingEnabled ? getMockData(mockUrl, httpOperation, mockingOptions) : undefined;
1779
1827
  const request = yield buildFetchRequest({
1780
1828
  parameterValues: parameterValuesWithDefaults,
1781
1829
  httpOperation,
@@ -1812,29 +1860,32 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1812
1860
  setLoading(false);
1813
1861
  }
1814
1862
  });
1815
- const serversSelect = (React__namespace.createElement(mosaic.Select, { "aria-label": "Servers", options: servers.map(server => ({ value: server.description || '' })), value: (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.description) || '', onChange: (value) => {
1816
- const server = servers.find(server => server.description === value);
1817
- setChosenServer(server);
1818
- } }));
1819
- const serverDescription = (React__namespace.createElement(mosaic.Tooltip, { renderTrigger: React__namespace.createElement(mosaic.Box, { ml: 2, mr: 1, flexShrink: 0 }, (_d = servers[0]) === null || _d === void 0 ? void 0 : _d.description) },
1820
- "Server Host: ", (_e = servers[0]) === null || _e === void 0 ? void 0 :
1821
- _e.url));
1863
+ const isOnlySendButton = !((_d = httpOperation.security) === null || _d === void 0 ? void 0 : _d.length) && !allParameters.length && !formDataState.isFormDataBody && !mediaTypeContent;
1864
+ const tryItPanelContents = (React__namespace.createElement(React__namespace.Fragment, null,
1865
+ ((_e = httpOperation.security) === null || _e === void 0 ? void 0 : _e.length) ? (React__namespace.createElement(TryItAuth, { onChange: setOperationAuthValue, operationSecurityScheme: (_f = httpOperation.security) !== null && _f !== void 0 ? _f : [], value: operationAuthValue })) : null,
1866
+ allParameters.length > 0 && (React__namespace.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
1867
+ formDataState.isFormDataBody ? (React__namespace.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues })) : mediaTypeContent ? (React__namespace.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
1868
+ React__namespace.createElement(mosaic.Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
1869
+ React__namespace.createElement(mosaic.HStack, { alignItems: "center", spacing: 2 },
1870
+ React__namespace.createElement(mosaic.Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
1871
+ servers.length > 1 && React__namespace.createElement(ServersDropdown, { servers: servers }),
1872
+ isMockingEnabled && (React__namespace.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
1873
+ validateParameters && hasRequiredButEmptyParameters && (React__namespace.createElement(mosaic.Box, { mt: 4, color: "danger-light", fontSize: "sm" },
1874
+ React__namespace.createElement(mosaic.Icon, { icon: freeSolidSvgIcons.faExclamationTriangle, className: "sl-mr-1" }),
1875
+ "You didn't provide all of the required parameters!")))));
1876
+ let tryItPanelElem;
1877
+ if (embeddedInMd) {
1878
+ tryItPanelElem = (React__namespace.createElement(mosaic.Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
1879
+ React__namespace.createElement(mosaic.Panel.Titlebar, { bg: "canvas-300" },
1880
+ React__namespace.createElement(mosaic.Box, { fontWeight: "bold", color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
1881
+ React__namespace.createElement(mosaic.Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${httpOperation.path}`)),
1882
+ tryItPanelContents));
1883
+ }
1884
+ else {
1885
+ tryItPanelElem = (React__namespace.createElement(mosaic.Box, { className: "TryItPanel", bg: "canvas-100", rounded: "lg" }, tryItPanelContents));
1886
+ }
1822
1887
  return (React__namespace.createElement(mosaic.Box, { rounded: "lg", overflowY: "hidden" },
1823
- React__namespace.createElement(mosaic.Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
1824
- React__namespace.createElement(mosaic.Panel.Titlebar, { rightComponent: servers.length > 1 ? serversSelect : serverDescription, bg: "canvas-300" },
1825
- React__namespace.createElement("div", { role: "heading", className: "sl-font-bold" },
1826
- React__namespace.createElement(mosaic.Text, { color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
1827
- React__namespace.createElement(mosaic.Text, { ml: 2 }, httpOperation.path))),
1828
- React__namespace.createElement(TryItAuth, { onChange: setOperationAuthValue, operationSecurityScheme: (_f = httpOperation.security) !== null && _f !== void 0 ? _f : [], value: operationAuthValue }),
1829
- allParameters.length > 0 && (React__namespace.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
1830
- formDataState.isFormDataBody ? (React__namespace.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues })) : mediaTypeContent ? (React__namespace.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
1831
- React__namespace.createElement(mosaic.Panel.Content, { className: "SendButtonHolder" },
1832
- React__namespace.createElement(mosaic.Flex, { alignItems: "center" },
1833
- React__namespace.createElement(mosaic.Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleClick, size: "sm" }, "Send Request"),
1834
- mockUrl && (React__namespace.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
1835
- validateParameters && hasRequiredButEmptyParameters && (React__namespace.createElement(mosaic.Box, { mt: 4, color: "danger-light", fontSize: "sm" },
1836
- React__namespace.createElement(mosaic.Icon, { icon: freeSolidSvgIcons.faExclamationTriangle, className: "sl-mr-1" }),
1837
- "You didn't provide all of the required parameters!")))),
1888
+ tryItPanelElem,
1838
1889
  requestData && embeddedInMd && React__namespace.createElement(RequestSamples, { request: requestData, embeddedInMd: true }),
1839
1890
  response && !('error' in response) && React__namespace.createElement(TryItResponse, { response: response }),
1840
1891
  response && 'error' in response && React__namespace.createElement(ResponseError, { state: response })));
@@ -1871,7 +1922,9 @@ const ResponseExamples = ({ httpOperation, responseMediaType, responseStatusCode
1871
1922
  const examplesSelect = userDefinedExamples && userDefinedExamples.length > 1 && (React__default["default"].createElement(mosaic.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: " }));
1872
1923
  return (React__default["default"].createElement(mosaic.Panel, { rounded: true, isCollapsible: false },
1873
1924
  React__default["default"].createElement(mosaic.Panel.Titlebar, null, examplesSelect || React__default["default"].createElement(mosaic.Text, { color: "body" }, "Response Example")),
1874
- React__default["default"].createElement(mosaic.Panel.Content, { p: 0 }, show || !exceedsSize(responseExample) ? (React__default["default"].createElement(mosaicCodeViewer.CodeViewer, { "aria-label": responseExample, noCopyButton: true, maxHeight: "400px", language: "json", value: responseExample, showLineNumbers: true })) : (React__default["default"].createElement(LoadMore, { loading: loading, onClick: handleLoadMore })))));
1925
+ React__default["default"].createElement(mosaic.Panel.Content, { p: 0 }, show || !exceedsSize(responseExample) ? (React__default["default"].createElement(mosaicCodeViewer.CodeViewer, { "aria-label": responseExample, noCopyButton: true, maxHeight: "500px", language: "json", value: responseExample, showLineNumbers: true, style: {
1926
+ '--fs-code': 12,
1927
+ } })) : (React__default["default"].createElement(LoadMore, { loading: loading, onClick: handleLoadMore })))));
1875
1928
  };
1876
1929
 
1877
1930
  const TryItWithRequestSamples = (_a) => {
@@ -1885,14 +1938,14 @@ const TryItWithRequestSamples = (_a) => {
1885
1938
  React__namespace.createElement(ResponseExamples, Object.assign({}, props))));
1886
1939
  };
1887
1940
 
1888
- const TwoColumnLayout = ({ header, right, left, className }) => (React__default["default"].createElement(mosaic.Box, { w: "full", className: className },
1941
+ const TwoColumnLayout = ({ header, right, left, className }) => (React__default["default"].createElement(mosaic.VStack, { w: "full", className: className, spacing: 8 },
1889
1942
  header,
1890
- React__default["default"].createElement(mosaic.Flex, { mt: header ? 12 : undefined },
1943
+ React__default["default"].createElement(mosaic.Flex, null,
1891
1944
  React__default["default"].createElement(mosaic.Box, { w: 0, flex: 1 }, left),
1892
1945
  right && (React__default["default"].createElement(mosaic.Box, { ml: 16, pos: "relative", w: "2/5", style: { maxWidth: 500 } }, right)))));
1893
1946
 
1894
1947
  const DeprecatedBadge = () => (React__default["default"].createElement(mosaic.Tooltip, { renderTrigger: React__default["default"].createElement(mosaic.Badge, { intent: "warning", icon: freeSolidSvgIcons.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."));
1895
- const InternalBadge = ({ isHttpService }) => (React__default["default"].createElement(mosaic.Tooltip, { renderTrigger: React__default["default"].createElement(mosaic.Badge, { icon: freeSolidSvgIcons.faEye, "data-testid": "badge-internal", bg: "danger", ml: 0 }, "Internal") }, `This ${isHttpService ? 'operation' : 'model'} is marked as internal and won't be visible in public docs.`));
1948
+ const InternalBadge = ({ isHttpService }) => (React__default["default"].createElement(mosaic.Tooltip, { renderTrigger: React__default["default"].createElement(mosaic.Badge, { icon: freeSolidSvgIcons.faEye, "data-testid": "badge-internal", bg: "danger" }, "Internal") }, `This ${isHttpService ? 'operation' : 'model'} is marked as internal and won't be visible in public docs.`));
1896
1949
  const VersionBadge = ({ value, backgroundColor }) => (React__default["default"].createElement(mosaic.Badge, { appearance: "solid", size: "sm", border: 0, style: {
1897
1950
  backgroundColor: backgroundColor || badgeDefaultBackgroundColor,
1898
1951
  color: badgeDefaultColor,
@@ -1972,32 +2025,43 @@ ${scopes.map(([key, value]) => `- \`${key}\` - ${value}`).join('\n')}`;
1972
2025
  return description;
1973
2026
  }
1974
2027
 
1975
- const SectionTitle = ({ title, children }) => {
1976
- return (React__namespace.createElement(mosaic.Flex, { role: "heading", borderB: true, mb: 3, pb: 3, "aria-label": title, align: "baseline" },
1977
- React__namespace.createElement(mosaic.Text, { size: "xl", fontWeight: "semibold", mr: 5 }, title),
2028
+ const SectionTitle = ({ title, id, size = 2, children }) => {
2029
+ return (React__namespace.createElement(mosaic.HStack, { spacing: 6 },
2030
+ React__namespace.createElement(mosaic.Box, { as: mosaic.LinkHeading, size: size, "aria-label": title, id: id || slugify(title) }, title),
1978
2031
  children));
1979
2032
  };
2033
+ const SectionSubtitle = props => {
2034
+ return React__namespace.createElement(SectionTitle, Object.assign({}, props, { size: 3 }));
2035
+ };
1980
2036
  const SubSectionPanel = ({ title, children, hasContent, rightComponent, defaultIsOpen = true, onChange, }) => {
1981
- return (React__namespace.createElement(mosaic.Panel, { appearance: "minimal", isCollapsible: hasContent, defaultIsOpen: defaultIsOpen, onChange: onChange },
2037
+ return (React__namespace.createElement(mosaic.Panel, { isCollapsible: hasContent, defaultIsOpen: defaultIsOpen, onChange: onChange, appearance: "outlined" },
1982
2038
  React__namespace.createElement(mosaic.Panel.Titlebar, { fontWeight: "medium", rightComponent: rightComponent },
1983
2039
  React__namespace.createElement("div", { role: "heading" }, title)),
1984
- hasContent !== false && (React__namespace.createElement(mosaic.Panel.Content, { pr: 3, pl: 6, p: 0 }, children))));
2040
+ hasContent !== false && React__namespace.createElement(mosaic.Panel.Content, null, children)));
1985
2041
  };
1986
2042
 
1987
- const Body = ({ body: { contents = [], description }, onChange }) => {
2043
+ const isBodyEmpty = (body) => {
2044
+ if (!body)
2045
+ return true;
2046
+ const { contents = [], description } = body;
2047
+ return contents.length === 0 && !(description === null || description === void 0 ? void 0 : description.trim());
2048
+ };
2049
+ const Body = ({ body, onChange }) => {
1988
2050
  var _a;
1989
2051
  const refResolver = useInlineRefResolver();
1990
2052
  const [chosenContent, setChosenContent] = React__namespace.useState(0);
1991
2053
  React__namespace.useEffect(() => {
1992
2054
  onChange(chosenContent);
1993
2055
  }, [chosenContent]);
1994
- if (contents.length === 0 && !description)
2056
+ if (isBodyEmpty(body))
1995
2057
  return null;
2058
+ const { contents = [], description } = body;
1996
2059
  const schema = (_a = contents[chosenContent]) === null || _a === void 0 ? void 0 : _a.schema;
1997
- return (React__namespace.createElement(SubSectionPanel, { title: "Body", rightComponent: contents.length > 0 && (React__namespace.createElement(mosaic.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" })) },
1998
- description && React__namespace.createElement(MarkdownViewer, { className: "sl-my-2", markdown: description }),
1999
- isJSONSchema(schema) && (React__namespace.createElement(mosaic.Box, null,
2000
- React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", hideExamples: true })))));
2060
+ return (React__namespace.createElement(mosaic.VStack, { spacing: 6 },
2061
+ React__namespace.createElement(SectionSubtitle, { title: "Body", id: "request-body" }, contents.length > 0 && (React__namespace.createElement(mosaic.Flex, { flex: 1, justify: "end" },
2062
+ React__namespace.createElement(mosaic.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" })))),
2063
+ description && React__namespace.createElement(MarkdownViewer, { markdown: description }),
2064
+ isJSONSchema(schema) && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", hideExamples: true, renderRootTreeLines: true }))));
2001
2065
  };
2002
2066
  Body.displayName = 'HttpOperation.Body';
2003
2067
 
@@ -2021,66 +2085,71 @@ const defaultStyle = {
2021
2085
  cookie: types.HttpParamStyles.Form,
2022
2086
  };
2023
2087
  const Parameters = ({ parameters, parameterType }) => {
2024
- if (!parameters || !parameters.length)
2088
+ const schema = React__namespace.useMemo(() => httpOperationParamsToSchema({ parameters, parameterType }), [parameters, parameterType]);
2089
+ if (!schema)
2025
2090
  return null;
2026
- return (React__namespace.createElement(mosaic.VStack, { spacing: 2, divider: React__namespace.createElement(mosaic.Box, { borderT: true, borderColor: "light", w: "full" }) }, sortBy__default["default"](parameters, ['required', 'name']).map(parameter => {
2027
- return React__namespace.createElement(Parameter, { key: parameter.name, parameter: parameter, parameterType: parameterType });
2028
- })));
2091
+ return React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: schema, disableCrumbs: true });
2029
2092
  };
2030
2093
  Parameters.displayName = 'HttpOperation.Parameters';
2031
- const Parameter = ({ parameter, parameterType }) => {
2032
- var _a, _b, _c, _d, _e;
2033
- if (!parameter)
2094
+ const httpOperationParamsToSchema = ({ parameters, parameterType }) => {
2095
+ var _a;
2096
+ if (!parameters || !parameters.length)
2034
2097
  return null;
2035
- const description = get__default["default"](parameter, 'description') || get__default["default"](parameter, 'schema.description');
2036
- const rootType = get__default["default"](parameter, 'schema.type', 'unknown');
2037
- const type = ((_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.items) === null || _b === void 0 ? void 0 : _b['type']) && rootType === 'array' ? `array[${parameter.schema.items['type']}]` : rootType;
2038
- const format = (_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.format;
2039
- const deprecated = get__default["default"](parameter, 'deprecated') || get__default["default"](parameter, 'schema.deprecated', false);
2040
- const parameterExamples = ((_d = parameter.examples) === null || _d === void 0 ? void 0 : _d.map(example => {
2041
- if (isNodeExample(example)) {
2042
- return example.value;
2098
+ const schema = {
2099
+ properties: {},
2100
+ required: [],
2101
+ };
2102
+ const sortedParams = sortBy__default["default"](parameters, ['required', 'name']);
2103
+ for (const p of sortedParams) {
2104
+ if (!p.schema)
2105
+ continue;
2106
+ const { name, description, required, deprecated, examples, style } = p;
2107
+ const paramExamples = (examples === null || examples === void 0 ? void 0 : examples.map(example => {
2108
+ if (isNodeExample(example)) {
2109
+ return example.value;
2110
+ }
2111
+ return example.externalValue;
2112
+ })) || [];
2113
+ const schemaExamples = (_a = p.schema) === null || _a === void 0 ? void 0 : _a.examples;
2114
+ const schemaExamplesArray = Array.isArray(schemaExamples) ? schemaExamples : [];
2115
+ const paramDescription = description || p.schema.description;
2116
+ const paramDeprecated = deprecated || p.schema.deprecated;
2117
+ const paramStyle = style && defaultStyle[parameterType] !== style ? readableStyles[style] || style : undefined;
2118
+ schema.properties[p.name] = Object.assign(Object.assign({}, p.schema), { description: paramDescription, examples: [...paramExamples, ...schemaExamplesArray], deprecated: paramDeprecated, style: paramStyle });
2119
+ if (required) {
2120
+ schema.required.push(name);
2043
2121
  }
2044
- return example.externalValue;
2045
- })) || [];
2046
- const schemaExamples = (_e = parameter.schema) === null || _e === void 0 ? void 0 : _e.examples;
2047
- const schemaExamplesArray = Array.isArray(schemaExamples) ? schemaExamples : [];
2048
- const validations = omitBy__default["default"](Object.assign(Object.assign(Object.assign(Object.assign({}, omit__default["default"](parameter, ['name', 'required', 'deprecated', 'description', 'schema', 'style', 'examples'])), omit__default["default"](get__default["default"](parameter, 'schema'), ['description', 'type', 'deprecated'])), omit__default["default"](get__default["default"](parameter, 'schema.items'), ['description', 'type', 'deprecated'])), { examples: [...parameterExamples, ...schemaExamplesArray] }), value => (typeof value === 'object' && isEmpty__default["default"](value)) || typeof value === 'undefined');
2049
- return (React__namespace.createElement(mosaic.Box, { className: "HttpOperation__Parameters" },
2050
- React__namespace.createElement(mosaic.Flex, { alignItems: "center", my: 2 },
2051
- React__namespace.createElement(mosaic.Flex, { alignItems: "baseline", fontSize: "base", flex: 1 },
2052
- React__namespace.createElement(mosaic.Box, { fontFamily: "mono", fontWeight: "bold" }, parameter.name),
2053
- React__namespace.createElement(mosaic.Box, { ml: 2, color: "muted" }, format ? `${type}<${format}>` : type)),
2054
- React__namespace.createElement(mosaic.Box, { fontSize: "sm", color: "warning" },
2055
- deprecated && (React__namespace.createElement(mosaic.Box, { as: "span", ml: 2 }, "deprecated")),
2056
- parameter.required && (React__namespace.createElement(mosaic.Box, { as: "span", ml: 2 }, "required")))),
2057
- description && (React__namespace.createElement(mosaic.Box, { w: "full", color: "muted", fontSize: "sm", my: 2 },
2058
- React__namespace.createElement(markdownViewer.MarkdownViewer, { markdown: description }))),
2059
- React__namespace.createElement(mosaic.Box, { fontSize: "sm" },
2060
- React__namespace.createElement(jsonSchemaViewer.Validations, { validations: validations })),
2061
- parameter.style && defaultStyle[parameterType] !== parameter.style && (React__namespace.createElement(mosaic.Flex, { my: 2 },
2062
- React__namespace.createElement(mosaic.Box, { as: "span", px: 1, color: "muted", fontFamily: "mono", rounded: "lg", fontSize: "sm", textTransform: "capitalize", style: { backgroundColor: '#EDF2F7' } }, readableStyles[parameter.style] || parameter.style)))));
2063
- };
2064
- Parameter.displayName = 'HttpOperation.Parameter';
2122
+ }
2123
+ return schema;
2124
+ };
2065
2125
 
2066
- const Request = ({ operation: { path, method, request, request: { path: pathParams = [], headers: headerParams = [], cookie: cookieParams = [], body, query: queryParams = [], } = {}, security, }, onChange, }) => {
2126
+ const Request = ({ operation: { request, request: { path: pathParams = [], headers: headerParams = [], cookie: cookieParams = [], body, query: queryParams = [], } = {}, security, }, onChange, }) => {
2067
2127
  if (!request || typeof request !== 'object')
2068
2128
  return null;
2129
+ const bodyIsEmpty = isBodyEmpty(body);
2069
2130
  const securitySchemes = flatten__default["default"](security);
2070
- const pathParamBlock = (React__namespace.createElement(mosaic.Box, null,
2071
- React__namespace.createElement(mosaic.Text, { textTransform: "uppercase", mr: 1, color: HttpMethodColors[method] }, method),
2072
- ' ',
2073
- path));
2074
- return (React__namespace.createElement(mosaic.Box, null,
2131
+ const hasRequestData = Boolean(securitySchemes.length ||
2132
+ pathParams.length ||
2133
+ queryParams.length ||
2134
+ headerParams.length ||
2135
+ cookieParams.length ||
2136
+ !bodyIsEmpty);
2137
+ if (!hasRequestData)
2138
+ return null;
2139
+ return (React__namespace.createElement(mosaic.VStack, { spacing: 8 },
2075
2140
  React__namespace.createElement(SectionTitle, { title: "Request" }),
2076
- securitySchemes.map((scheme, i) => (React__namespace.createElement(SecurityPanel, { key: i, scheme: scheme, includeKey: shouldIncludeKey(securitySchemes, scheme.type) }))),
2077
- React__namespace.createElement(SubSectionPanel, { title: pathParamBlock, hasContent: pathParams.length > 0 },
2078
- React__namespace.createElement(Parameters, { parameterType: "path", parameters: pathParams })),
2079
- queryParams.length > 0 && (React__namespace.createElement(SubSectionPanel, { title: "Query" },
2141
+ securitySchemes.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 3 }, securitySchemes.map((scheme, i) => (React__namespace.createElement(SecurityPanel, { key: i, scheme: scheme, includeKey: shouldIncludeKey(securitySchemes, scheme.type) }))))),
2142
+ pathParams.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2143
+ React__namespace.createElement(SectionSubtitle, { title: "Path Parameters" }),
2144
+ React__namespace.createElement(Parameters, { parameterType: "path", parameters: pathParams }))),
2145
+ queryParams.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2146
+ React__namespace.createElement(SectionSubtitle, { title: "Query Parameters" }),
2080
2147
  React__namespace.createElement(Parameters, { parameterType: "query", parameters: queryParams }))),
2081
- headerParams.length > 0 && (React__namespace.createElement(SubSectionPanel, { title: "Headers" },
2148
+ headerParams.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2149
+ React__namespace.createElement(SectionSubtitle, { title: "Headers", id: "request-headers" }),
2082
2150
  React__namespace.createElement(Parameters, { parameterType: "header", parameters: headerParams }))),
2083
- cookieParams.length > 0 && (React__namespace.createElement(SubSectionPanel, { title: "Cookie" },
2151
+ cookieParams.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2152
+ React__namespace.createElement(SectionSubtitle, { title: "Cookies", id: "request-cookies" }),
2084
2153
  React__namespace.createElement(Parameters, { parameterType: "cookie", parameters: cookieParams }))),
2085
2154
  body && React__namespace.createElement(Body, { onChange: onChange, body: body })));
2086
2155
  };
@@ -2101,15 +2170,15 @@ const Responses = ({ responses: unsortedResponses, onStatusCodeChange, onMediaTy
2101
2170
  }, [activeResponseId]);
2102
2171
  if (!responses.length)
2103
2172
  return null;
2104
- return (React__namespace.createElement(mosaic.Tabs, { selectedId: activeResponseId, onChange: setActiveResponseId },
2105
- React__namespace.createElement(mosaic.Box, null,
2106
- React__namespace.createElement(SectionTitle, { title: "Responses" },
2107
- React__namespace.createElement(mosaic.TabList, null, responses.map(({ code }) => (React__namespace.createElement(mosaic.Tab, { key: code, id: code }, code))))),
2108
- React__namespace.createElement(mosaic.Box, { as: mosaic.TabPanels, mt: 4 }, responses.map(response => (React__namespace.createElement(mosaic.TabPanel, { key: response.code, id: response.code },
2109
- React__namespace.createElement(Response, { response: response, onMediaTypeChange: onMediaTypeChange }))))))));
2173
+ return (React__namespace.createElement(mosaic.VStack, { spacing: 8, as: mosaic.Tabs, selectedId: activeResponseId, onChange: setActiveResponseId, appearance: "pill" },
2174
+ React__namespace.createElement(SectionTitle, { title: "Responses" },
2175
+ React__namespace.createElement(mosaic.TabList, { density: "compact" }, responses.map(({ code }) => (React__namespace.createElement(mosaic.Tab, { key: code, id: code, intent: codeToIntentVal(code) }, code))))),
2176
+ React__namespace.createElement(mosaic.TabPanels, { p: 0 }, responses.map(response => (React__namespace.createElement(mosaic.TabPanel, { key: response.code, id: response.code },
2177
+ React__namespace.createElement(Response, { response: response, onMediaTypeChange: onMediaTypeChange })))))));
2110
2178
  };
2111
2179
  Responses.displayName = 'HttpOperation.Responses';
2112
- const Response = ({ response: { contents = [], headers = [], description }, onMediaTypeChange }) => {
2180
+ const Response = ({ response, onMediaTypeChange }) => {
2181
+ const { contents = [], headers = [], description } = response;
2113
2182
  const [chosenContent, setChosenContent] = React__namespace.useState(0);
2114
2183
  const refResolver = useInlineRefResolver();
2115
2184
  const responseContent = contents[chosenContent];
@@ -2117,14 +2186,31 @@ const Response = ({ response: { contents = [], headers = [], description }, onMe
2117
2186
  React__namespace.useEffect(() => {
2118
2187
  responseContent && onMediaTypeChange(responseContent.mediaType);
2119
2188
  }, [responseContent]);
2120
- return (React__namespace.createElement(mosaic.Box, null,
2121
- description && React__namespace.createElement(MarkdownViewer, { className: "sl-ml-1 sl-mb-6", markdown: description }),
2122
- headers.length > 0 && (React__namespace.createElement(SubSectionPanel, { title: "Headers" },
2189
+ return (React__namespace.createElement(mosaic.VStack, { spacing: 8, pt: 8 },
2190
+ description && React__namespace.createElement(MarkdownViewer, { markdown: description }),
2191
+ headers.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2192
+ React__namespace.createElement(SectionSubtitle, { title: "Headers", id: "response-headers" }),
2123
2193
  React__namespace.createElement(Parameters, { parameterType: "header", parameters: headers }))),
2124
- contents.length > 0 && (React__namespace.createElement(SubSectionPanel, { title: "Body", rightComponent: React__namespace.createElement(mosaic.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" }) }, schema && (React__namespace.createElement(mosaic.Box, null,
2125
- React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", hideExamples: true })))))));
2194
+ contents.length > 0 && (React__namespace.createElement(React__namespace.Fragment, null,
2195
+ React__namespace.createElement(SectionSubtitle, { title: "Body", id: "response-body" },
2196
+ React__namespace.createElement(mosaic.Flex, { flex: 1, justify: "end" },
2197
+ React__namespace.createElement(mosaic.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" }))),
2198
+ schema && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", hideExamples: true, parentCrumbs: ['responses', response.code], renderRootTreeLines: true }))))));
2126
2199
  };
2127
- Response.displayName = 'HttpOperation.Response';
2200
+ Response.displayName = 'HttpOperation.Response';
2201
+ const codeToIntentVal = (code) => {
2202
+ const firstChar = code.charAt(0);
2203
+ switch (firstChar) {
2204
+ case '2':
2205
+ return 'success';
2206
+ case '4':
2207
+ return 'warning';
2208
+ case '5':
2209
+ return 'danger';
2210
+ default:
2211
+ return 'default';
2212
+ }
2213
+ };
2128
2214
 
2129
2215
  const HttpOperationComponent = React__namespace.memo(({ className, data: unresolvedData, layoutOptions, tryItCredentialsPolicy, tryItCorsProxy }) => {
2130
2216
  const data = useResolvedObject(unresolvedData);
@@ -2134,13 +2220,16 @@ const HttpOperationComponent = React__namespace.memo(({ className, data: unresol
2134
2220
  const [responseMediaType, setResponseMediaType] = React__namespace.useState('');
2135
2221
  const [responseStatusCode, setResponseStatusCode] = React__namespace.useState('');
2136
2222
  const [requestBodyIndex, setTextRequestBodyIndex] = React__namespace.useState(0);
2223
+ const prettyName = (data.summary || data.iid || '').trim();
2137
2224
  const hasBadges = isDeprecated || isInternal;
2138
- const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React__namespace.createElement(React__namespace.Fragment, null,
2139
- !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (React__namespace.createElement(mosaic.Heading, { size: 1, mb: 4, fontWeight: "semibold" }, data.summary || data.iid || `${data.method} ${data.path}`)),
2140
- hasBadges && (React__namespace.createElement(mosaic.HStack, { spacing: 2 },
2141
- isDeprecated && React__namespace.createElement(DeprecatedBadge, null),
2142
- isInternal && React__namespace.createElement(InternalBadge, { isHttpService: true })))));
2143
- const description = (React__namespace.createElement(mosaic.VStack, { spacing: 6 },
2225
+ const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2226
+ React__namespace.createElement(mosaic.HStack, { spacing: 5 },
2227
+ !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React__namespace.createElement(mosaic.Heading, { size: 1, fontWeight: "semibold" }, prettyName)) : null,
2228
+ React__namespace.createElement(mosaic.HStack, { spacing: 2 },
2229
+ isDeprecated && React__namespace.createElement(DeprecatedBadge, null),
2230
+ isInternal && React__namespace.createElement(InternalBadge, { isHttpService: true }))),
2231
+ React__namespace.createElement(MethodPath, { method: data.method, path: data.path })));
2232
+ const description = (React__namespace.createElement(mosaic.VStack, { spacing: 10 },
2144
2233
  data.description && React__namespace.createElement(MarkdownViewer, { className: "HttpOperation__Description", markdown: data.description }),
2145
2234
  React__namespace.createElement(Request, { onChange: setTextRequestBodyIndex, operation: data }),
2146
2235
  data.responses && (React__namespace.createElement(Responses, { responses: data.responses, onMediaTypeChange: setResponseMediaType, onStatusCodeChange: setResponseStatusCode }))));
@@ -2150,7 +2239,26 @@ const HttpOperationComponent = React__namespace.memo(({ className, data: unresol
2150
2239
  HttpOperationComponent.displayName = 'HttpOperation.Component';
2151
2240
  const HttpOperation = reactErrorBoundary.withErrorBoundary(HttpOperationComponent, {
2152
2241
  recoverableProps: ['data'],
2153
- });
2242
+ });
2243
+ function MethodPath({ method, path }) {
2244
+ const chosenServer = utils.useAtomValue(chosenServerAtom);
2245
+ let chosenServerUrl = '';
2246
+ if (chosenServer) {
2247
+ chosenServerUrl = chosenServer.url.endsWith('/') ? chosenServer.url.slice(0, -1) : chosenServer.url;
2248
+ }
2249
+ return (React__namespace.createElement(mosaic.Box, null,
2250
+ React__namespace.createElement(MethodPathInner, { method: method, path: path, chosenServerUrl: chosenServerUrl })));
2251
+ }
2252
+ function MethodPathInner({ method, path, chosenServerUrl }) {
2253
+ const isDark = mosaic.useThemeIsDark();
2254
+ const fullUrl = `${chosenServerUrl}${path}`;
2255
+ const pathElem = (React__namespace.createElement(mosaic.Flex, { overflowX: "hidden" },
2256
+ chosenServerUrl ? (React__namespace.createElement(mosaic.Box, { dir: "rtl", color: "muted", fontSize: "lg", textOverflow: "truncate", overflowX: "hidden" }, chosenServerUrl)) : null,
2257
+ React__namespace.createElement(mosaic.Box, { fontSize: "lg", fontWeight: "semibold", flex: 1 }, path)));
2258
+ return (React__namespace.createElement(mosaic.HStack, { spacing: 3, pl: 2.5, pr: 4, py: 2, bg: "canvas-50", rounded: "lg", fontFamily: "mono", display: "inline-flex", maxW: "full", title: fullUrl },
2259
+ React__namespace.createElement(mosaic.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),
2260
+ pathElem));
2261
+ }
2154
2262
 
2155
2263
  const PoweredByLink = ({ source, pathname, packageType, layout = 'sidebar' }) => {
2156
2264
  return (React__namespace.createElement(mosaic.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" },
@@ -2186,7 +2294,7 @@ const ExportButton = ({ original, bundled }) => {
2186
2294
  return items;
2187
2295
  }, [original, bundled]);
2188
2296
  return (React__namespace.createElement(mosaic.Box, null,
2189
- React__namespace.createElement(mosaic.Menu, { "aria-label": "Export", items: menuItems, renderTrigger: ({ isOpen }) => (React__namespace.createElement(mosaic.Button, { iconRight: "chevron-down", appearance: "default", ml: 2, active: isOpen, size: "sm" }, "Export")) })));
2297
+ React__namespace.createElement(mosaic.Menu, { "aria-label": "Export", items: menuItems, placement: "bottom right", renderTrigger: ({ isOpen }) => (React__namespace.createElement(mosaic.Button, { iconRight: "chevron-down", appearance: "default", ml: 2, active: isOpen, size: "sm" }, "Export")) })));
2190
2298
  };
2191
2299
 
2192
2300
  const SecuritySchemes = ({ schemes, defaultScheme, defaultCollapsed = false, }) => {
@@ -2206,7 +2314,8 @@ const SecurityScheme = ({ scheme, defaultIsOpen, isCollapsible, showSchemeKey })
2206
2314
  const ServerInfo = ({ servers, mockUrl }) => {
2207
2315
  const mocking = React__namespace.useContext(MockingContext);
2208
2316
  const showMocking = !mocking.hideMocking && mockUrl && isProperUrl(mockUrl);
2209
- const serversToDisplay = getServersToDisplay(servers);
2317
+ const $mockUrl = showMocking ? mockUrl || mocking.mockUrl : undefined;
2318
+ const serversToDisplay = getServersToDisplay(servers, $mockUrl);
2210
2319
  if (!showMocking && serversToDisplay.length === 0) {
2211
2320
  return null;
2212
2321
  }
@@ -2215,14 +2324,11 @@ const ServerInfo = ({ servers, mockUrl }) => {
2215
2324
  React__namespace.createElement(mosaic.Panel.Titlebar, { whitespace: "nowrap" }, "API Base URL"),
2216
2325
  React__namespace.createElement(mosaic.Box, { overflowX: "auto" },
2217
2326
  React__namespace.createElement(mosaic.Panel.Content, { w: "full", className: "sl-flex sl-flex-col" },
2218
- serversToDisplay.map((server, index) => (React__namespace.createElement(ServerUrl, Object.assign({}, server, { key: index })))),
2219
- showMocking && (React__namespace.createElement(React__namespace.Fragment, null,
2220
- React__namespace.createElement(mosaic.Box, { borderT: 2, pt: 2, borderColor: "light", w: "full" }),
2221
- React__namespace.createElement(ServerUrl, { description: "Mock Server", url: mockUrl || '', marginBottom: false }))))))));
2327
+ React__namespace.createElement(mosaic.VStack, { spacing: 1, divider: true }, serversToDisplay.map((server, index) => (React__namespace.createElement(ServerUrl, Object.assign({}, server, { key: index }))))))))));
2222
2328
  };
2223
2329
  const ServerUrl = ({ description, url, marginBottom = true }) => {
2224
2330
  const { onCopy, hasCopied } = mosaic.useClipboard(url);
2225
- return (React__namespace.createElement(mosaic.Box, { whitespace: "nowrap", mb: marginBottom ? 2 : 0 },
2331
+ return (React__namespace.createElement(mosaic.Box, { whitespace: "nowrap" },
2226
2332
  React__namespace.createElement(mosaic.Text, { pr: 2, fontWeight: "bold" },
2227
2333
  description,
2228
2334
  ":"),
@@ -2271,14 +2377,13 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
2271
2377
  };
2272
2378
  const examples = React__namespace.useMemo(() => generateExamplesFromJsonSchema(data), [data]);
2273
2379
  const shouldDisplayHeader = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (title !== undefined || (exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport)));
2274
- const header = (shouldDisplayHeader || isInternal) && (React__namespace.createElement(React__namespace.Fragment, null,
2275
- shouldDisplayHeader && (React__namespace.createElement(mosaic.Flex, { justifyContent: "between", alignItems: "center" },
2276
- React__namespace.createElement(mosaic.Heading, { size: 1, mb: 4, fontWeight: "semibold" }, title),
2277
- exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React__namespace.createElement(ExportButton, Object.assign({}, exportProps)))),
2278
- isInternal && (React__namespace.createElement(mosaic.HStack, { spacing: 2, mb: 12 },
2279
- React__namespace.createElement(InternalBadge, null)))));
2280
- const description = (React__namespace.createElement(React__namespace.Fragment, null,
2281
- data.description && data.type === 'object' && (React__namespace.createElement(MarkdownViewer, { className: "sl-mb-6", role: "textbox", markdown: data.description })),
2380
+ const header = (shouldDisplayHeader || isInternal) && (React__namespace.createElement(mosaic.Flex, { justifyContent: "between", alignItems: "center" },
2381
+ React__namespace.createElement(mosaic.HStack, { spacing: 5 },
2382
+ title && (React__namespace.createElement(mosaic.Heading, { size: 1, fontWeight: "semibold" }, title)),
2383
+ React__namespace.createElement(mosaic.HStack, { spacing: 2 }, isInternal && React__namespace.createElement(InternalBadge, null))),
2384
+ exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React__namespace.createElement(ExportButton, Object.assign({}, exportProps))));
2385
+ const description = (React__namespace.createElement(mosaic.VStack, { spacing: 10 },
2386
+ data.description && data.type === 'object' && React__namespace.createElement(MarkdownViewer, { role: "textbox", markdown: data.description }),
2282
2387
  React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(data) })));
2283
2388
  const examplesSelect = examples.length > 1 && (React__namespace.createElement(mosaic.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: " }));
2284
2389
  const modelExamples = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideModelExamples) && (React__namespace.createElement(mosaic.Panel, { rounded: true, isCollapsible: false },
@@ -2663,10 +2768,11 @@ const RouterComponent = {
2663
2768
  history: reactRouterDom.BrowserRouter,
2664
2769
  memory: reactRouterDom.MemoryRouter,
2665
2770
  hash: reactRouterDom.HashRouter,
2771
+ static: reactRouterDom.StaticRouter,
2666
2772
  };
2667
- const useRouter = (router, basePath) => {
2773
+ const useRouter = (router, basePath, staticRouterPath) => {
2668
2774
  const Router = RouterComponent[router];
2669
- const routerProps = Object.assign({}, (router !== 'memory' && { basename: basePath }));
2775
+ const routerProps = Object.assign(Object.assign({}, (router !== 'memory' && { basename: basePath })), (router === 'static' && { location: staticRouterPath }));
2670
2776
  return {
2671
2777
  Router,
2672
2778
  routerProps,
@@ -2675,9 +2781,10 @@ const useRouter = (router, basePath) => {
2675
2781
 
2676
2782
  function withRouter(WrappedComponent) {
2677
2783
  const WithRouter = (props) => {
2678
- var _a, _b;
2784
+ var _a, _b, _c;
2679
2785
  const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
2680
- const { Router, routerProps } = useRouter((_b = props.router) !== null && _b !== void 0 ? _b : 'history', basePath);
2786
+ const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
2787
+ const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
2681
2788
  return (React__namespace.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
2682
2789
  React__namespace.createElement(reactRouterDom.Route, { path: "/" },
2683
2790
  React__namespace.createElement(MarkdownComponentsProvider, { value: { link: ReactRouterMarkdownLink } },
@@ -2881,6 +2988,7 @@ exports.createResolvedObject = createResolvedObject;
2881
2988
  exports.findFirstNode = findFirstNode;
2882
2989
  exports.isHttpOperation = isHttpOperation;
2883
2990
  exports.isHttpService = isHttpService;
2991
+ exports.slugify = slugify;
2884
2992
  exports.useBundleRefsIntoDocument = useBundleRefsIntoDocument;
2885
2993
  exports.useParsedData = useParsedData;
2886
2994
  exports.useParsedValue = useParsedValue;