@stoplight/elements-core 7.3.11 → 7.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -2,32 +2,53 @@ import { __rest, __awaiter } from 'tslib';
2
2
  import * as React from 'react';
3
3
  import React__default, { useContext, useMemo } from 'react';
4
4
  import { resolveInlineRef, isPlainObject as isPlainObject$1, safeParse, safeStringify } from '@stoplight/json';
5
- import _, { isObject, isPlainObject, isArray, throttle, filter, capitalize, flatten, curry, map, omit, pickBy, isString, compact, uniq, uniqBy, orderBy, sortBy, get, omitBy, isEmpty, keys, entries, mapValues, isEqual } from 'lodash';
5
+ import isArray from 'lodash/isArray.js';
6
+ import isObject from 'lodash/isObject.js';
7
+ import isPlainObject from 'lodash/isPlainObject.js';
6
8
  import { parse } from '@stoplight/markdown';
7
9
  import { NodeType, HttpParamStyles } from '@stoplight/types';
8
10
  import { parse as parse$1 } from '@stoplight/yaml';
9
- import { isArray as isArray$1, Flex, Box, Popover, Button, Panel, CopyButton, Menu, Text, Input, Icon, Select, Image, Link, useThemeIsDark, Tooltip, VStack, InvertTheme, Badge, Tabs, TabList, Tab, TabPanels, TabPanel, Heading as Heading$1, HStack, useClipboard, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
11
+ import { isArray as isArray$1, Box, Flex, Icon, Button, Popover, Panel, CopyButton, Menu, Text, Input, Select, FieldButton, Image, Link, useThemeIsDark, HStack, VStack, InvertTheme, Tooltip, Badge, LinkHeading, Tabs, TabList, Tab, TabPanels, TabPanel, Heading as Heading$1, useClipboard, useMosaicContext, Provider as Provider$1 } from '@stoplight/mosaic';
10
12
  import { withErrorBoundary } from '@stoplight/react-error-boundary';
11
13
  import { MarkdownViewer as MarkdownViewer$1, DefaultSMDComponents, MarkdownViewerProvider } from '@stoplight/markdown-viewer';
12
14
  export { DefaultSMDComponents } from '@stoplight/markdown-viewer';
13
- import { faStream, faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faExclamationTriangle, faEye, faLock, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
14
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
15
+ import { faStream, faCrosshairs, faCloud, faBookOpen, faCube, faDatabase, faQuestionCircle, faExclamationCircle, faServer, faExclamationTriangle, faEye, faBolt, faCopy, faCheck } from '@fortawesome/free-solid-svg-icons';
16
+ import throttle from 'lodash/throttle.js';
15
17
  import { selectAll } from 'unist-util-select';
16
18
  import cn from 'classnames';
19
+ import { atomWithStorage, useAtomValue } from 'jotai/utils';
17
20
  import { atom, useAtom, Provider } from 'jotai';
18
21
  import URI from 'urijs';
19
22
  import { CodeViewer } from '@stoplight/mosaic-code-viewer';
20
23
  import HTTPSnippet from 'httpsnippet';
24
+ import flatten from 'lodash/flatten.js';
25
+ import capitalize from 'lodash/capitalize.js';
26
+ import filter from 'lodash/filter.js';
21
27
  import { nanoid } from 'nanoid';
28
+ import curry from 'lodash/curry.js';
29
+ import omit from 'lodash/omit.js';
30
+ import keyBy from 'lodash/keyBy.js';
31
+ import map from 'lodash/map.js';
32
+ import mapValues from 'lodash/mapValues.js';
33
+ import isString from 'lodash/isString.js';
34
+ import pickBy from 'lodash/pickBy.js';
22
35
  import { CodeEditor } from '@stoplight/mosaic-code-editor';
23
36
  import * as Sampler from '@stoplight/json-schema-sampler';
37
+ import compact from 'lodash/compact.js';
38
+ import uniq from 'lodash/uniq.js';
39
+ import orderBy from 'lodash/orderBy.js';
40
+ import uniqBy from 'lodash/uniqBy.js';
24
41
  import formatXml from 'xml-formatter';
25
- import { Link as Link$1, useLocation, BrowserRouter, MemoryRouter, HashRouter, Route } from 'react-router-dom';
26
- import { JsonSchemaViewer, Validations } from '@stoplight/json-schema-viewer';
42
+ import entries from 'lodash/entries.js';
43
+ import keys from 'lodash/keys.js';
44
+ import { JsonSchemaViewer } from '@stoplight/json-schema-viewer';
45
+ import sortBy from 'lodash/sortBy.js';
46
+ import { useLocation, BrowserRouter, MemoryRouter, HashRouter, StaticRouter, Route } from 'react-router-dom';
27
47
  import { HashLink } from 'react-router-hash-link';
28
48
  import { QueryClient, useQueryClient, QueryClientProvider } from 'react-query';
29
49
  import $RefParser from '@stoplight/json-schema-ref-parser';
30
50
  import * as PropTypes from 'prop-types';
51
+ import isEqual from 'lodash/isEqual.js';
31
52
  import * as ReactDOM from 'react-dom';
32
53
 
33
54
  const defaultResolver = (contextObject) => ({ pointer }, _, currentObject) => {
@@ -246,7 +267,7 @@ const findTitle = (parent) => {
246
267
  };
247
268
 
248
269
  function useLocationHash() {
249
- const isBrowser = typeof window !== undefined;
270
+ const isBrowser = typeof window !== 'undefined';
250
271
  const [locationHash, setLocationHash] = React.useState(isBrowser && window.location.hash);
251
272
  React.useEffect(() => {
252
273
  if (!isBrowser)
@@ -262,20 +283,21 @@ const ArticleHeadings = ({ tree, container }) => {
262
283
  const { width } = useComponentSize(container);
263
284
  const showHeadings = width >= 768;
264
285
  const headings = useComputeMarkdownHeadings(tree);
265
- return React.createElement(Headings, { className: "ArticleHeadings", headings: headings, minimal: !showHeadings });
286
+ return React.createElement(Headings, { className: "ArticleHeadings", headings: headings, minimal: !showHeadings, maxWidth: 300 });
266
287
  };
267
- const Headings = ({ headings, className, title = 'On This Page', minimal }) => {
288
+ const Headings = ({ headings, className, title = 'On This Page', minimal, maxWidth }) => {
268
289
  const locationHash = useLocationHash();
269
290
  if (!headings || !headings.length)
270
291
  return null;
271
- const component = (React.createElement("div", { style: { maxHeight: '85vh', overflow: 'auto' } },
292
+ const component = (React.createElement(Box, { overflowY: "auto", style: { maxHeight: '85vh', maxWidth } },
272
293
  title && (React.createElement(Flex, { py: 2, alignItems: "center", fontSize: "sm", fontWeight: "medium", color: "muted", style: { paddingLeft: 18 } },
273
- React.createElement(FontAwesomeIcon, { icon: faStream, className: "sl-mr-2" }),
294
+ React.createElement(Box, { as: Icon, icon: faStream, mr: 2 }),
274
295
  title)),
275
296
  headings.map((heading, i) => (React.createElement(Heading, { key: i, item: heading, isSelected: locationHash === `#${heading.id}` })))));
297
+ const button = React.createElement(Button, { pos: "sticky", size: "sm", borderColor: "light", icon: faStream, style: { top: 10 } });
276
298
  if (minimal) {
277
- return (React.createElement(Box, { pos: "absolute", top: 0, right: 0, style: { top: 10 } },
278
- React.createElement(Popover, { renderTrigger: React.createElement(Button, { size: "sm", borderColor: "light", icon: faStream }), placement: "bottom" },
299
+ return (React.createElement(Box, { pos: "sticky", top: 0, right: 0, style: { top: 10 } },
300
+ React.createElement(Popover, { renderTrigger: button, placement: "bottom" },
279
301
  React.createElement(Box, { className: className }, component))));
280
302
  }
281
303
  return (React.createElement(Box, { pos: "sticky", pr: 4, pl: 16, h: "full", overflowX: "auto", overflowY: "auto", className: className, style: { top: 30 } },
@@ -290,59 +312,13 @@ const ArticleComponent = React.memo(({ data }) => {
290
312
  const tree = React.useMemo(() => (typeof data === 'object' ? data : parse(data)), [data]);
291
313
  if (tree === null)
292
314
  return null;
293
- return (React.createElement(Flex, { className: "sl-elements-article", w: "full", pos: "relative", ref: setContainer },
315
+ return (React.createElement(Flex, { className: "sl-elements-article", justifyContent: "evenly", w: "full", pos: "relative", ref: setContainer },
294
316
  React.createElement(Box, { className: "sl-elements-article-content", style: { width: 0 }, flex: 1 },
295
317
  React.createElement(MarkdownViewer, { markdown: tree })),
296
318
  React.createElement(ArticleHeadings, { tree: tree, container: container })));
297
319
  });
298
320
  const Article = withErrorBoundary(ArticleComponent, { recoverableProps: ['data'] });
299
321
 
300
- const MockingContext = createNamedContext('MockingContext', { mockUrl: undefined, hideMocking: undefined });
301
- const MockingProvider = ({ mockUrl, hideMocking, children }) => {
302
- const info = {
303
- mockUrl,
304
- hideMocking: hideMocking || !mockUrl,
305
- };
306
- return React.createElement(MockingContext.Provider, { value: info }, children);
307
- };
308
- function createNamedContext(name, defaultValue) {
309
- const context = React.createContext(defaultValue);
310
- context.displayName = name;
311
- return context;
312
- }
313
-
314
- function getReadableSecurityName(securityScheme, includeKey = false) {
315
- let name = '';
316
- switch (securityScheme.type) {
317
- case 'apiKey':
318
- name = 'API Key';
319
- break;
320
- case 'http':
321
- name = `${capitalize(securityScheme.scheme)} Auth`;
322
- break;
323
- case 'oauth2':
324
- name = 'OAuth 2.0';
325
- break;
326
- case 'openIdConnect':
327
- name = 'OpenID Connect';
328
- break;
329
- case 'mutualTLS':
330
- name = 'Mutual TLS';
331
- break;
332
- }
333
- return includeKey ? `${name} (${securityScheme.key})` : name;
334
- }
335
- function getServiceUriFromOperation(uri) {
336
- const match = uri === null || uri === void 0 ? void 0 : uri.match(/(.*)\/(paths|operations)/);
337
- return match && match.length > 1 ? match[1] || '/' : undefined;
338
- }
339
- const isOAuth2ImplicitFlow = (maybeFlow) => isObject(maybeFlow) && 'authorizationUrl' in maybeFlow && !('tokenUrl' in maybeFlow);
340
- const isOauth2AuthorizationCodeFlow = (maybeFlow) => isObject(maybeFlow) && 'authorizationUrl' in maybeFlow && 'tokenUrl' in maybeFlow;
341
- const isOauth2ClientCredentialsOrPasswordFlow = (maybeFlow) => isObject(maybeFlow) && !('authorizationUrl' in maybeFlow) && 'tokenUrl' in maybeFlow;
342
- function shouldIncludeKey(schemes, type) {
343
- return filter(schemes, { type }).length > 1;
344
- }
345
-
346
322
  const NodeTypeColors = {
347
323
  http_operation: '#6a6acb',
348
324
  http_service: '#e056fd',
@@ -459,10 +435,36 @@ const HttpCodeDescriptions = {
459
435
  const badgeDefaultBackgroundColor = '#293742';
460
436
  const badgeDefaultColor = '#FFFFFF';
461
437
 
462
- const getServersToDisplay = (originalServers) => {
463
- return originalServers
464
- .map((server, i) => (Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || `Server ${i + 1}` })))
438
+ const MockingContext = createNamedContext('MockingContext', { mockUrl: undefined, hideMocking: undefined });
439
+ const MockingProvider = ({ mockUrl, hideMocking, children }) => {
440
+ const info = {
441
+ mockUrl,
442
+ hideMocking: hideMocking || !mockUrl,
443
+ };
444
+ return React.createElement(MockingContext.Provider, { value: info }, children);
445
+ };
446
+ function createNamedContext(name, defaultValue) {
447
+ const context = React.createContext(defaultValue);
448
+ context.displayName = name;
449
+ return context;
450
+ }
451
+
452
+ const chosenServerAtom = atom(undefined);
453
+
454
+ const getServersToDisplay = (originalServers, mockUrl) => {
455
+ const servers = originalServers
456
+ .map((server, i) => {
457
+ const fallbackDescription = originalServers.length === 1 ? 'Live Server' : `Server ${i + 1}`;
458
+ return Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || fallbackDescription });
459
+ })
465
460
  .filter(server => isProperUrl(server.url));
461
+ if (mockUrl) {
462
+ servers.push({
463
+ description: 'Mock Server',
464
+ url: mockUrl,
465
+ });
466
+ }
467
+ return servers;
466
468
  };
467
469
  const getServerUrlWithDefaultValues = (server) => {
468
470
  var _a;
@@ -728,9 +730,42 @@ const RequestSamples = React__default.memo(({ request, embeddedInMd = false }) =
728
730
  " ",
729
731
  selectedLibrary ? ` / ${selectedLibrary}` : '')) }))),
730
732
  React__default.createElement(Panel.Content, { p: 0 },
731
- React__default.createElement(CodeViewer, { "aria-label": requestSample !== null && requestSample !== void 0 ? requestSample : fallbackText, noCopyButton: true, maxHeight: "400px", language: mosaicCodeViewerLanguage, value: requestSample || fallbackText }))));
733
+ React__default.createElement(CodeViewer, { "aria-label": requestSample !== null && requestSample !== void 0 ? requestSample : fallbackText, noCopyButton: true, maxHeight: "400px", language: mosaicCodeViewerLanguage, value: requestSample || fallbackText, style: embeddedInMd
734
+ ? undefined
735
+ :
736
+ {
737
+ '--fs-code': 12,
738
+ } }))));
732
739
  });
733
740
 
741
+ function getReadableSecurityName(securityScheme, includeKey = false) {
742
+ let name = '';
743
+ switch (securityScheme.type) {
744
+ case 'apiKey':
745
+ name = 'API Key';
746
+ break;
747
+ case 'http':
748
+ name = `${capitalize(securityScheme.scheme)} Auth`;
749
+ break;
750
+ case 'oauth2':
751
+ name = 'OAuth 2.0';
752
+ break;
753
+ case 'openIdConnect':
754
+ name = 'OpenID Connect';
755
+ break;
756
+ case 'mutualTLS':
757
+ name = 'Mutual TLS';
758
+ break;
759
+ }
760
+ return includeKey ? `${name} (${securityScheme.key})` : name;
761
+ }
762
+ const isOAuth2ImplicitFlow = (maybeFlow) => isObject(maybeFlow) && 'authorizationUrl' in maybeFlow && !('tokenUrl' in maybeFlow);
763
+ const isOauth2AuthorizationCodeFlow = (maybeFlow) => isObject(maybeFlow) && 'authorizationUrl' in maybeFlow && 'tokenUrl' in maybeFlow;
764
+ const isOauth2ClientCredentialsOrPasswordFlow = (maybeFlow) => isObject(maybeFlow) && !('authorizationUrl' in maybeFlow) && 'tokenUrl' in maybeFlow;
765
+ function shouldIncludeKey(schemes, type) {
766
+ return filter(schemes, { type }).length > 1;
767
+ }
768
+
734
769
  const useUniqueId = (prefix = 'id_') => React.useRef(`${prefix}${nanoid(8)}`).current;
735
770
 
736
771
  const AuthTokenInput = ({ type, name, value, onChange }) => {
@@ -865,7 +900,14 @@ const SecuritySchemeComponent = (_a) => {
865
900
  };
866
901
  const securitySchemeKeys = ['apiKey', 'http', 'oauth2', 'openIdConnect'];
867
902
 
868
- const caseInsensitivelyEquals = curry((a, b) => a.toUpperCase() === b.toUpperCase());
903
+ const caseInsensitivelyEquals = curry((a, b) => a.toUpperCase() === b.toUpperCase());
904
+ function slugify(name) {
905
+ return name
906
+ .replace(/\/|{|}|\s/g, '-')
907
+ .replace(/-{2,}/, '-')
908
+ .replace(/^-/, '')
909
+ .replace(/-$/, '');
910
+ }
869
911
 
870
912
  const isApiKeySecurityScheme = (maybeIApiKey) => isObject(maybeIApiKey) && maybeIApiKey.type === 'apiKey';
871
913
  const isOAuth2SecurityScheme = (maybeIOAuth2) => isObject(maybeIOAuth2) && maybeIOAuth2.type === 'oauth2';
@@ -976,10 +1018,10 @@ function exampleValue(example) {
976
1018
  }
977
1019
  function getPlaceholderForParameter(parameter) {
978
1020
  var _a, _b;
979
- const parameterValue = getValueForParameter(parameter);
1021
+ const { value: parameterValue, isDefault } = getValueForParameter(parameter);
980
1022
  if (parameterValue)
981
- return `example: ${parameterValue}`;
982
- return parameterValue || String((_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : '');
1023
+ return `${isDefault ? 'defaults to' : 'example'}: ${parameterValue}`;
1024
+ return String((_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : '');
983
1025
  }
984
1026
  function retrieveDefaultFromSchema(parameter) {
985
1027
  var _a;
@@ -988,28 +1030,29 @@ function retrieveDefaultFromSchema(parameter) {
988
1030
  }
989
1031
  const getValueForParameter = (parameter) => {
990
1032
  var _a, _b, _c;
991
- const examples = (_a = parameter.examples) !== null && _a !== void 0 ? _a : [];
992
- if (examples.length > 0)
993
- return exampleValue(examples[0]);
994
1033
  const defaultValue = retrieveDefaultFromSchema(parameter);
995
- if (defaultValue)
996
- return String(defaultValue);
1034
+ if (typeof defaultValue !== 'undefined') {
1035
+ return { value: String(defaultValue), isDefault: true };
1036
+ }
1037
+ const examples = (_a = parameter.examples) !== null && _a !== void 0 ? _a : [];
1038
+ if (examples.length > 0) {
1039
+ return { value: exampleValue(examples[0]) };
1040
+ }
997
1041
  const enums = (_c = (_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.enum) !== null && _c !== void 0 ? _c : [];
998
- if (enums.length > 0)
999
- return String(enums[0]);
1000
- return '';
1042
+ if (enums.length > 0) {
1043
+ return { value: String(enums[0]) };
1044
+ }
1045
+ return { value: '' };
1001
1046
  };
1002
1047
  const getInitialValueForParameter = (parameter) => {
1003
1048
  const isRequired = !!parameter.required;
1004
1049
  if (!isRequired)
1005
1050
  return '';
1006
- return getValueForParameter(parameter);
1051
+ return getValueForParameter(parameter).value;
1007
1052
  };
1008
1053
  const initialParameterValues = params => {
1009
- return _.chain(params)
1010
- .keyBy((param) => param.name)
1011
- .mapValues(param => getInitialValueForParameter(param))
1012
- .value();
1054
+ const paramsByName = keyBy(params, (param) => param.name);
1055
+ return mapValues(paramsByName, param => getInitialValueForParameter(param));
1013
1056
  };
1014
1057
  function mapSchemaPropertiesToParameters(properties, required) {
1015
1058
  return Object.entries(properties).map(([name, schema]) => (Object.assign({ name, schema: typeof schema !== 'boolean' ? schema : undefined, examples: typeof schema !== 'boolean' && schema.examples ? [{ key: 'example', value: schema.examples }] : undefined }, ((required === null || required === void 0 ? void 0 : required.includes(name)) && { required: true }))));
@@ -1150,7 +1193,9 @@ const RequestBody = ({ examples, requestBody, onChange }) => {
1150
1193
  return (React.createElement(Panel, { defaultIsOpen: true },
1151
1194
  React.createElement(Panel.Titlebar, { rightComponent: examples.length > 1 && React.createElement(ExampleMenu, { examples: examples, requestBody: requestBody, onChange: onChange }) }, "Body"),
1152
1195
  React.createElement(Panel.Content, { className: "TextRequestBody" },
1153
- React.createElement(CodeEditor, { onChange: onChange, language: "json", value: requestBody, showLineNumbers: true, padding: 0 }))));
1196
+ React.createElement(CodeEditor, { onChange: onChange, language: "json", value: requestBody, showLineNumbers: true, padding: 0, style: {
1197
+ fontSize: 12,
1198
+ } }))));
1154
1199
  };
1155
1200
  function ExampleMenu({ examples, requestBody, onChange }) {
1156
1201
  const handleClick = React.useCallback((example) => {
@@ -1235,7 +1280,6 @@ const generateExamplesFromJsonSchema = (schema) => {
1235
1280
  : [{ label: 'default', data: '' }];
1236
1281
  }
1237
1282
  catch (e) {
1238
- console.error(e);
1239
1283
  return [{ label: '', data: `Example cannot be created for this schema\n${e}` }];
1240
1284
  }
1241
1285
  };
@@ -1409,8 +1453,8 @@ const formatMultiValueHeader = (...keyValuePairs) => {
1409
1453
  .join(', ');
1410
1454
  };
1411
1455
 
1412
- function getMockData(url, httpOperation, { isEnabled, code, dynamic, example }) {
1413
- return isEnabled && url ? { url, header: buildPreferHeader({ code, dynamic, example }, httpOperation) } : undefined;
1456
+ function getMockData(url, httpOperation, { code, dynamic, example }) {
1457
+ return url ? { url, header: buildPreferHeader({ code, dynamic, example }, httpOperation) } : undefined;
1414
1458
  }
1415
1459
  function buildPreferHeader({ code, example, dynamic }, httpOperation) {
1416
1460
  if (!code) {
@@ -1443,23 +1487,14 @@ function supportsExample(httpOperation, code, exampleKey) {
1443
1487
  return exampleKeys.includes(exampleKey);
1444
1488
  }
1445
1489
 
1446
- const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic }, onOptionsChange, }) => {
1447
- const toggleEnabled = React.useCallback(() => {
1448
- onOptionsChange({ isEnabled: !isEnabled });
1449
- }, [isEnabled, onOptionsChange]);
1490
+ const MockingButton = ({ operation, options: { code, example, dynamic }, onOptionsChange, }) => {
1450
1491
  const operationResponses = operation.responses;
1451
1492
  const setMockingOptions = React.useCallback(({ code, example, dynamic }) => {
1452
- onOptionsChange({ isEnabled, code, example, dynamic });
1453
- }, [isEnabled, onOptionsChange]);
1493
+ onOptionsChange({ code, example, dynamic });
1494
+ }, [onOptionsChange]);
1454
1495
  const menuItems = React.useMemo(() => {
1455
1496
  var _a;
1456
- const items = [
1457
- { id: 'mocking-enabled', title: 'Enabled', isChecked: isEnabled, onPress: toggleEnabled },
1458
- {
1459
- type: 'group',
1460
- 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),
1461
- },
1462
- ];
1497
+ const items = (_a = operationResponses === null || operationResponses === void 0 ? void 0 : operationResponses.filter(operationResponse => Number.isInteger(parseFloat(operationResponse.code)))) === null || _a === void 0 ? void 0 : _a.map(generateOperationResponseMenu);
1463
1498
  function generateOperationResponseMenu(operationResponse) {
1464
1499
  var _a;
1465
1500
  const menuId = `response-${operationResponse.code}`;
@@ -1493,7 +1528,6 @@ const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic
1493
1528
  ];
1494
1529
  const menuItem = {
1495
1530
  id: menuId,
1496
- isDisabled: !isEnabled,
1497
1531
  isChecked: isActive,
1498
1532
  title: operationResponse.code,
1499
1533
  onPress: () => {
@@ -1507,13 +1541,13 @@ const MockingButton = ({ operation, options: { isEnabled, code, example, dynamic
1507
1541
  return menuItem;
1508
1542
  }
1509
1543
  return items;
1510
- }, [code, dynamic, example, isEnabled, operationResponses, setMockingOptions, toggleEnabled]);
1544
+ }, [code, dynamic, example, operationResponses, setMockingOptions]);
1511
1545
  return (React.createElement(Box, null,
1512
- React.createElement(Menu, { "aria-label": "Mocking", items: menuItems, renderTrigger: ({ isOpen }) => (React.createElement(Button, { iconRight: "chevron-down", icon: isEnabled ? 'check' : undefined, appearance: isEnabled ? 'primary' : 'minimal', ml: 2, active: isOpen, size: "sm" }, "Mocking")) })));
1546
+ React.createElement(Menu, { "aria-label": "Mock settings", items: menuItems, renderTrigger: ({ isOpen }) => (React.createElement(FieldButton, { active: isOpen, size: "sm" }, "Mock Settings")) })));
1513
1547
  };
1514
1548
 
1515
- const persistedMockingOptionsAtom = atom({ isEnabled: false });
1516
- const useMockingOptions = () => useAtom(persistedMockingOptionsAtom);
1549
+ const mockingOptionsAtom = atom({});
1550
+ const useMockingOptions = () => useAtom(mockingOptionsAtom);
1517
1551
 
1518
1552
  const OperationParameters = ({ parameters, values, onChangeValue, validate, }) => {
1519
1553
  return (React.createElement(Panel, { defaultIsOpen: true },
@@ -1611,7 +1645,7 @@ const TryItResponse = ({ response }) => {
1611
1645
  ? parseBody(response.bodyText, responseType)
1612
1646
  : response.bodyText })) : response.blob && responseType === 'image' ? (React.createElement(Flex, { justifyContent: "center" },
1613
1647
  React.createElement(Image, { src: URL.createObjectURL(response.blob), alt: "response image" }))) : (React.createElement("p", null,
1614
- React.createElement(FontAwesomeIcon, { icon: faExclamationCircle, className: "sl-mr-2" }),
1648
+ React.createElement(Box, { as: Icon, icon: faExclamationCircle, mr: 2 }),
1615
1649
  "No supported response body returned"))))));
1616
1650
  };
1617
1651
  const ResponseMenu = ({ types, type, onChange }) => {
@@ -1642,7 +1676,32 @@ class NetworkError extends Error {
1642
1676
  }
1643
1677
  const isNetworkError = (error) => error instanceof NetworkError;
1644
1678
 
1645
- const chosenServerAtom = atom(undefined);
1679
+ const ServersDropdown = ({ servers }) => {
1680
+ const [chosenServer, setChosenServer] = useAtom(chosenServerAtom);
1681
+ const serverItems = [
1682
+ {
1683
+ type: 'option_group',
1684
+ title: 'Servers',
1685
+ value: (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || '',
1686
+ onChange: url => {
1687
+ const server = servers.find(server => server.url === url);
1688
+ setChosenServer(server);
1689
+ },
1690
+ children: [
1691
+ ...servers.map((server, i) => ({
1692
+ id: server.url,
1693
+ title: server.name || server.description,
1694
+ description: server.name ? server.description || server.url : server.description ? server.url : undefined,
1695
+ value: server.url,
1696
+ })),
1697
+ ],
1698
+ },
1699
+ ];
1700
+ return (React.createElement(Menu, { "aria-label": "Server", items: serverItems, closeOnPress: true, renderTrigger: ({ isOpen }) => (React.createElement(FieldButton, { icon: faServer, size: "sm", active: isOpen }, (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.name) || (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.description) || 'Server')) }));
1701
+ };
1702
+ ServersDropdown.displayName = 'ServersDropdown';
1703
+
1704
+ const defaultServers = [];
1646
1705
  const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embeddedInMd = false, tryItCredentialsPolicy, corsProxy, }) => {
1647
1706
  var _a, _b, _c, _d, _e, _f, _g;
1648
1707
  const isDark = useThemeIsDark();
@@ -1656,27 +1715,41 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1656
1715
  const [bodyParameterValues, setBodyParameterValues, formDataState] = useBodyParameterState(mediaTypeContent);
1657
1716
  const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
1658
1717
  const [operationAuthValue, setOperationAuthValue] = usePersistedSecuritySchemeWithValues();
1659
- const servers = getServersToDisplay(httpOperation.servers || []);
1718
+ const servers = React.useMemo(() => {
1719
+ const toDisplay = getServersToDisplay(httpOperation.servers || defaultServers, mockUrl);
1720
+ return toDisplay;
1721
+ }, [httpOperation.servers, mockUrl]);
1722
+ const firstServer = servers[0] || null;
1660
1723
  const [chosenServer, setChosenServer] = useAtom(chosenServerAtom);
1724
+ const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
1661
1725
  const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
1662
1726
  React.useEffect(() => {
1663
- if (!chosenServer) {
1664
- setChosenServer(servers[0]);
1727
+ const currentUrl = chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url;
1728
+ const exists = currentUrl && servers.find(s => s.url === currentUrl);
1729
+ if (!exists) {
1730
+ setChosenServer(firstServer);
1665
1731
  }
1666
- }, []);
1732
+ else if (exists !== chosenServer) {
1733
+ setChosenServer(exists);
1734
+ }
1735
+ }, [servers, firstServer, chosenServer, setChosenServer]);
1667
1736
  React.useEffect(() => {
1668
- let isActive = true;
1737
+ let isMounted = true;
1669
1738
  if (onRequestChange || embeddedInMd) {
1670
- buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody, auth: operationAuthValue }, (mockingOptions.isEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
1739
+ buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
1671
1740
  corsProxy })).then(request => {
1672
- if (onRequestChange && isActive)
1673
- onRequestChange(request);
1674
- if (embeddedInMd)
1675
- setRequestData(request);
1741
+ if (isMounted) {
1742
+ if (onRequestChange) {
1743
+ onRequestChange(request);
1744
+ }
1745
+ if (embeddedInMd) {
1746
+ setRequestData(request);
1747
+ }
1748
+ }
1676
1749
  });
1677
1750
  }
1678
1751
  return () => {
1679
- isActive = false;
1752
+ isMounted = false;
1680
1753
  };
1681
1754
  }, [
1682
1755
  httpOperation,
@@ -1690,13 +1763,13 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1690
1763
  corsProxy,
1691
1764
  embeddedInMd,
1692
1765
  ]);
1693
- const handleClick = () => __awaiter(void 0, void 0, void 0, function* () {
1766
+ const handleSendRequest = () => __awaiter(void 0, void 0, void 0, function* () {
1694
1767
  setValidateParameters(true);
1695
1768
  if (hasRequiredButEmptyParameters)
1696
1769
  return;
1697
1770
  try {
1698
1771
  setLoading(true);
1699
- const mockData = getMockData(mockUrl, httpOperation, mockingOptions);
1772
+ const mockData = isMockingEnabled ? getMockData(mockUrl, httpOperation, mockingOptions) : undefined;
1700
1773
  const request = yield buildFetchRequest({
1701
1774
  parameterValues: parameterValuesWithDefaults,
1702
1775
  httpOperation,
@@ -1733,29 +1806,32 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1733
1806
  setLoading(false);
1734
1807
  }
1735
1808
  });
1736
- const serversSelect = (React.createElement(Select, { "aria-label": "Servers", options: servers.map(server => ({ value: server.description || '' })), value: (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.description) || '', onChange: (value) => {
1737
- const server = servers.find(server => server.description === value);
1738
- setChosenServer(server);
1739
- } }));
1740
- const serverDescription = (React.createElement(Tooltip, { renderTrigger: React.createElement(Box, { ml: 2, mr: 1, flexShrink: 0 }, (_d = servers[0]) === null || _d === void 0 ? void 0 : _d.description) },
1741
- "Server Host: ", (_e = servers[0]) === null || _e === void 0 ? void 0 :
1742
- _e.url));
1809
+ const isOnlySendButton = !((_d = httpOperation.security) === null || _d === void 0 ? void 0 : _d.length) && !allParameters.length && !formDataState.isFormDataBody && !mediaTypeContent;
1810
+ const tryItPanelContents = (React.createElement(React.Fragment, null,
1811
+ ((_e = httpOperation.security) === null || _e === void 0 ? void 0 : _e.length) ? (React.createElement(TryItAuth, { onChange: setOperationAuthValue, operationSecurityScheme: (_f = httpOperation.security) !== null && _f !== void 0 ? _f : [], value: operationAuthValue })) : null,
1812
+ allParameters.length > 0 && (React.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
1813
+ formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
1814
+ React.createElement(Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
1815
+ React.createElement(HStack, { alignItems: "center", spacing: 2 },
1816
+ React.createElement(Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
1817
+ servers.length > 1 && React.createElement(ServersDropdown, { servers: servers }),
1818
+ isMockingEnabled && (React.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
1819
+ validateParameters && hasRequiredButEmptyParameters && (React.createElement(Box, { mt: 4, color: "danger-light", fontSize: "sm" },
1820
+ React.createElement(Icon, { icon: faExclamationTriangle, className: "sl-mr-1" }),
1821
+ "You didn't provide all of the required parameters!")))));
1822
+ let tryItPanelElem;
1823
+ if (embeddedInMd) {
1824
+ tryItPanelElem = (React.createElement(Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
1825
+ React.createElement(Panel.Titlebar, { bg: "canvas-300" },
1826
+ React.createElement(Box, { fontWeight: "bold", color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
1827
+ React.createElement(Box, { fontWeight: "medium", ml: 2, textOverflow: "truncate", overflowX: "hidden" }, `${(chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) || ''}${httpOperation.path}`)),
1828
+ tryItPanelContents));
1829
+ }
1830
+ else {
1831
+ tryItPanelElem = (React.createElement(Box, { className: "TryItPanel", bg: "canvas-100", rounded: "lg" }, tryItPanelContents));
1832
+ }
1743
1833
  return (React.createElement(Box, { rounded: "lg", overflowY: "hidden" },
1744
- React.createElement(Panel, { isCollapsible: false, p: 0, className: "TryItPanel" },
1745
- React.createElement(Panel.Titlebar, { rightComponent: servers.length > 1 ? serversSelect : serverDescription, bg: "canvas-300" },
1746
- React.createElement("div", { role: "heading", className: "sl-font-bold" },
1747
- React.createElement(Text, { color: !isDark ? HttpMethodColors[httpOperation.method] : undefined }, httpOperation.method.toUpperCase()),
1748
- React.createElement(Text, { ml: 2 }, httpOperation.path))),
1749
- React.createElement(TryItAuth, { onChange: setOperationAuthValue, operationSecurityScheme: (_f = httpOperation.security) !== null && _f !== void 0 ? _f : [], value: operationAuthValue }),
1750
- allParameters.length > 0 && (React.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
1751
- formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
1752
- React.createElement(Panel.Content, { className: "SendButtonHolder" },
1753
- React.createElement(Flex, { alignItems: "center" },
1754
- React.createElement(Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleClick, size: "sm" }, "Send Request"),
1755
- mockUrl && (React.createElement(MockingButton, { options: mockingOptions, onOptionsChange: setMockingOptions, operation: httpOperation }))),
1756
- validateParameters && hasRequiredButEmptyParameters && (React.createElement(Box, { mt: 4, color: "danger-light", fontSize: "sm" },
1757
- React.createElement(Icon, { icon: faExclamationTriangle, className: "sl-mr-1" }),
1758
- "You didn't provide all of the required parameters!")))),
1834
+ tryItPanelElem,
1759
1835
  requestData && embeddedInMd && React.createElement(RequestSamples, { request: requestData, embeddedInMd: true }),
1760
1836
  response && !('error' in response) && React.createElement(TryItResponse, { response: response }),
1761
1837
  response && 'error' in response && React.createElement(ResponseError, { state: response })));
@@ -1792,7 +1868,9 @@ const ResponseExamples = ({ httpOperation, responseMediaType, responseStatusCode
1792
1868
  const examplesSelect = userDefinedExamples && userDefinedExamples.length > 1 && (React__default.createElement(Select, { "aria-label": "Response Example", value: String(chosenExampleIndex), options: userDefinedExamples.map((example, index) => ({ value: index, label: example.key })), onChange: (value) => setChosenExampleIndex(parseInt(String(value), 10)), size: "sm", triggerTextPrefix: "Response Example: " }));
1793
1869
  return (React__default.createElement(Panel, { rounded: true, isCollapsible: false },
1794
1870
  React__default.createElement(Panel.Titlebar, null, examplesSelect || React__default.createElement(Text, { color: "body" }, "Response Example")),
1795
- React__default.createElement(Panel.Content, { p: 0 }, show || !exceedsSize(responseExample) ? (React__default.createElement(CodeViewer, { "aria-label": responseExample, noCopyButton: true, maxHeight: "400px", language: "json", value: responseExample, showLineNumbers: true })) : (React__default.createElement(LoadMore, { loading: loading, onClick: handleLoadMore })))));
1871
+ React__default.createElement(Panel.Content, { p: 0 }, show || !exceedsSize(responseExample) ? (React__default.createElement(CodeViewer, { "aria-label": responseExample, noCopyButton: true, maxHeight: "500px", language: "json", value: responseExample, showLineNumbers: true, style: {
1872
+ '--fs-code': 12,
1873
+ } })) : (React__default.createElement(LoadMore, { loading: loading, onClick: handleLoadMore })))));
1796
1874
  };
1797
1875
 
1798
1876
  const TryItWithRequestSamples = (_a) => {
@@ -1806,21 +1884,16 @@ const TryItWithRequestSamples = (_a) => {
1806
1884
  React.createElement(ResponseExamples, Object.assign({}, props))));
1807
1885
  };
1808
1886
 
1809
- const TwoColumnLayout = ({ header, right, left, className }) => (React__default.createElement(Box, { w: "full", className: className },
1887
+ const TwoColumnLayout = ({ header, right, left, className }) => (React__default.createElement(VStack, { w: "full", className: className, spacing: 8 },
1810
1888
  header,
1811
- React__default.createElement(Flex, { mt: header ? 12 : undefined },
1812
- React__default.createElement(Box, { style: { width: 0 }, flex: 1 }, left),
1889
+ React__default.createElement(Flex, null,
1890
+ React__default.createElement(Box, { w: 0, flex: 1 }, left),
1813
1891
  right && (React__default.createElement(Box, { ml: 16, pos: "relative", w: "2/5", style: { maxWidth: 500 } }, right)))));
1814
1892
 
1815
1893
  const DeprecatedBadge = () => (React__default.createElement(Tooltip, { renderTrigger: React__default.createElement(Badge, { intent: "warning", icon: faExclamationCircle, "data-testid": "badge-deprecated" }, "Deprecated") }, "This operation has been marked as deprecated, which means it could be removed at some point in the future."));
1816
- const InternalBadge = ({ isHttpService }) => (React__default.createElement(Tooltip, { renderTrigger: React__default.createElement(Badge, { icon: faEye, "data-testid": "badge-internal", className: "sl-bg-danger sl-ml-0" }, "Internal") }, `This ${isHttpService ? 'operation' : 'model'} is marked as internal and won't be visible in public docs.`));
1817
- const SecurityBadge = ({ scheme, httpServiceUri, includeKey }) => {
1818
- const badge = (React__default.createElement(Badge, { icon: faLock, "data-testid": "badge-security", className: "sl-truncate", style: { backgroundColor: badgeDefaultBackgroundColor, color: badgeDefaultColor } }, getReadableSecurityName(scheme, includeKey)));
1819
- return httpServiceUri ? (React__default.createElement(Link$1, { to: `${httpServiceUri}?security=${scheme.key}`, className: "sl-no-underline sl-block" }, badge)) : (badge);
1820
- };
1821
- const VersionBadge = ({ value, backgroundColor }) => (React__default.createElement(Badge, { appearance: "solid", size: "sm", style: {
1894
+ const InternalBadge = ({ isHttpService }) => (React__default.createElement(Tooltip, { renderTrigger: React__default.createElement(Badge, { icon: faEye, "data-testid": "badge-internal", bg: "danger" }, "Internal") }, `This ${isHttpService ? 'operation' : 'model'} is marked as internal and won't be visible in public docs.`));
1895
+ const VersionBadge = ({ value, backgroundColor }) => (React__default.createElement(Badge, { appearance: "solid", size: "sm", border: 0, style: {
1822
1896
  backgroundColor: backgroundColor || badgeDefaultBackgroundColor,
1823
- border: 'none',
1824
1897
  color: badgeDefaultColor,
1825
1898
  } }, enhanceVersionString(value)));
1826
1899
  const enhanceVersionString = (version) => {
@@ -1829,32 +1902,112 @@ const enhanceVersionString = (version) => {
1829
1902
  return `v${version}`;
1830
1903
  };
1831
1904
 
1832
- const SectionTitle = ({ title, children }) => {
1833
- return (React.createElement(Flex, { role: "heading", borderB: true, mb: 3, pb: 3, "aria-label": title, align: "baseline" },
1834
- React.createElement(Text, { size: "xl", fontWeight: "semibold", mr: 5 }, title),
1905
+ const oauthFlowNames = {
1906
+ implicit: 'Implicit',
1907
+ authorizationCode: 'Authorization Code',
1908
+ clientCredentials: 'Client Credentials',
1909
+ password: 'Password',
1910
+ };
1911
+ function getDefaultDescription(scheme) {
1912
+ switch (scheme.type) {
1913
+ case 'apiKey':
1914
+ return getApiKeyDescription(scheme.in, scheme.name);
1915
+ case 'http':
1916
+ switch (scheme.scheme) {
1917
+ case 'basic':
1918
+ return getBasicAuthDescription();
1919
+ case 'bearer':
1920
+ return getBearerAuthDescription();
1921
+ case 'digest':
1922
+ return getDigestAuthDescription();
1923
+ }
1924
+ case 'oauth2':
1925
+ return getOAuthDescription(scheme);
1926
+ }
1927
+ return '';
1928
+ }
1929
+ function getApiKeyDescription(inProperty, name) {
1930
+ return `An API key is a token that you provide when making API calls. Include the token in a ${inProperty} parameter called \`${name}\`.
1931
+
1932
+ Example: ${inProperty === 'query' ? `\`?${name}=123\`` : `\`${name}: 123\``}`;
1933
+ }
1934
+ function getBasicAuthDescription() {
1935
+ return `Basic authentication is a simple authentication scheme built into the HTTP protocol.
1936
+ To use it, send your HTTP requests with an Authorization header that contains the word Basic
1937
+ followed by a space and a base64-encoded string \`username:password\`.
1938
+
1939
+ Example: \`Authorization: Basic ZGVtbzpwQDU1dzByZA==\``;
1940
+ }
1941
+ function getBearerAuthDescription() {
1942
+ return `Provide your bearer token in the Authorization header when making requests to protected resources.
1943
+
1944
+ Example: \`Authorization: Bearer 123\``;
1945
+ }
1946
+ function getDigestAuthDescription() {
1947
+ return `Provide your encrypted digest scheme data in the Authorization header when making requests to protected resources.
1948
+
1949
+ Example: \`Authorization: Digest username=guest, realm="test", nonce="2", uri="/uri", response="123"\``;
1950
+ }
1951
+ function getOAuthDescription(scheme) {
1952
+ const flows = keys(scheme.flows);
1953
+ return flows.map(flow => getOAuthFlowDescription(oauthFlowNames[flow], scheme.flows[flow])).join('\n\n');
1954
+ }
1955
+ function getOAuthFlowDescription(title, flow) {
1956
+ let description = `**${title} OAuth Flow**`;
1957
+ description +=
1958
+ isOAuth2ImplicitFlow(flow) || isOauth2AuthorizationCodeFlow(flow)
1959
+ ? `\n\nAuthorize URL: ${flow.authorizationUrl}`
1960
+ : '';
1961
+ description +=
1962
+ isOauth2AuthorizationCodeFlow(flow) || isOauth2ClientCredentialsOrPasswordFlow(flow)
1963
+ ? `\n\nToken URL: ${flow.tokenUrl}`
1964
+ : '';
1965
+ description += flow.refreshUrl ? `\n\nRefresh URL: ${flow.refreshUrl}` : '';
1966
+ const scopes = entries(flow.scopes);
1967
+ if (scopes.length) {
1968
+ description += `\n\nScopes:
1969
+ ${scopes.map(([key, value]) => `- \`${key}\` - ${value}`).join('\n')}`;
1970
+ }
1971
+ return description;
1972
+ }
1973
+
1974
+ const SectionTitle = ({ title, id, size = 2, children }) => {
1975
+ return (React.createElement(HStack, { spacing: 6 },
1976
+ React.createElement(Box, { as: LinkHeading, size: size, "aria-label": title, id: id || slugify(title) }, title),
1835
1977
  children));
1836
1978
  };
1837
- const SubSectionPanel = ({ title, children, hasContent, rightComponent }) => {
1838
- return (React.createElement(Panel, { appearance: "minimal", isCollapsible: hasContent, defaultIsOpen: true },
1979
+ const SectionSubtitle = props => {
1980
+ return React.createElement(SectionTitle, Object.assign({}, props, { size: 3 }));
1981
+ };
1982
+ const SubSectionPanel = ({ title, children, hasContent, rightComponent, defaultIsOpen = true, onChange, }) => {
1983
+ return (React.createElement(Panel, { isCollapsible: hasContent, defaultIsOpen: defaultIsOpen, onChange: onChange, appearance: "outlined" },
1839
1984
  React.createElement(Panel.Titlebar, { fontWeight: "medium", rightComponent: rightComponent },
1840
1985
  React.createElement("div", { role: "heading" }, title)),
1841
- hasContent !== false && (React.createElement(Panel.Content, { pr: 3, className: "sl-py-0 sl-pl-0" }, children))));
1986
+ hasContent !== false && React.createElement(Panel.Content, null, children)));
1842
1987
  };
1843
1988
 
1844
- const Body = ({ body: { contents = [], description }, onChange }) => {
1989
+ const isBodyEmpty = (body) => {
1990
+ if (!body)
1991
+ return true;
1992
+ const { contents = [], description } = body;
1993
+ return contents.length === 0 && !(description === null || description === void 0 ? void 0 : description.trim());
1994
+ };
1995
+ const Body = ({ body, onChange }) => {
1845
1996
  var _a;
1846
1997
  const refResolver = useInlineRefResolver();
1847
1998
  const [chosenContent, setChosenContent] = React.useState(0);
1848
1999
  React.useEffect(() => {
1849
2000
  onChange(chosenContent);
1850
2001
  }, [chosenContent]);
1851
- if (contents.length === 0 && !description)
2002
+ if (isBodyEmpty(body))
1852
2003
  return null;
2004
+ const { contents = [], description } = body;
1853
2005
  const schema = (_a = contents[chosenContent]) === null || _a === void 0 ? void 0 : _a.schema;
1854
- return (React.createElement(SubSectionPanel, { title: "Body", rightComponent: contents.length > 0 && (React.createElement(Select, { "aria-label": "Request Body Content Type", value: String(chosenContent), onChange: (value) => setChosenContent(parseInt(String(value), 10)), options: contents.map((content, index) => ({ label: content.mediaType, value: index })), size: "sm" })) },
1855
- description && React.createElement(MarkdownViewer, { className: "sl-my-2", markdown: description }),
1856
- isJSONSchema(schema) && (React.createElement(Box, null,
1857
- React.createElement(JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", hideExamples: true })))));
2006
+ return (React.createElement(VStack, { spacing: 6 },
2007
+ React.createElement(SectionSubtitle, { title: "Body", id: "request-body" }, contents.length > 0 && (React.createElement(Flex, { flex: 1, justify: "end" },
2008
+ React.createElement(Select, { "aria-label": "Request Body Content Type", value: String(chosenContent), onChange: (value) => setChosenContent(parseInt(String(value), 10)), options: contents.map((content, index) => ({ label: content.mediaType, value: index })), size: "sm" })))),
2009
+ description && React.createElement(MarkdownViewer, { markdown: description }),
2010
+ isJSONSchema(schema) && (React.createElement(JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", hideExamples: true, renderRootTreeLines: true }))));
1858
2011
  };
1859
2012
  Body.displayName = 'HttpOperation.Body';
1860
2013
 
@@ -1878,68 +2031,81 @@ const defaultStyle = {
1878
2031
  cookie: HttpParamStyles.Form,
1879
2032
  };
1880
2033
  const Parameters = ({ parameters, parameterType }) => {
1881
- if (!parameters || !parameters.length)
2034
+ const schema = React.useMemo(() => httpOperationParamsToSchema({ parameters, parameterType }), [parameters, parameterType]);
2035
+ if (!schema)
1882
2036
  return null;
1883
- return (React.createElement(VStack, { spacing: 2, pl: 6, divider: React.createElement(Box, { borderT: true, borderColor: "light", w: "full" }) }, sortBy(parameters, ['required', 'name']).map(parameter => {
1884
- return React.createElement(Parameter, { key: parameter.name, parameter: parameter, parameterType: parameterType });
1885
- })));
2037
+ return React.createElement(JsonSchemaViewer, { schema: schema, disableCrumbs: true });
1886
2038
  };
1887
2039
  Parameters.displayName = 'HttpOperation.Parameters';
1888
- const Parameter = ({ parameter, parameterType }) => {
1889
- var _a, _b, _c, _d, _e;
1890
- if (!parameter)
2040
+ const httpOperationParamsToSchema = ({ parameters, parameterType }) => {
2041
+ var _a;
2042
+ if (!parameters || !parameters.length)
1891
2043
  return null;
1892
- const description = get(parameter, 'description') || get(parameter, 'schema.description');
1893
- const rootType = get(parameter, 'schema.type', 'unknown');
1894
- 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;
1895
- const format = (_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.format;
1896
- const deprecated = get(parameter, 'deprecated') || get(parameter, 'schema.deprecated', false);
1897
- const parameterExamples = ((_d = parameter.examples) === null || _d === void 0 ? void 0 : _d.map(example => {
1898
- if (isNodeExample(example)) {
1899
- return example.value;
2044
+ const schema = {
2045
+ properties: {},
2046
+ required: [],
2047
+ };
2048
+ const sortedParams = sortBy(parameters, ['required', 'name']);
2049
+ for (const p of sortedParams) {
2050
+ if (!p.schema)
2051
+ continue;
2052
+ const { name, description, required, deprecated, examples, style } = p;
2053
+ const paramExamples = (examples === null || examples === void 0 ? void 0 : examples.map(example => {
2054
+ if (isNodeExample(example)) {
2055
+ return example.value;
2056
+ }
2057
+ return example.externalValue;
2058
+ })) || [];
2059
+ const schemaExamples = (_a = p.schema) === null || _a === void 0 ? void 0 : _a.examples;
2060
+ const schemaExamplesArray = Array.isArray(schemaExamples) ? schemaExamples : [];
2061
+ const paramDescription = description || p.schema.description;
2062
+ const paramDeprecated = deprecated || p.schema.deprecated;
2063
+ const paramStyle = style && defaultStyle[parameterType] !== style ? readableStyles[style] || style : undefined;
2064
+ schema.properties[p.name] = Object.assign(Object.assign({}, p.schema), { description: paramDescription, examples: [...paramExamples, ...schemaExamplesArray], deprecated: paramDeprecated, style: paramStyle });
2065
+ if (required) {
2066
+ schema.required.push(name);
1900
2067
  }
1901
- return example.externalValue;
1902
- })) || [];
1903
- const schemaExamples = (_e = parameter.schema) === null || _e === void 0 ? void 0 : _e.examples;
1904
- const schemaExamplesArray = Array.isArray(schemaExamples) ? schemaExamples : [];
1905
- const validations = omitBy(Object.assign(Object.assign(Object.assign(Object.assign({}, omit(parameter, ['name', 'required', 'deprecated', 'description', 'schema', 'style', 'examples'])), omit(get(parameter, 'schema'), ['description', 'type', 'deprecated'])), omit(get(parameter, 'schema.items'), ['description', 'type', 'deprecated'])), { examples: [...parameterExamples, ...schemaExamplesArray] }), value => (typeof value === 'object' && isEmpty(value)) || typeof value === 'undefined');
1906
- return (React.createElement("div", { className: "HttpOperation__Parameters" },
1907
- React.createElement("div", { className: "sl-flex sl-items-center sl-my-2" },
1908
- React.createElement("div", { className: "sl-flex sl-items-baseline sl-text-base sl-flex-1" },
1909
- React.createElement("div", { className: "sl-font-mono sl-font-bold" }, parameter.name),
1910
- React.createElement("div", { className: 'sl-ml-2 sl-text-muted' }, format ? `${type}<${format}>` : type)),
1911
- React.createElement("div", { className: "sl-text-sm sl-text-warning" },
1912
- deprecated && React.createElement("span", { className: "sl-ml-2" }, "deprecated"),
1913
- parameter.required && React.createElement("span", { className: "sl-ml-2" }, "required"))),
1914
- description && (React.createElement("div", { className: "sl-w-full sl-text-muted sl-text-sm sl-my-2" },
1915
- React.createElement(MarkdownViewer$1, { markdown: description }))),
1916
- React.createElement("div", { className: "sl-text-sm" },
1917
- React.createElement(Validations, { validations: validations })),
1918
- parameter.style && defaultStyle[parameterType] !== parameter.style && (React.createElement("div", { className: "sl-flex sl-my-2" },
1919
- React.createElement("span", { className: "sl-px-1 sl-text-muted sl-font-mono sl-border sl-rounded-lg sl-text-sm sl-capitalize", style: { backgroundColor: '#EDF2F7' } }, readableStyles[parameter.style] || parameter.style)))));
1920
- };
1921
- Parameter.displayName = 'HttpOperation.Parameter';
2068
+ }
2069
+ return schema;
2070
+ };
1922
2071
 
1923
- const Request = ({ operation: { path, method, request, request: { path: pathParams = [], headers: headerParams = [], cookie: cookieParams = [], body, query: queryParams = [], } = {}, security, }, onChange, }) => {
2072
+ const Request = ({ operation: { request, request: { path: pathParams = [], headers: headerParams = [], cookie: cookieParams = [], body, query: queryParams = [], } = {}, security, }, onChange, }) => {
1924
2073
  if (!request || typeof request !== 'object')
1925
2074
  return null;
1926
- const pathParamBlock = (React.createElement("div", null,
1927
- React.createElement(Text, { textTransform: "uppercase", mr: 1, color: HttpMethodColors[method] }, method),
1928
- ' ',
1929
- path));
1930
- return (React.createElement(Box, { mb: 10 },
2075
+ const bodyIsEmpty = isBodyEmpty(body);
2076
+ const securitySchemes = flatten(security);
2077
+ const hasRequestData = Boolean(securitySchemes.length ||
2078
+ pathParams.length ||
2079
+ queryParams.length ||
2080
+ headerParams.length ||
2081
+ cookieParams.length ||
2082
+ !bodyIsEmpty);
2083
+ if (!hasRequestData)
2084
+ return null;
2085
+ return (React.createElement(VStack, { spacing: 8 },
1931
2086
  React.createElement(SectionTitle, { title: "Request" }),
1932
- React.createElement(SubSectionPanel, { title: pathParamBlock, hasContent: pathParams.length > 0 },
1933
- React.createElement(Parameters, { parameterType: "path", parameters: pathParams })),
1934
- queryParams.length > 0 && (React.createElement(SubSectionPanel, { title: "Query" },
2087
+ securitySchemes.length > 0 && (React.createElement(VStack, { spacing: 3 }, securitySchemes.map((scheme, i) => (React.createElement(SecurityPanel, { key: i, scheme: scheme, includeKey: shouldIncludeKey(securitySchemes, scheme.type) }))))),
2088
+ pathParams.length > 0 && (React.createElement(VStack, { spacing: 5 },
2089
+ React.createElement(SectionSubtitle, { title: "Path Parameters" }),
2090
+ React.createElement(Parameters, { parameterType: "path", parameters: pathParams }))),
2091
+ queryParams.length > 0 && (React.createElement(VStack, { spacing: 5 },
2092
+ React.createElement(SectionSubtitle, { title: "Query Parameters" }),
1935
2093
  React.createElement(Parameters, { parameterType: "query", parameters: queryParams }))),
1936
- headerParams.length > 0 && (React.createElement(SubSectionPanel, { title: "Headers" },
2094
+ headerParams.length > 0 && (React.createElement(VStack, { spacing: 5 },
2095
+ React.createElement(SectionSubtitle, { title: "Headers", id: "request-headers" }),
1937
2096
  React.createElement(Parameters, { parameterType: "header", parameters: headerParams }))),
1938
- cookieParams.length > 0 && (React.createElement(SubSectionPanel, { title: "Cookie" },
2097
+ cookieParams.length > 0 && (React.createElement(VStack, { spacing: 5 },
2098
+ React.createElement(SectionSubtitle, { title: "Cookies", id: "request-cookies" }),
1939
2099
  React.createElement(Parameters, { parameterType: "cookie", parameters: cookieParams }))),
1940
2100
  body && React.createElement(Body, { onChange: onChange, body: body })));
1941
2101
  };
1942
- Request.displayName = 'HttpOperation.Request';
2102
+ Request.displayName = 'HttpOperation.Request';
2103
+ const schemeExpandedState = atomWithStorage('HttpOperation_security_expanded', {});
2104
+ const SecurityPanel = ({ scheme, includeKey }) => {
2105
+ const [expandedState, setExpanded] = useAtom(schemeExpandedState);
2106
+ return (React.createElement(SubSectionPanel, { title: `Security: ${getReadableSecurityName(scheme, includeKey)}`, defaultIsOpen: !!expandedState[scheme.key], onChange: isOpen => setExpanded(Object.assign(Object.assign({}, expandedState), { [scheme.key]: isOpen })) },
2107
+ React.createElement(MarkdownViewer, { style: { fontSize: 12 }, markdown: `${scheme.description || ''}\n\n` + getDefaultDescription(scheme) })));
2108
+ };
1943
2109
 
1944
2110
  const Responses = ({ responses: unsortedResponses, onStatusCodeChange, onMediaTypeChange }) => {
1945
2111
  var _a, _b;
@@ -1950,15 +2116,15 @@ const Responses = ({ responses: unsortedResponses, onStatusCodeChange, onMediaTy
1950
2116
  }, [activeResponseId]);
1951
2117
  if (!responses.length)
1952
2118
  return null;
1953
- return (React.createElement(Tabs, { selectedId: activeResponseId, onChange: setActiveResponseId },
1954
- React.createElement(Box, null,
1955
- React.createElement(SectionTitle, { title: "Responses" },
1956
- React.createElement(TabList, null, responses.map(({ code }) => (React.createElement(Tab, { key: code, id: code }, code))))),
1957
- React.createElement(Box, { as: TabPanels, mt: 4 }, responses.map(response => (React.createElement(TabPanel, { key: response.code, id: response.code },
1958
- React.createElement(Response, { response: response, onMediaTypeChange: onMediaTypeChange }))))))));
2119
+ return (React.createElement(VStack, { spacing: 8, as: Tabs, selectedId: activeResponseId, onChange: setActiveResponseId, appearance: "pill" },
2120
+ React.createElement(SectionTitle, { title: "Responses" },
2121
+ React.createElement(TabList, { density: "compact" }, responses.map(({ code }) => (React.createElement(Tab, { key: code, id: code, intent: codeToIntentVal(code) }, code))))),
2122
+ React.createElement(TabPanels, { p: 0 }, responses.map(response => (React.createElement(TabPanel, { key: response.code, id: response.code },
2123
+ React.createElement(Response, { response: response, onMediaTypeChange: onMediaTypeChange })))))));
1959
2124
  };
1960
2125
  Responses.displayName = 'HttpOperation.Responses';
1961
- const Response = ({ response: { contents = [], headers = [], description }, onMediaTypeChange }) => {
2126
+ const Response = ({ response, onMediaTypeChange }) => {
2127
+ const { contents = [], headers = [], description } = response;
1962
2128
  const [chosenContent, setChosenContent] = React.useState(0);
1963
2129
  const refResolver = useInlineRefResolver();
1964
2130
  const responseContent = contents[chosenContent];
@@ -1966,16 +2132,33 @@ const Response = ({ response: { contents = [], headers = [], description }, onMe
1966
2132
  React.useEffect(() => {
1967
2133
  responseContent && onMediaTypeChange(responseContent.mediaType);
1968
2134
  }, [responseContent]);
1969
- return (React.createElement(Box, null,
1970
- description && React.createElement(MarkdownViewer, { className: "sl-ml-1 sl-mb-6", markdown: description }),
1971
- headers.length > 0 && (React.createElement(SubSectionPanel, { title: "Headers" },
2135
+ return (React.createElement(VStack, { spacing: 8, pt: 8 },
2136
+ description && React.createElement(MarkdownViewer, { markdown: description }),
2137
+ headers.length > 0 && (React.createElement(VStack, { spacing: 5 },
2138
+ React.createElement(SectionSubtitle, { title: "Headers", id: "response-headers" }),
1972
2139
  React.createElement(Parameters, { parameterType: "header", parameters: headers }))),
1973
- contents.length > 0 && (React.createElement(SubSectionPanel, { title: "Body", rightComponent: React.createElement(Select, { "aria-label": "Response Body Content Type", value: String(chosenContent), onChange: (value) => setChosenContent(parseInt(String(value), 10)), options: contents.map((content, index) => ({ label: content.mediaType, value: index })), size: "sm" }) }, schema && (React.createElement(Box, null,
1974
- React.createElement(JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", hideExamples: true })))))));
2140
+ contents.length > 0 && (React.createElement(React.Fragment, null,
2141
+ React.createElement(SectionSubtitle, { title: "Body", id: "response-body" },
2142
+ React.createElement(Flex, { flex: 1, justify: "end" },
2143
+ React.createElement(Select, { "aria-label": "Response Body Content Type", value: String(chosenContent), onChange: (value) => setChosenContent(parseInt(String(value), 10)), options: contents.map((content, index) => ({ label: content.mediaType, value: index })), size: "sm" }))),
2144
+ schema && (React.createElement(JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", hideExamples: true, parentCrumbs: ['responses', response.code], renderRootTreeLines: true }))))));
1975
2145
  };
1976
- Response.displayName = 'HttpOperation.Response';
2146
+ Response.displayName = 'HttpOperation.Response';
2147
+ const codeToIntentVal = (code) => {
2148
+ const firstChar = code.charAt(0);
2149
+ switch (firstChar) {
2150
+ case '2':
2151
+ return 'success';
2152
+ case '4':
2153
+ return 'warning';
2154
+ case '5':
2155
+ return 'danger';
2156
+ default:
2157
+ return 'default';
2158
+ }
2159
+ };
1977
2160
 
1978
- const HttpOperationComponent = React.memo(({ className, data: unresolvedData, uri, allowRouting = false, layoutOptions, tryItCredentialsPolicy, tryItCorsProxy, }) => {
2161
+ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, layoutOptions, tryItCredentialsPolicy, tryItCorsProxy }) => {
1979
2162
  const data = useResolvedObject(unresolvedData);
1980
2163
  const mocking = React.useContext(MockingContext);
1981
2164
  const isDeprecated = !!data.deprecated;
@@ -1983,32 +2166,50 @@ const HttpOperationComponent = React.memo(({ className, data: unresolvedData, ur
1983
2166
  const [responseMediaType, setResponseMediaType] = React.useState('');
1984
2167
  const [responseStatusCode, setResponseStatusCode] = React.useState('');
1985
2168
  const [requestBodyIndex, setTextRequestBodyIndex] = React.useState(0);
1986
- const httpServiceUri = uri && getServiceUriFromOperation(uri);
1987
- const securitySchemes = flatten(data.security);
1988
- const hasBadges = isDeprecated || securitySchemes.length > 0 || isInternal;
1989
- const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React.createElement(React.Fragment, null,
1990
- !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (React.createElement(Heading$1, { size: 1, mb: 4, fontWeight: "semibold" }, data.summary || data.iid || `${data.method} ${data.path}`)),
1991
- hasBadges && (React.createElement(HStack, { spacing: 2 },
1992
- isDeprecated && React.createElement(DeprecatedBadge, null),
1993
- sortBy(securitySchemes, 'type').map((scheme, i) => (React.createElement(SecurityBadge, { key: i, scheme: scheme, httpServiceUri: allowRouting ? httpServiceUri : undefined, includeKey: shouldIncludeKey(securitySchemes, scheme.type) }))),
1994
- isInternal && React.createElement(InternalBadge, { isHttpService: true })))));
1995
- const description = (React.createElement(React.Fragment, null,
1996
- data.description && (React.createElement(MarkdownViewer, { className: "HttpOperation__Description sl-mb-10", markdown: data.description })),
2169
+ const prettyName = (data.summary || data.iid || '').trim();
2170
+ const hasBadges = isDeprecated || isInternal;
2171
+ const header = (!(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) || hasBadges) && (React.createElement(VStack, { spacing: 5 },
2172
+ React.createElement(HStack, { spacing: 5 },
2173
+ !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && prettyName ? (React.createElement(Heading$1, { size: 1, fontWeight: "semibold" }, prettyName)) : null,
2174
+ React.createElement(HStack, { spacing: 2 },
2175
+ isDeprecated && React.createElement(DeprecatedBadge, null),
2176
+ isInternal && React.createElement(InternalBadge, { isHttpService: true }))),
2177
+ React.createElement(MethodPath, { method: data.method, path: data.path })));
2178
+ const description = (React.createElement(VStack, { spacing: 10 },
2179
+ data.description && React.createElement(MarkdownViewer, { className: "HttpOperation__Description", markdown: data.description }),
1997
2180
  React.createElement(Request, { onChange: setTextRequestBodyIndex, operation: data }),
1998
2181
  data.responses && (React.createElement(Responses, { responses: data.responses, onMediaTypeChange: setResponseMediaType, onStatusCodeChange: setResponseStatusCode }))));
1999
- const tryItPanel = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryItPanel) && (React.createElement(Box, { className: "HttpOperation__gutter" },
2000
- React.createElement(TryItWithRequestSamples, { httpOperation: data, responseMediaType: responseMediaType, responseStatusCode: responseStatusCode, requestBodyIndex: requestBodyIndex, hideTryIt: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryIt, tryItCredentialsPolicy: tryItCredentialsPolicy, mockUrl: mocking.hideMocking ? undefined : mocking.mockUrl, corsProxy: tryItCorsProxy })));
2182
+ const tryItPanel = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryItPanel) && (React.createElement(TryItWithRequestSamples, { httpOperation: data, responseMediaType: responseMediaType, responseStatusCode: responseStatusCode, requestBodyIndex: requestBodyIndex, hideTryIt: layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideTryIt, tryItCredentialsPolicy: tryItCredentialsPolicy, mockUrl: mocking.hideMocking ? undefined : mocking.mockUrl, corsProxy: tryItCorsProxy }));
2001
2183
  return (React.createElement(TwoColumnLayout, { className: cn('HttpOperation', className), header: header, left: description, right: tryItPanel }));
2002
2184
  });
2003
2185
  HttpOperationComponent.displayName = 'HttpOperation.Component';
2004
2186
  const HttpOperation = withErrorBoundary(HttpOperationComponent, {
2005
2187
  recoverableProps: ['data'],
2006
- });
2188
+ });
2189
+ function MethodPath({ method, path }) {
2190
+ const chosenServer = useAtomValue(chosenServerAtom);
2191
+ let chosenServerUrl = '';
2192
+ if (chosenServer) {
2193
+ chosenServerUrl = chosenServer.url.endsWith('/') ? chosenServer.url.slice(0, -1) : chosenServer.url;
2194
+ }
2195
+ return (React.createElement(Box, null,
2196
+ React.createElement(MethodPathInner, { method: method, path: path, chosenServerUrl: chosenServerUrl })));
2197
+ }
2198
+ function MethodPathInner({ method, path, chosenServerUrl }) {
2199
+ const isDark = useThemeIsDark();
2200
+ const fullUrl = `${chosenServerUrl}${path}`;
2201
+ const pathElem = (React.createElement(Flex, { overflowX: "hidden" },
2202
+ chosenServerUrl ? (React.createElement(Box, { dir: "rtl", color: "muted", fontSize: "lg", textOverflow: "truncate", overflowX: "hidden" }, chosenServerUrl)) : null,
2203
+ React.createElement(Box, { fontSize: "lg", fontWeight: "semibold", flex: 1 }, path)));
2204
+ return (React.createElement(HStack, { spacing: 3, pl: 2.5, pr: 4, py: 2, bg: "canvas-50", rounded: "lg", fontFamily: "mono", display: "inline-flex", maxW: "full", title: fullUrl },
2205
+ React.createElement(Box, { py: 1, px: 2.5, rounded: "lg", bg: !isDark ? HttpMethodColors[method] : 'canvas-100', color: !isDark ? 'on-primary' : 'body', fontSize: "lg", fontWeight: "semibold", textTransform: "uppercase" }, method),
2206
+ pathElem));
2207
+ }
2007
2208
 
2008
2209
  const PoweredByLink = ({ source, pathname, packageType, layout = 'sidebar' }) => {
2009
2210
  return (React.createElement(Flex, { as: "a", align: "center", borderT: layout === 'stacked' ? undefined : true, px: layout === 'stacked' ? 1 : 4, py: 3, justify: layout === 'stacked' ? 'end' : undefined, href: `https://stoplight.io/?utm_source=${packageType}&utm_medium=${source}&utm_campaign=powered_by&utm_content=${pathname}`, target: "_blank", rel: "noopener noreferrer" },
2010
- React.createElement(FontAwesomeIcon, { icon: faBolt, className: "sl-mr-1 fa-fw", style: { color: 'rgba(144, 97, 249, 1)' } }),
2011
- React.createElement("div", null,
2211
+ React.createElement(Box, { as: Icon, icon: faBolt, mr: 1, className: "fa-fw", style: { color: 'rgba(144, 97, 249, 1)' } }),
2212
+ React.createElement(Box, null,
2012
2213
  "powered by\u00A0",
2013
2214
  React.createElement("strong", null, "Stoplight"))));
2014
2215
  };
@@ -2039,91 +2240,28 @@ const ExportButton = ({ original, bundled }) => {
2039
2240
  return items;
2040
2241
  }, [original, bundled]);
2041
2242
  return (React.createElement(Box, null,
2042
- React.createElement(Menu, { "aria-label": "Export", items: menuItems, renderTrigger: ({ isOpen }) => (React.createElement(Button, { iconRight: "chevron-down", appearance: "default", ml: 2, active: isOpen, size: "sm" }, "Export")) })));
2243
+ React.createElement(Menu, { "aria-label": "Export", items: menuItems, placement: "bottom right", renderTrigger: ({ isOpen }) => (React.createElement(Button, { iconRight: "chevron-down", appearance: "default", ml: 2, active: isOpen, size: "sm" }, "Export")) })));
2043
2244
  };
2044
2245
 
2045
- const oauthFlowNames = {
2046
- implicit: 'Implicit',
2047
- authorizationCode: 'Authorization Code',
2048
- clientCredentials: 'Client Credentials',
2049
- password: 'Password',
2050
- };
2051
- const SecuritySchemes = ({ schemes, defaultScheme }) => {
2052
- return (React__default.createElement(Panel, { rounded: true, isCollapsible: false },
2246
+ const SecuritySchemes = ({ schemes, defaultScheme, defaultCollapsed = false, }) => {
2247
+ return (React__default.createElement(Panel, { rounded: true, isCollapsible: defaultCollapsed },
2053
2248
  React__default.createElement(Panel.Titlebar, { bg: "canvas-300" },
2054
- React__default.createElement("span", { role: "heading" }, "Security")),
2055
- React__default.createElement(Panel.Content, { p: 0 }, sortBy(schemes, 'type').map((scheme, i) => (React__default.createElement(Panel, { key: i, defaultIsOpen: defaultScheme ? scheme.key === defaultScheme : i === 0, isCollapsible: schemes.length > 1 },
2056
- React__default.createElement(Panel.Titlebar, null,
2057
- React__default.createElement("span", { role: "heading" }, getReadableSecurityName(scheme, shouldIncludeKey(schemes, scheme.type)))),
2058
- React__default.createElement(Panel.Content, null,
2059
- React__default.createElement(MarkdownViewer, { style: { fontSize: 12 }, markdown: `${scheme.description || ''}\n\n` + getDefaultDescription(scheme) }))))))));
2249
+ React__default.createElement(Box, { as: "span", role: "heading" }, "Security")),
2250
+ React__default.createElement(Panel.Content, { p: 0 }, sortBy(schemes, 'type').map((scheme, i) => (React__default.createElement(SecurityScheme, { key: i, scheme: scheme, defaultIsOpen: defaultScheme ? scheme.key === defaultScheme : i === 0, isCollapsible: schemes.length > 1, showSchemeKey: shouldIncludeKey(schemes, scheme.type) }))))));
2060
2251
  };
2061
- function getDefaultDescription(scheme) {
2062
- switch (scheme.type) {
2063
- case 'apiKey':
2064
- return getApiKeyDescription(scheme.in, scheme.name);
2065
- case 'http':
2066
- switch (scheme.scheme) {
2067
- case 'basic':
2068
- return getBasicAuthDescription();
2069
- case 'bearer':
2070
- return getBearerAuthDescription();
2071
- case 'digest':
2072
- return getDigestAuthDescription();
2073
- }
2074
- case 'oauth2':
2075
- return getOAuthDescription(scheme);
2076
- }
2077
- return '';
2078
- }
2079
- function getApiKeyDescription(inProperty, name) {
2080
- return `An API key is a token that you provide when making API calls. Include the token in a ${inProperty} parameter called \`${name}\`.
2081
-
2082
- Example: ${inProperty === 'query' ? `\`?${name}=123\`` : `\`${name}: 123\``}`;
2083
- }
2084
- function getBasicAuthDescription() {
2085
- return `Basic authentication is a simple authentication scheme built into the HTTP protocol.
2086
- To use it, send your HTTP requests with an Authorization header that contains the word Basic
2087
- followed by a space and a base64-encoded string \`username:password\`.
2088
-
2089
- Example: \`Authorization: Basic ZGVtbzpwQDU1dzByZA==\``;
2090
- }
2091
- function getBearerAuthDescription() {
2092
- return `Provide your bearer token in the Authorization header when making requests to protected resources.
2093
-
2094
- Example: \`Authorization: Bearer 123\``;
2095
- }
2096
- function getDigestAuthDescription() {
2097
- return `Provide your encrypted digest scheme data in the Authorization header when making requests to protected resources.
2098
-
2099
- Example: \`Authorization: Digest username=guest, realm="test", nonce="2", uri="/uri", response="123"\``;
2100
- }
2101
- function getOAuthDescription(scheme) {
2102
- const flows = keys(scheme.flows);
2103
- return flows.map(flow => getOAuthFlowDescription(oauthFlowNames[flow], scheme.flows[flow])).join('\n\n');
2104
- }
2105
- function getOAuthFlowDescription(title, flow) {
2106
- let description = `**${title} OAuth Flow**`;
2107
- description +=
2108
- isOAuth2ImplicitFlow(flow) || isOauth2AuthorizationCodeFlow(flow)
2109
- ? `\n\nAuthorize URL: ${flow.authorizationUrl}`
2110
- : '';
2111
- description +=
2112
- isOauth2AuthorizationCodeFlow(flow) || isOauth2ClientCredentialsOrPasswordFlow(flow)
2113
- ? `\n\nToken URL: ${flow.tokenUrl}`
2114
- : '';
2115
- description += flow.refreshUrl ? `\n\nRefresh URL: ${flow.refreshUrl}` : '';
2116
- description += `\n\nScopes:
2117
- ${entries(flow.scopes)
2118
- .map(([key, value]) => `- \`${key}\` - ${value}`)
2119
- .join('\n')}`;
2120
- return description;
2121
- }
2252
+ const SecurityScheme = ({ scheme, defaultIsOpen, isCollapsible, showSchemeKey }) => {
2253
+ return (React__default.createElement(Panel, { defaultIsOpen: defaultIsOpen, isCollapsible: isCollapsible },
2254
+ React__default.createElement(Panel.Titlebar, null,
2255
+ React__default.createElement(Box, { as: "span", role: "heading" }, getReadableSecurityName(scheme, showSchemeKey))),
2256
+ React__default.createElement(Panel.Content, null,
2257
+ React__default.createElement(MarkdownViewer, { style: { fontSize: 12 }, markdown: `${scheme.description || ''}\n\n` + getDefaultDescription(scheme) }))));
2258
+ };
2122
2259
 
2123
2260
  const ServerInfo = ({ servers, mockUrl }) => {
2124
2261
  const mocking = React.useContext(MockingContext);
2125
2262
  const showMocking = !mocking.hideMocking && mockUrl && isProperUrl(mockUrl);
2126
- const serversToDisplay = getServersToDisplay(servers);
2263
+ const $mockUrl = showMocking ? mockUrl || mocking.mockUrl : undefined;
2264
+ const serversToDisplay = getServersToDisplay(servers, $mockUrl);
2127
2265
  if (!showMocking && serversToDisplay.length === 0) {
2128
2266
  return null;
2129
2267
  }
@@ -2132,14 +2270,11 @@ const ServerInfo = ({ servers, mockUrl }) => {
2132
2270
  React.createElement(Panel.Titlebar, { whitespace: "nowrap" }, "API Base URL"),
2133
2271
  React.createElement(Box, { overflowX: "auto" },
2134
2272
  React.createElement(Panel.Content, { w: "full", className: "sl-flex sl-flex-col" },
2135
- serversToDisplay.map((server, index) => (React.createElement(ServerUrl, Object.assign({}, server, { key: index })))),
2136
- showMocking && (React.createElement(React.Fragment, null,
2137
- React.createElement(Box, { borderT: 2, pt: 2, borderColor: "light", w: "full" }),
2138
- React.createElement(ServerUrl, { description: "Mock Server", url: mockUrl || '', marginBottom: false }))))))));
2273
+ React.createElement(VStack, { spacing: 1, divider: true }, serversToDisplay.map((server, index) => (React.createElement(ServerUrl, Object.assign({}, server, { key: index }))))))))));
2139
2274
  };
2140
2275
  const ServerUrl = ({ description, url, marginBottom = true }) => {
2141
2276
  const { onCopy, hasCopied } = useClipboard(url);
2142
- return (React.createElement(Box, { whitespace: "nowrap", mb: marginBottom ? 2 : 0 },
2277
+ return (React.createElement(Box, { whitespace: "nowrap" },
2143
2278
  React.createElement(Text, { pr: 2, fontWeight: "bold" },
2144
2279
  description,
2145
2280
  ":"),
@@ -2188,14 +2323,13 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
2188
2323
  };
2189
2324
  const examples = React.useMemo(() => generateExamplesFromJsonSchema(data), [data]);
2190
2325
  const shouldDisplayHeader = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.noHeading) && (title !== undefined || (exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport)));
2191
- const header = (shouldDisplayHeader || isInternal) && (React.createElement(React.Fragment, null,
2192
- shouldDisplayHeader && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
2193
- React.createElement(Heading$1, { size: 1, mb: 4, fontWeight: "semibold" }, title),
2194
- exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps)))),
2195
- isInternal && (React.createElement(HStack, { spacing: 2, mb: 12 },
2196
- React.createElement(InternalBadge, null)))));
2197
- const description = (React.createElement(React.Fragment, null,
2198
- data.description && data.type === 'object' && (React.createElement(MarkdownViewer, { className: "sl-mb-6", role: "textbox", markdown: data.description })),
2326
+ const header = (shouldDisplayHeader || isInternal) && (React.createElement(Flex, { justifyContent: "between", alignItems: "center" },
2327
+ React.createElement(HStack, { spacing: 5 },
2328
+ title && (React.createElement(Heading$1, { size: 1, fontWeight: "semibold" }, title)),
2329
+ React.createElement(HStack, { spacing: 2 }, isInternal && React.createElement(InternalBadge, null))),
2330
+ exportProps && !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideExport) && React.createElement(ExportButton, Object.assign({}, exportProps))));
2331
+ const description = (React.createElement(VStack, { spacing: 10 },
2332
+ data.description && data.type === 'object' && React.createElement(MarkdownViewer, { role: "textbox", markdown: data.description }),
2199
2333
  React.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(data) })));
2200
2334
  const examplesSelect = examples.length > 1 && (React.createElement(Select, { "aria-label": "Example", value: String(chosenExampleIndex), options: examples.map(({ label }, index) => ({ value: index, label })), onChange: (value) => setChosenExampleIndex(parseInt(String(value), 10)), size: "sm", triggerTextPrefix: "Example: " }));
2201
2335
  const modelExamples = !(layoutOptions === null || layoutOptions === void 0 ? void 0 : layoutOptions.hideModelExamples) && (React.createElement(Panel, { rounded: true, isCollapsible: false },
@@ -2248,7 +2382,7 @@ const SidebarLayout = React.forwardRef(({ sidebar, children, maxContentWidth = M
2248
2382
  paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
2249
2383
  minWidth: `${sidebarWidth}px`,
2250
2384
  } }, sidebar),
2251
- React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, overflowY: "auto", overflowX: "hidden", w: "full" },
2385
+ React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full" },
2252
2386
  React.createElement(Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
2253
2387
  });
2254
2388
 
@@ -2284,7 +2418,7 @@ const SchemaAndDescription = ({ title: titleProp, schema }) => {
2284
2418
  const title = titleProp !== null && titleProp !== void 0 ? titleProp : schema.title;
2285
2419
  return (React__default.createElement(Box, { py: 2 },
2286
2420
  title && (React__default.createElement(Flex, { alignItems: "center", p: 2 },
2287
- React__default.createElement(FontAwesomeIcon, { icon: NodeTypeIconDefs[NodeType.Model], color: NodeTypeColors[NodeType.Model] }),
2421
+ React__default.createElement(Icon, { icon: NodeTypeIconDefs[NodeType.Model], color: NodeTypeColors[NodeType.Model] }),
2288
2422
  React__default.createElement(Box, { color: "muted", px: 2 }, title))),
2289
2423
  React__default.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
2290
2424
  };
@@ -2580,10 +2714,11 @@ const RouterComponent = {
2580
2714
  history: BrowserRouter,
2581
2715
  memory: MemoryRouter,
2582
2716
  hash: HashRouter,
2717
+ static: StaticRouter,
2583
2718
  };
2584
- const useRouter = (router, basePath) => {
2719
+ const useRouter = (router, basePath, staticRouterPath) => {
2585
2720
  const Router = RouterComponent[router];
2586
- const routerProps = Object.assign({}, (router !== 'memory' && { basename: basePath }));
2721
+ const routerProps = Object.assign(Object.assign({}, (router !== 'memory' && { basename: basePath })), (router === 'static' && { location: staticRouterPath }));
2587
2722
  return {
2588
2723
  Router,
2589
2724
  routerProps,
@@ -2592,9 +2727,10 @@ const useRouter = (router, basePath) => {
2592
2727
 
2593
2728
  function withRouter(WrappedComponent) {
2594
2729
  const WithRouter = (props) => {
2595
- var _a, _b;
2730
+ var _a, _b, _c;
2596
2731
  const basePath = (_a = props.basePath) !== null && _a !== void 0 ? _a : '/';
2597
- const { Router, routerProps } = useRouter((_b = props.router) !== null && _b !== void 0 ? _b : 'history', basePath);
2732
+ const staticRouterPath = (_b = props.staticRouterPath) !== null && _b !== void 0 ? _b : '';
2733
+ const { Router, routerProps } = useRouter((_c = props.router) !== null && _c !== void 0 ? _c : 'history', basePath, staticRouterPath);
2598
2734
  return (React.createElement(Router, Object.assign({}, routerProps, { key: basePath }),
2599
2735
  React.createElement(Route, { path: "/" },
2600
2736
  React.createElement(MarkdownComponentsProvider, { value: { link: ReactRouterMarkdownLink } },
@@ -2612,24 +2748,26 @@ function useBundleRefsIntoDocument(document, options) {
2612
2748
  setBundledData(document);
2613
2749
  return;
2614
2750
  }
2615
- let isActive = true;
2751
+ let isMounted = true;
2616
2752
  doBundle(document, baseUrl)
2617
2753
  .then(res => {
2618
- if (isActive) {
2754
+ if (isMounted) {
2619
2755
  setBundledData(Object.assign({}, res));
2620
2756
  }
2621
2757
  })
2622
2758
  .catch(reason => {
2623
2759
  var _a;
2624
2760
  if (typeof reason === 'object' && reason !== null && 'files' in reason) {
2625
- setBundledData(Object.assign({}, reason.files.schema));
2761
+ if (isMounted) {
2762
+ setBundledData(Object.assign({}, reason.files.schema));
2763
+ }
2626
2764
  }
2627
2765
  else {
2628
2766
  console.warn(`Could bundle: ${(_a = reason === null || reason === void 0 ? void 0 : reason.message) !== null && _a !== void 0 ? _a : 'Unknown error'}`);
2629
2767
  }
2630
2768
  });
2631
2769
  return () => {
2632
- isActive = false;
2770
+ isMounted = false;
2633
2771
  };
2634
2772
  }, [document, baseUrl]);
2635
2773
  return bundledData;
@@ -2766,4 +2904,4 @@ const createElementClass = (Component, propDescriptors) => {
2766
2904
  };
2767
2905
  };
2768
2906
 
2769
- export { DeprecatedBadge, Docs, ExportButton, HttpMethodColors, InlineRefResolverProvider, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, useBundleRefsIntoDocument, useParsedData, useParsedValue, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };
2907
+ export { DeprecatedBadge, Docs, ExportButton, HttpMethodColors, InlineRefResolverProvider, Logo, MarkdownComponentsProvider, MockingProvider, NodeTypeColors, NodeTypeIconDefs, NodeTypePrettyName, NonIdealState, ParsedDocs, PersistenceContextProvider, PoweredByLink, ReactRouterMarkdownLink, SidebarLayout, Styled, TableOfContents, TryIt, TryItWithRequestSamples, createElementClass, createResolvedObject, findFirstNode, isHttpOperation, isHttpService, slugify, useBundleRefsIntoDocument, useParsedData, useParsedValue, useRouter, withMosaicProvider, withPersistenceBoundary, withQueryClientProvider, withRouter, withStyles };