@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/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)
@@ -355,9 +349,10 @@ const Headings = ({ headings, className, title = 'On This Page', minimal, maxWid
355
349
  React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, icon: freeSolidSvgIcons.faStream, mr: 2 }),
356
350
  title)),
357
351
  headings.map((heading, i) => (React__namespace.createElement(Heading, { key: i, item: heading, isSelected: locationHash === `#${heading.id}` })))));
352
+ const button = React__namespace.createElement(mosaic.Button, { pos: "sticky", size: "sm", borderColor: "light", icon: freeSolidSvgIcons.faStream, style: { top: 10 } });
358
353
  if (minimal) {
359
- return (React__namespace.createElement(mosaic.Box, { pos: "absolute", top: 0, right: 0, style: { top: 10 } },
360
- React__namespace.createElement(mosaic.Popover, { renderTrigger: React__namespace.createElement(mosaic.Button, { size: "sm", borderColor: "light", icon: freeSolidSvgIcons.faStream }), placement: "bottom" },
354
+ return (React__namespace.createElement(mosaic.Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
355
+ React__namespace.createElement(mosaic.Popover, { renderTrigger: button, placement: "bottom" },
361
356
  React__namespace.createElement(mosaic.Box, { className: className }, component))));
362
357
  }
363
358
  return (React__namespace.createElement(mosaic.Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
@@ -379,20 +374,6 @@ const ArticleComponent = React__namespace.memo(({ data }) => {
379
374
  });
380
375
  const Article = reactErrorBoundary.withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
381
376
 
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
377
  const NodeTypeColors = {
397
378
  http_operation: '#6a6acb',
398
379
  http_service: '#e056fd',
@@ -509,10 +490,36 @@ const HttpCodeDescriptions = {
509
490
  const badgeDefaultBackgroundColor = '#293742';
510
491
  const badgeDefaultColor = '#FFFFFF';
511
492
 
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}` })))
493
+ const MockingContext = createNamedContext('MockingContext', { mockUrl: undefined, hideMocking: undefined });
494
+ const MockingProvider = ({ mockUrl, hideMocking, children }) => {
495
+ const info = {
496
+ mockUrl,
497
+ hideMocking: hideMocking || !mockUrl,
498
+ };
499
+ return React__namespace.createElement(MockingContext.Provider, { value: info }, children);
500
+ };
501
+ function createNamedContext(name, defaultValue) {
502
+ const context = React__namespace.createContext(defaultValue);
503
+ context.displayName = name;
504
+ return context;
505
+ }
506
+
507
+ const chosenServerAtom = jotai.atom(undefined);
508
+
509
+ const getServersToDisplay = (originalServers, mockUrl) => {
510
+ const servers = originalServers
511
+ .map((server, i) => {
512
+ const fallbackDescription = originalServers.length === 1 ? 'Live Server' : `Server ${i + 1}`;
513
+ return Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || fallbackDescription });
514
+ })
515
515
  .filter(server => isProperUrl(server.url));
516
+ if (mockUrl) {
517
+ servers.push({
518
+ description: 'Mock Server',
519
+ url: mockUrl,
520
+ });
521
+ }
522
+ return servers;
516
523
  };
517
524
  const getServerUrlWithDefaultValues = (server) => {
518
525
  var _a;
@@ -778,7 +785,12 @@ const RequestSamples = React__default["default"].memo(({ request, embeddedInMd =
778
785
  " ",
779
786
  selectedLibrary ? ` / ${selectedLibrary}` : '')) }))),
780
787
  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 }))));
788
+ 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
789
+ ? undefined
790
+ :
791
+ {
792
+ '--fs-code': 12,
793
+ } }))));
782
794
  });
783
795
 
784
796
  function getReadableSecurityName(securityScheme, includeKey = false) {
@@ -943,7 +955,14 @@ const SecuritySchemeComponent = (_a) => {
943
955
  };
944
956
  const securitySchemeKeys = ['apiKey', 'http', 'oauth2', 'openIdConnect'];
945
957
 
946
- const caseInsensitivelyEquals = curry__default["default"]((a, b) => a.toUpperCase() === b.toUpperCase());
958
+ const caseInsensitivelyEquals = curry__default["default"]((a, b) => a.toUpperCase() === b.toUpperCase());
959
+ function slugify(name) {
960
+ return name
961
+ .replace(/\/|{|}|\s/g, '-')
962
+ .replace(/-{2,}/, '-')
963
+ .replace(/^-/, '')
964
+ .replace(/-$/, '');
965
+ }
947
966
 
948
967
  const isApiKeySecurityScheme = (maybeIApiKey) => isObject__default["default"](maybeIApiKey) && maybeIApiKey.type === 'apiKey';
949
968
  const isOAuth2SecurityScheme = (maybeIOAuth2) => isObject__default["default"](maybeIOAuth2) && maybeIOAuth2.type === 'oauth2';
@@ -1054,10 +1073,10 @@ function exampleValue(example) {
1054
1073
  }
1055
1074
  function getPlaceholderForParameter(parameter) {
1056
1075
  var _a, _b;
1057
- const parameterValue = getValueForParameter(parameter);
1076
+ const { value: parameterValue, isDefault } = getValueForParameter(parameter);
1058
1077
  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 : '');
1078
+ return `${isDefault ? 'defaults to' : 'example'}: ${parameterValue}`;
1079
+ return String((_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : '');
1061
1080
  }
1062
1081
  function retrieveDefaultFromSchema(parameter) {
1063
1082
  var _a;
@@ -1066,22 +1085,25 @@ function retrieveDefaultFromSchema(parameter) {
1066
1085
  }
1067
1086
  const getValueForParameter = (parameter) => {
1068
1087
  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
1088
  const defaultValue = retrieveDefaultFromSchema(parameter);
1073
- if (defaultValue)
1074
- return String(defaultValue);
1089
+ if (typeof defaultValue !== 'undefined') {
1090
+ return { value: String(defaultValue), isDefault: true };
1091
+ }
1092
+ const examples = (_a = parameter.examples) !== null && _a !== void 0 ? _a : [];
1093
+ if (examples.length > 0) {
1094
+ return { value: exampleValue(examples[0]) };
1095
+ }
1075
1096
  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 '';
1097
+ if (enums.length > 0) {
1098
+ return { value: String(enums[0]) };
1099
+ }
1100
+ return { value: '' };
1079
1101
  };
1080
1102
  const getInitialValueForParameter = (parameter) => {
1081
1103
  const isRequired = !!parameter.required;
1082
1104
  if (!isRequired)
1083
1105
  return '';
1084
- return getValueForParameter(parameter);
1106
+ return getValueForParameter(parameter).value;
1085
1107
  };
1086
1108
  const initialParameterValues = params => {
1087
1109
  const paramsByName = keyBy__default["default"](params, (param) => param.name);
@@ -1226,7 +1248,9 @@ const RequestBody = ({ examples, requestBody, onChange }) => {
1226
1248
  return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
1227
1249
  React__namespace.createElement(mosaic.Panel.Titlebar, { rightComponent: examples.length > 1 && React__namespace.createElement(ExampleMenu, { examples: examples, requestBody: requestBody, onChange: onChange }) }, "Body"),
1228
1250
  React__namespace.createElement(mosaic.Panel.Content, { className: "TextRequestBody" },
1229
- React__namespace.createElement(mosaicCodeEditor.CodeEditor, { onChange: onChange, language: "json", value: requestBody, showLineNumbers: true, padding: 0 }))));
1251
+ React__namespace.createElement(mosaicCodeEditor.CodeEditor, { onChange: onChange, language: "json", value: requestBody, showLineNumbers: true, padding: 0, style: {
1252
+ fontSize: 12,
1253
+ } }))));
1230
1254
  };
1231
1255
  function ExampleMenu({ examples, requestBody, onChange }) {
1232
1256
  const handleClick = React__namespace.useCallback((example) => {
@@ -1484,8 +1508,8 @@ const formatMultiValueHeader = (...keyValuePairs) => {
1484
1508
  .join(', ');
1485
1509
  };
1486
1510
 
1487
- function getMockData(url, httpOperation, { isEnabled, code, dynamic, example }) {
1488
- return isEnabled && url ? { url, header: buildPreferHeader({ code, dynamic, example }, httpOperation) } : undefined;
1511
+ function getMockData(url, httpOperation, { code, dynamic, example }) {
1512
+ return url ? { url, header: buildPreferHeader({ code, dynamic, example }, httpOperation) } : undefined;
1489
1513
  }
1490
1514
  function buildPreferHeader({ code, example, dynamic }, httpOperation) {
1491
1515
  if (!code) {
@@ -1518,23 +1542,14 @@ function supportsExample(httpOperation, code, exampleKey) {
1518
1542
  return exampleKeys.includes(exampleKey);
1519
1543
  }
1520
1544
 
1521
- const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic }, onOptionsChange, }) => {
1522
- const toggleEnabled = React__namespace.useCallback(() => {
1523
- onOptionsChange({ isEnabled: !isEnabled });
1524
- }, [isEnabled, onOptionsChange]);
1545
+ const MockingButton = ({ operation, options: { code, example, dynamic }, onOptionsChange, }) => {
1525
1546
  const operationResponses = operation.responses;
1526
1547
  const setMockingOptions = React__namespace.useCallback(({ code, example, dynamic }) => {
1527
- onOptionsChange({ isEnabled, code, example, dynamic });
1528
- }, [isEnabled, onOptionsChange]);
1548
+ onOptionsChange({ code, example, dynamic });
1549
+ }, [onOptionsChange]);
1529
1550
  const menuItems = React__namespace.useMemo(() => {
1530
1551
  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
- ];
1552
+ 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
1553
  function generateOperationResponseMenu(operationResponse) {
1539
1554
  var _a;
1540
1555
  const menuId = `response-${operationResponse.code}`;
@@ -1568,7 +1583,6 @@ const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic
1568
1583
  ];
1569
1584
  const menuItem = {
1570
1585
  id: menuId,
1571
- isDisabled: !isEnabled,
1572
1586
  isChecked: isActive,
1573
1587
  title: operationResponse.code,
1574
1588
  onPress: () => {
@@ -1582,13 +1596,13 @@ const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic
1582
1596
  return menuItem;
1583
1597
  }
1584
1598
  return items;
1585
- }, [code, dynamic, example, isEnabled, operationResponses, setMockingOptions, toggleEnabled]);
1599
+ }, [code, dynamic, example, operationResponses, setMockingOptions]);
1586
1600
  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")) })));
1601
+ 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
1602
  };
1589
1603
 
1590
- const persistedMockingOptionsAtom = jotai.atom({ isEnabled: false });
1591
- const useMockingOptions = () => jotai.useAtom(persistedMockingOptionsAtom);
1604
+ const mockingOptionsAtom = jotai.atom({});
1605
+ const useMockingOptions = () => jotai.useAtom(mockingOptionsAtom);
1592
1606
 
1593
1607
  const OperationParameters = ({ parameters, values, onChangeValue, validate, }) => {
1594
1608
  return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
@@ -1717,7 +1731,32 @@ class NetworkError extends Error {
1717
1731
  }
1718
1732
  const isNetworkError = (error) => error instanceof NetworkError;
1719
1733
 
1720
- const chosenServerAtom = jotai.atom(undefined);
1734
+ const ServersDropdown = ({ servers }) => {
1735
+ const [chosenServer, setChosenServer] = jotai.useAtom(chosenServerAtom);
1736
+ const serverItems = [
1737
+ {
1738
+ type: 'option_group',
1739
+ title: 'Servers',
1740
+ value: (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || '',
1741
+ onChange: url => {
1742
+ const server = servers.find(server => server.url === url);
1743
+ setChosenServer(server);
1744
+ },
1745
+ children: [
1746
+ ...servers.map((server, i) => ({
1747
+ id: server.url,
1748
+ title: server.name || server.description,
1749
+ description: server.name ? server.description || server.url : server.description ? server.url : undefined,
1750
+ value: server.url,
1751
+ })),
1752
+ ],
1753
+ },
1754
+ ];
1755
+ 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')) }));
1756
+ };
1757
+ ServersDropdown.displayName = 'ServersDropdown';
1758
+
1759
+ const defaultServers = [];
1721
1760
  const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embeddedInMd = false, tryItCredentialsPolicy, corsProxy, }) => {
1722
1761
  var _a, _b, _c, _d, _e, _f, _g;
1723
1762
  const isDark = mosaic.useThemeIsDark();
@@ -1731,18 +1770,28 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1731
1770
  const [bodyParameterValues, setBodyParameterValues, formDataState] = useBodyParameterState(mediaTypeContent);
1732
1771
  const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
1733
1772
  const [operationAuthValue, setOperationAuthValue] = usePersistedSecuritySchemeWithValues();
1734
- const servers = getServersToDisplay(httpOperation.servers || []);
1773
+ const servers = React__namespace.useMemo(() => {
1774
+ const toDisplay = getServersToDisplay(httpOperation.servers || defaultServers, mockUrl);
1775
+ return toDisplay;
1776
+ }, [httpOperation.servers, mockUrl]);
1777
+ const firstServer = servers[0] || null;
1735
1778
  const [chosenServer, setChosenServer] = jotai.useAtom(chosenServerAtom);
1779
+ const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
1736
1780
  const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
1737
1781
  React__namespace.useEffect(() => {
1738
- if (!chosenServer) {
1739
- setChosenServer(servers[0]);
1782
+ const currentUrl = chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url;
1783
+ const exists = currentUrl && servers.find(s => s.url === currentUrl);
1784
+ if (!exists) {
1785
+ setChosenServer(firstServer);
1740
1786
  }
1741
- }, []);
1787
+ else if (exists !== chosenServer) {
1788
+ setChosenServer(exists);
1789
+ }
1790
+ }, [servers, firstServer, chosenServer, setChosenServer]);
1742
1791
  React__namespace.useEffect(() => {
1743
1792
  let isMounted = true;
1744
1793
  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,
1794
+ buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
1746
1795
  corsProxy })).then(request => {
1747
1796
  if (isMounted) {
1748
1797
  if (onRequestChange) {
@@ -1769,13 +1818,13 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1769
1818
  corsProxy,
1770
1819
  embeddedInMd,
1771
1820
  ]);
1772
- const handleClick = () => tslib.__awaiter(void 0, void 0, void 0, function* () {
1821
+ const handleSendRequest = () => tslib.__awaiter(void 0, void 0, void 0, function* () {
1773
1822
  setValidateParameters(true);
1774
1823
  if (hasRequiredButEmptyParameters)
1775
1824
  return;
1776
1825
  try {
1777
1826
  setLoading(true);
1778
- const mockData = getMockData(mockUrl, httpOperation, mockingOptions);
1827
+ const mockData = isMockingEnabled ? getMockData(mockUrl, httpOperation, mockingOptions) : undefined;
1779
1828
  const request = yield buildFetchRequest({
1780
1829
  parameterValues: parameterValuesWithDefaults,
1781
1830
  httpOperation,
@@ -1812,29 +1861,32 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1812
1861
  setLoading(false);
1813
1862
  }
1814
1863
  });
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));
1864
+ const isOnlySendButton = !((_d = httpOperation.security) === null || _d === void 0 ? void 0 : _d.length) && !allParameters.length && !formDataState.isFormDataBody && !mediaTypeContent;
1865
+ const tryItPanelContents = (React__namespace.createElement(React__namespace.Fragment, null,
1866
+ ((_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,
1867
+ allParameters.length > 0 && (React__namespace.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
1868
+ 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,
1869
+ React__namespace.createElement(mosaic.Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
1870
+ React__namespace.createElement(mosaic.HStack, { alignItems: "center", spacing: 2 },
1871
+ React__namespace.createElement(mosaic.Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
1872
+ servers.length > 1 && React__namespace.createElement(ServersDropdown, { servers: servers }),
1873
+ isMockingEnabled && (React__namespace.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
1874
+ validateParameters && hasRequiredButEmptyParameters && (React__namespace.createElement(mosaic.Box, { mt: 4, color: "danger-light", fontSize: "sm" },
1875
+ React__namespace.createElement(mosaic.Icon, { icon: freeSolidSvgIcons.faExclamationTriangle, className: "sl-mr-1" }),
1876
+ "You didn't provide all of the required parameters!")))));
1877
+ let tryItPanelElem;
1878
+ if (embeddedInMd) {
1879
+ tryItPanelElem = (React__namespace.createElement(mosaic.Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
1880
+ React__namespace.createElement(mosaic.Panel.Titlebar, { bg: "canvas-300" },
1881
+ React__namespace.createElement(mosaic.Box, { fontWeight: "bold", color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
1882
+ React__namespace.createElement(mosaic.Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${httpOperation.path}`)),
1883
+ tryItPanelContents));
1884
+ }
1885
+ else {
1886
+ tryItPanelElem = (React__namespace.createElement(mosaic.Box, { className: "TryItPanel", bg: "canvas-100", rounded: "lg" }, tryItPanelContents));
1887
+ }
1822
1888
  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!")))),
1889
+ tryItPanelElem,
1838
1890
  requestData && embeddedInMd && React__namespace.createElement(RequestSamples, { request: requestData, embeddedInMd: true }),
1839
1891
  response && !('error' in response) && React__namespace.createElement(TryItResponse, { response: response }),
1840
1892
  response && 'error' in response && React__namespace.createElement(ResponseError, { state: response })));
@@ -1871,7 +1923,9 @@ const ResponseExamples = ({ httpOperation, responseMediaType, responseStatusCode
1871
1923
  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
1924
  return (React__default["default"].createElement(mosaic.Panel, { rounded: true, isCollapsible: false },
1873
1925
  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 })))));
1926
+ 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: {
1927
+ '--fs-code': 12,
1928
+ } })) : (React__default["default"].createElement(LoadMore, { loading: loading, onClick: handleLoadMore })))));
1875
1929
  };
1876
1930
 
1877
1931
  const TryItWithRequestSamples = (_a) => {
@@ -1885,14 +1939,14 @@ const TryItWithRequestSamples = (_a) => {
1885
1939
  React__namespace.createElement(ResponseExamples, Object.assign({}, props))));
1886
1940
  };
1887
1941
 
1888
- const TwoColumnLayout = ({ header, right, left, className }) => (React__default["default"].createElement(mosaic.Box, { w: "full", className: className },
1942
+ const TwoColumnLayout = ({ header, right, left, className }) => (React__default["default"].createElement(mosaic.VStack, { w: "full", className: className, spacing: 8 },
1889
1943
  header,
1890
- React__default["default"].createElement(mosaic.Flex, { mt: header ? 12 : undefined },
1944
+ React__default["default"].createElement(mosaic.Flex, null,
1891
1945
  React__default["default"].createElement(mosaic.Box, { w: 0, flex: 1 }, left),
1892
1946
  right && (React__default["default"].createElement(mosaic.Box, { ml: 16, pos: "relative", w: "2/5", style: { maxWidth: 500 } }, right)))));
1893
1947
 
1894
1948
  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.`));
1949
+ 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
1950
  const VersionBadge = ({ value, backgroundColor }) => (React__default["default"].createElement(mosaic.Badge, { appearance: "solid", size: "sm", border: 0, style: {
1897
1951
  backgroundColor: backgroundColor || badgeDefaultBackgroundColor,
1898
1952
  color: badgeDefaultColor,
@@ -1972,32 +2026,43 @@ ${scopes.map(([key, value]) => `- \`${key}\` - ${value}`).join('\n')}`;
1972
2026
  return description;
1973
2027
  }
1974
2028
 
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),
2029
+ const SectionTitle = ({ title, id, size = 2, children }) => {
2030
+ return (React__namespace.createElement(mosaic.HStack, { spacing: 6 },
2031
+ React__namespace.createElement(mosaic.Box, { as: mosaic.LinkHeading, size: size, "aria-label": title, id: id || slugify(title) }, title),
1978
2032
  children));
1979
2033
  };
2034
+ const SectionSubtitle = props => {
2035
+ return React__namespace.createElement(SectionTitle, Object.assign({}, props, { size: 3 }));
2036
+ };
1980
2037
  const SubSectionPanel = ({ title, children, hasContent, rightComponent, defaultIsOpen = true, onChange, }) => {
1981
- return (React__namespace.createElement(mosaic.Panel, { appearance: "minimal", isCollapsible: hasContent, defaultIsOpen: defaultIsOpen, onChange: onChange },
2038
+ return (React__namespace.createElement(mosaic.Panel, { isCollapsible: hasContent, defaultIsOpen: defaultIsOpen, onChange: onChange, appearance: "outlined" },
1982
2039
  React__namespace.createElement(mosaic.Panel.Titlebar, { fontWeight: "medium", rightComponent: rightComponent },
1983
2040
  React__namespace.createElement("div", { role: "heading" }, title)),
1984
- hasContent !== false && (React__namespace.createElement(mosaic.Panel.Content, { pr: 3, pl: 6, p: 0 }, children))));
2041
+ hasContent !== false && React__namespace.createElement(mosaic.Panel.Content, null, children)));
1985
2042
  };
1986
2043
 
1987
- const Body = ({ body: { contents = [], description }, onChange }) => {
2044
+ const isBodyEmpty = (body) => {
2045
+ if (!body)
2046
+ return true;
2047
+ const { contents = [], description } = body;
2048
+ return contents.length === 0 && !(description === null || description === void 0 ? void 0 : description.trim());
2049
+ };
2050
+ const Body = ({ body, onChange }) => {
1988
2051
  var _a;
1989
2052
  const refResolver = useInlineRefResolver();
1990
2053
  const [chosenContent, setChosenContent] = React__namespace.useState(0);
1991
2054
  React__namespace.useEffect(() => {
1992
2055
  onChange(chosenContent);
1993
2056
  }, [chosenContent]);
1994
- if (contents.length === 0 && !description)
2057
+ if (isBodyEmpty(body))
1995
2058
  return null;
2059
+ const { contents = [], description } = body;
1996
2060
  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 })))));
2061
+ return (React__namespace.createElement(mosaic.VStack, { spacing: 6 },
2062
+ React__namespace.createElement(SectionSubtitle, { title: "Body", id: "request-body" }, contents.length > 0 && (React__namespace.createElement(mosaic.Flex, { flex: 1, justify: "end" },
2063
+ 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" })))),
2064
+ description && React__namespace.createElement(MarkdownViewer, { markdown: description }),
2065
+ isJSONSchema(schema) && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", hideExamples: true, renderRootTreeLines: true }))));
2001
2066
  };
2002
2067
  Body.displayName = 'HttpOperation.Body';
2003
2068
 
@@ -2021,66 +2086,71 @@ const defaultStyle = {
2021
2086
  cookie: types.HttpParamStyles.Form,
2022
2087
  };
2023
2088
  const Parameters = ({ parameters, parameterType }) => {
2024
- if (!parameters || !parameters.length)
2089
+ const schema = React__namespace.useMemo(() => httpOperationParamsToSchema({ parameters, parameterType }), [parameters, parameterType]);
2090
+ if (!schema)
2025
2091
  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
- })));
2092
+ return React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: schema, disableCrumbs: true });
2029
2093
  };
2030
2094
  Parameters.displayName = 'HttpOperation.Parameters';
2031
- const Parameter = ({ parameter, parameterType }) => {
2032
- var _a, _b, _c, _d, _e;
2033
- if (!parameter)
2095
+ const httpOperationParamsToSchema = ({ parameters, parameterType }) => {
2096
+ var _a;
2097
+ if (!parameters || !parameters.length)
2034
2098
  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;
2099
+ const schema = {
2100
+ properties: {},
2101
+ required: [],
2102
+ };
2103
+ const sortedParams = sortBy__default["default"](parameters, ['required', 'name']);
2104
+ for (const p of sortedParams) {
2105
+ if (!p.schema)
2106
+ continue;
2107
+ const { name, description, required, deprecated, examples, style } = p;
2108
+ const paramExamples = (examples === null || examples === void 0 ? void 0 : examples.map(example => {
2109
+ if (isNodeExample(example)) {
2110
+ return example.value;
2111
+ }
2112
+ return example.externalValue;
2113
+ })) || [];
2114
+ const schemaExamples = (_a = p.schema) === null || _a === void 0 ? void 0 : _a.examples;
2115
+ const schemaExamplesArray = Array.isArray(schemaExamples) ? schemaExamples : [];
2116
+ const paramDescription = description || p.schema.description;
2117
+ const paramDeprecated = deprecated || p.schema.deprecated;
2118
+ const paramStyle = style && defaultStyle[parameterType] !== style ? readableStyles[style] || style : undefined;
2119
+ schema.properties[p.name] = Object.assign(Object.assign({}, p.schema), { description: paramDescription, examples: [...paramExamples, ...schemaExamplesArray], deprecated: paramDeprecated, style: paramStyle });
2120
+ if (required) {
2121
+ schema.required.push(name);
2043
2122
  }
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';
2123
+ }
2124
+ return schema;
2125
+ };
2065
2126
 
2066
- const Request = ({ operation: { path, method, request, request: { path: pathParams = [], headers: headerParams = [], cookie: cookieParams = [], body, query: queryParams = [], } = {}, security, }, onChange, }) => {
2127
+ const Request = ({ operation: { request, request: { path: pathParams = [], headers: headerParams = [], cookie: cookieParams = [], body, query: queryParams = [], } = {}, security, }, onChange, }) => {
2067
2128
  if (!request || typeof request !== 'object')
2068
2129
  return null;
2130
+ const bodyIsEmpty = isBodyEmpty(body);
2069
2131
  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,
2132
+ const hasRequestData = Boolean(securitySchemes.length ||
2133
+ pathParams.length ||
2134
+ queryParams.length ||
2135
+ headerParams.length ||
2136
+ cookieParams.length ||
2137
+ !bodyIsEmpty);
2138
+ if (!hasRequestData)
2139
+ return null;
2140
+ return (React__namespace.createElement(mosaic.VStack, { spacing: 8 },
2075
2141
  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" },
2142
+ 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) }))))),
2143
+ pathParams.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2144
+ React__namespace.createElement(SectionSubtitle, { title: "Path Parameters" }),
2145
+ React__namespace.createElement(Parameters, { parameterType: "path", parameters: pathParams }))),
2146
+ queryParams.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2147
+ React__namespace.createElement(SectionSubtitle, { title: "Query Parameters" }),
2080
2148
  React__namespace.createElement(Parameters, { parameterType: "query", parameters: queryParams }))),
2081
- headerParams.length > 0 && (React__namespace.createElement(SubSectionPanel, { title: "Headers" },
2149
+ headerParams.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2150
+ React__namespace.createElement(SectionSubtitle, { title: "Headers", id: "request-headers" }),
2082
2151
  React__namespace.createElement(Parameters, { parameterType: "header", parameters: headerParams }))),
2083
- cookieParams.length > 0 && (React__namespace.createElement(SubSectionPanel, { title: "Cookie" },
2152
+ cookieParams.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2153
+ React__namespace.createElement(SectionSubtitle, { title: "Cookies", id: "request-cookies" }),
2084
2154
  React__namespace.createElement(Parameters, { parameterType: "cookie", parameters: cookieParams }))),
2085
2155
  body && React__namespace.createElement(Body, { onChange: onChange, body: body })));
2086
2156
  };
@@ -2101,15 +2171,15 @@ const Responses = ({ responses: unsortedResponses, onStatusCodeChange, onMediaTy
2101
2171
  }, [activeResponseId]);
2102
2172
  if (!responses.length)
2103
2173
  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 }))))))));
2174
+ return (React__namespace.createElement(mosaic.VStack, { spacing: 8, as: mosaic.Tabs, selectedId: activeResponseId, onChange: setActiveResponseId, appearance: "pill" },
2175
+ React__namespace.createElement(SectionTitle, { title: "Responses" },
2176
+ React__namespace.createElement(mosaic.TabList, { density: "compact" }, responses.map(({ code }) => (React__namespace.createElement(mosaic.Tab, { key: code, id: code, intent: codeToIntentVal(code) }, code))))),
2177
+ React__namespace.createElement(mosaic.TabPanels, { p: 0 }, responses.map(response => (React__namespace.createElement(mosaic.TabPanel, { key: response.code, id: response.code },
2178
+ React__namespace.createElement(Response, { response: response, onMediaTypeChange: onMediaTypeChange })))))));
2110
2179
  };
2111
2180
  Responses.displayName = 'HttpOperation.Responses';
2112
- const Response = ({ response: { contents = [], headers = [], description }, onMediaTypeChange }) => {
2181
+ const Response = ({ response, onMediaTypeChange }) => {
2182
+ const { contents = [], headers = [], description } = response;
2113
2183
  const [chosenContent, setChosenContent] = React__namespace.useState(0);
2114
2184
  const refResolver = useInlineRefResolver();
2115
2185
  const responseContent = contents[chosenContent];
@@ -2117,14 +2187,31 @@ const Response = ({ response: { contents = [], headers = [], description }, onMe
2117
2187
  React__namespace.useEffect(() => {
2118
2188
  responseContent && onMediaTypeChange(responseContent.mediaType);
2119
2189
  }, [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" },
2190
+ return (React__namespace.createElement(mosaic.VStack, { spacing: 8, pt: 8 },
2191
+ description && React__namespace.createElement(MarkdownViewer, { markdown: description }),
2192
+ headers.length > 0 && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2193
+ React__namespace.createElement(SectionSubtitle, { title: "Headers", id: "response-headers" }),
2123
2194
  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 })))))));
2195
+ contents.length > 0 && (React__namespace.createElement(React__namespace.Fragment, null,
2196
+ React__namespace.createElement(SectionSubtitle, { title: "Body", id: "response-body" },
2197
+ React__namespace.createElement(mosaic.Flex, { flex: 1, justify: "end" },
2198
+ 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" }))),
2199
+ schema && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", hideExamples: true, parentCrumbs: ['responses', response.code], renderRootTreeLines: true }))))));
2126
2200
  };
2127
- Response.displayName = 'HttpOperation.Response';
2201
+ Response.displayName = 'HttpOperation.Response';
2202
+ const codeToIntentVal = (code) => {
2203
+ const firstChar = code.charAt(0);
2204
+ switch (firstChar) {
2205
+ case '2':
2206
+ return 'success';
2207
+ case '4':
2208
+ return 'warning';
2209
+ case '5':
2210
+ return 'danger';
2211
+ default:
2212
+ return 'default';
2213
+ }
2214
+ };
2128
2215
 
2129
2216
  const HttpOperationComponent = React__namespace.memo(({ className, data: unresolvedData, layoutOptions, tryItCredentialsPolicy, tryItCorsProxy }) => {
2130
2217
  const data = useResolvedObject(unresolvedData);
@@ -2134,13 +2221,16 @@ const HttpOperationComponent = React__namespace.memo(({ className, data: unresol
2134
2221
  const [responseMediaType, setResponseMediaType] = React__namespace.useState('');
2135
2222
  const [responseStatusCode, setResponseStatusCode] = React__namespace.useState('');
2136
2223
  const [requestBodyIndex, setTextRequestBodyIndex] = React__namespace.useState(0);
2224
+ const prettyName = (data.summary || data.iid || '').trim();
2137
2225
  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 },
2226
+ const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React__namespace.createElement(mosaic.VStack, { spacing: 5 },
2227
+ React__namespace.createElement(mosaic.HStack, { spacing: 5 },
2228
+ !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React__namespace.createElement(mosaic.Heading, { size: 1, fontWeight: "semibold" }, prettyName)) : null,
2229
+ React__namespace.createElement(mosaic.HStack, { spacing: 2 },
2230
+ isDeprecated && React__namespace.createElement(DeprecatedBadge, null),
2231
+ isInternal && React__namespace.createElement(InternalBadge, { isHttpService: true }))),
2232
+ React__namespace.createElement(MethodPath, { method: data.method, path: data.path })));
2233
+ const description = (React__namespace.createElement(mosaic.VStack, { spacing: 10 },
2144
2234
  data.description && React__namespace.createElement(MarkdownViewer, { className: "HttpOperation__Description", markdown: data.description }),
2145
2235
  React__namespace.createElement(Request, { onChange: setTextRequestBodyIndex, operation: data }),
2146
2236
  data.responses && (React__namespace.createElement(Responses, { responses: data.responses, onMediaTypeChange: setResponseMediaType, onStatusCodeChange: setResponseStatusCode }))));
@@ -2150,7 +2240,26 @@ const HttpOperationComponent = React__namespace.memo(({ className, data: unresol
2150
2240
  HttpOperationComponent.displayName = 'HttpOperation.Component';
2151
2241
  const HttpOperation = reactErrorBoundary.withErrorBoundary(HttpOperationComponent, {
2152
2242
  recoverableProps: ['data'],
2153
- });
2243
+ });
2244
+ function MethodPath({ method, path }) {
2245
+ const chosenServer = utils.useAtomValue(chosenServerAtom);
2246
+ let chosenServerUrl = '';
2247
+ if (chosenServer) {
2248
+ chosenServerUrl = chosenServer.url.endsWith('/') ? chosenServer.url.slice(0, -1) : chosenServer.url;
2249
+ }
2250
+ return (React__namespace.createElement(mosaic.Box, null,
2251
+ React__namespace.createElement(MethodPathInner, { method: method, path: path, chosenServerUrl: chosenServerUrl })));
2252
+ }
2253
+ function MethodPathInner({ method, path, chosenServerUrl }) {
2254
+ const isDark = mosaic.useThemeIsDark();
2255
+ const fullUrl = `${chosenServerUrl}${path}`;
2256
+ const pathElem = (React__namespace.createElement(mosaic.Flex, { overflowX: "hidden" },
2257
+ chosenServerUrl ? (React__namespace.createElement(mosaic.Box, { dir: "rtl", color: "muted", fontSize: "lg", textOverflow: "truncate", overflowX: "hidden" }, chosenServerUrl)) : null,
2258
+ React__namespace.createElement(mosaic.Box, { fontSize: "lg", fontWeight: "semibold", flex: 1 }, path)));
2259
+ 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 },
2260
+ 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),
2261
+ pathElem));
2262
+ }
2154
2263
 
2155
2264
  const PoweredByLink = ({ source, pathname, packageType, layout = 'sidebar' }) => {
2156
2265
  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 +2295,7 @@ const ExportButton = ({ original, bundled }) => {
2186
2295
  return items;
2187
2296
  }, [original, bundled]);
2188
2297
  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")) })));
2298
+ 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
2299
  };
2191
2300
 
2192
2301
  const SecuritySchemes = ({ schemes, defaultScheme, defaultCollapsed = false, }) => {
@@ -2206,7 +2315,8 @@ const SecurityScheme = ({ scheme, defaultIsOpen, isCollapsible, showSchemeKey })
2206
2315
  const ServerInfo = ({ servers, mockUrl }) => {
2207
2316
  const mocking = React__namespace.useContext(MockingContext);
2208
2317
  const showMocking = !mocking.hideMocking && mockUrl && isProperUrl(mockUrl);
2209
- const serversToDisplay = getServersToDisplay(servers);
2318
+ const $mockUrl = showMocking ? mockUrl || mocking.mockUrl : undefined;
2319
+ const serversToDisplay = getServersToDisplay(servers, $mockUrl);
2210
2320
  if (!showMocking && serversToDisplay.length === 0) {
2211
2321
  return null;
2212
2322
  }
@@ -2215,14 +2325,11 @@ const ServerInfo = ({ servers, mockUrl }) => {
2215
2325
  React__namespace.createElement(mosaic.Panel.Titlebar, { whitespace: "nowrap" }, "API Base URL"),
2216
2326
  React__namespace.createElement(mosaic.Box, { overflowX: "auto" },
2217
2327
  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 }))))))));
2328
+ React__namespace.createElement(mosaic.VStack, { spacing: 1, divider: true }, serversToDisplay.map((server, index) => (React__namespace.createElement(ServerUrl, Object.assign({}, server, { key: index }))))))))));
2222
2329
  };
2223
2330
  const ServerUrl = ({ description, url, marginBottom = true }) => {
2224
2331
  const { onCopy, hasCopied } = mosaic.useClipboard(url);
2225
- return (React__namespace.createElement(mosaic.Box, { whitespace: "nowrap", mb: marginBottom ? 2 : 0 },
2332
+ return (React__namespace.createElement(mosaic.Box, { whitespace: "nowrap" },
2226
2333
  React__namespace.createElement(mosaic.Text, { pr: 2, fontWeight: "bold" },
2227
2334
  description,
2228
2335
  ":"),
@@ -2271,14 +2378,13 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
2271
2378
  };
2272
2379
  const examples = React__namespace.useMemo(() => generateExamplesFromJsonSchema(data), [data]);
2273
2380
  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 })),
2381
+ const header = (shouldDisplayHeader || isInternal) && (React__namespace.createElement(mosaic.Flex, { justifyContent: "between", alignItems: "center" },
2382
+ React__namespace.createElement(mosaic.HStack, { spacing: 5 },
2383
+ title && (React__namespace.createElement(mosaic.Heading, { size: 1, fontWeight: "semibold" }, title)),
2384
+ React__namespace.createElement(mosaic.HStack, { spacing: 2 }, isInternal && React__namespace.createElement(InternalBadge, null))),
2385
+ exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React__namespace.createElement(ExportButton, Object.assign({}, exportProps))));
2386
+ const description = (React__namespace.createElement(mosaic.VStack, { spacing: 10 },
2387
+ data.description && data.type === 'object' && React__namespace.createElement(MarkdownViewer, { role: "textbox", markdown: data.description }),
2282
2388
  React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(data) })));
2283
2389
  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
2390
  const modelExamples = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideModelExamples) && (React__namespace.createElement(mosaic.Panel, { rounded: true, isCollapsible: false },
@@ -2663,10 +2769,11 @@ const RouterComponent = {
2663
2769
  history: reactRouterDom.BrowserRouter,
2664
2770
  memory: reactRouterDom.MemoryRouter,
2665
2771
  hash: reactRouterDom.HashRouter,
2772
+ static: reactRouterDom.StaticRouter,
2666
2773
  };
2667
- const useRouter = (router, basePath) => {
2774
+ const useRouter = (router, basePath, staticRouterPath) => {
2668
2775
  const Router = RouterComponent[router];
2669
- const routerProps = Object.assign({}, (router !== 'memory' && { basename: basePath }));
2776
+ const routerProps = Object.assign(Object.assign({}, (router !== 'memory' && { basename: basePath })), (router === 'static' && { location: staticRouterPath }));
2670
2777
  return {
2671
2778
  Router,
2672
2779
  routerProps,
@@ -2675,9 +2782,10 @@ const useRouter = (router, basePath) => {
2675
2782
 
2676
2783
  function withRouter(WrappedComponent) {
2677
2784
  const WithRouter = (props) => {
2678
- var _a, _b;
2785
+ var _a, _b, _c;
2679
2786
  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);
2787
+ const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
2788
+ const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
2681
2789
  return (React__namespace.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
2682
2790
  React__namespace.createElement(reactRouterDom.Route, { path: "/" },
2683
2791
  React__namespace.createElement(MarkdownComponentsProvider, { value: { link: ReactRouterMarkdownLink } },
@@ -2881,6 +2989,7 @@ exports.createResolvedObject = createResolvedObject;
2881
2989
  exports.findFirstNode = findFirstNode;
2882
2990
  exports.isHttpOperation = isHttpOperation;
2883
2991
  exports.isHttpService = isHttpService;
2992
+ exports.slugify = slugify;
2884
2993
  exports.useBundleRefsIntoDocument = useBundleRefsIntoDocument;
2885
2994
  exports.useParsedData = useParsedData;
2886
2995
  exports.useParsedValue = useParsedValue;