@stoplight/elements-core 7.5.12 → 7.5.15

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.
@@ -1,4 +1,4 @@
1
1
  import { IHttpOperation } from '@stoplight/types';
2
2
  export declare const singleSecurityOperation: IHttpOperation;
3
- export declare const emptySecurityOperation: IHttpOperation;
4
- export declare const duplicatedSecurityScheme: IHttpOperation;
3
+ export declare const emptySecurityOperation: any;
4
+ export declare const duplicatedSecurityScheme: any;
@@ -1,5 +1,5 @@
1
- import { IServer } from '@stoplight/types';
2
1
  import * as React from 'react';
2
+ import { IServer } from '../../../utils/http-spec/IServer';
3
3
  interface ServerInfoProps {
4
4
  servers: IServer[];
5
5
  mockUrl?: string;
@@ -1,10 +1,12 @@
1
1
  import { IMediaTypeContent } from '@stoplight/types';
2
2
  import * as React from 'react';
3
- import { BodyParameterValues } from './request-body-utils';
3
+ import { BodyParameterValues, ParameterOptional } from './request-body-utils';
4
4
  interface FormDataBodyProps {
5
5
  specification: IMediaTypeContent;
6
6
  values: BodyParameterValues;
7
7
  onChangeValues: (newValues: BodyParameterValues) => void;
8
+ onChangeParameterAllow: (newValue: ParameterOptional) => void;
9
+ isAllowedEmptyValues: ParameterOptional;
8
10
  }
9
11
  export declare const FormDataBody: React.FC<FormDataBodyProps>;
10
12
  export {};
@@ -1,12 +1,13 @@
1
1
  import { IMediaTypeContent } from '@stoplight/types';
2
2
  import * as React from 'react';
3
3
  export declare type BodyParameterValues = Record<string, string | File>;
4
+ export declare type ParameterOptional = Record<string, boolean>;
4
5
  export declare const isFormDataContent: (content: IMediaTypeContent) => boolean;
5
6
  export declare function createRequestBody(mediaTypeContent: IMediaTypeContent | undefined, bodyParameterValues: BodyParameterValues | undefined): Promise<string | Blob | ArrayBuffer | ArrayBufferView | FormData | ReadableStream<Uint8Array> | undefined>;
6
- export declare const useBodyParameterState: (mediaTypeContent: IMediaTypeContent | undefined) => readonly [BodyParameterValues, React.Dispatch<React.SetStateAction<BodyParameterValues>>, {
7
+ export declare const useBodyParameterState: (mediaTypeContent: IMediaTypeContent | undefined) => readonly [BodyParameterValues, React.Dispatch<React.SetStateAction<BodyParameterValues>>, ParameterOptional, React.Dispatch<React.SetStateAction<ParameterOptional>>, {
7
8
  readonly isFormDataBody: true;
8
9
  readonly bodySpecification: IMediaTypeContent;
9
- }] | readonly [BodyParameterValues, React.Dispatch<React.SetStateAction<BodyParameterValues>>, {
10
+ }] | readonly [BodyParameterValues, React.Dispatch<React.SetStateAction<BodyParameterValues>>, ParameterOptional, React.Dispatch<React.SetStateAction<ParameterOptional>>, {
10
11
  readonly isFormDataBody: false;
11
12
  readonly bodySpecification: undefined;
12
13
  }];
@@ -5,6 +5,9 @@ interface ParameterProps {
5
5
  parameter: ParameterSpec;
6
6
  value?: string;
7
7
  onChange: SelectProps['onChange'];
8
+ isOptional: boolean;
9
+ onChangeOptional: (optional: boolean) => void;
10
+ canChangeOptional: boolean;
8
11
  validate?: boolean;
9
12
  }
10
13
  export declare const ParameterEditor: React.FC<ParameterProps>;
@@ -1,6 +1,8 @@
1
- import { IHttpParam } from '@stoplight/types';
1
+ import type { IHttpParam, INodeExample, INodeExternalExample } from '@stoplight/types';
2
2
  import { JSONSchema7Definition } from 'json-schema';
3
- export declare type ParameterSpec = Pick<IHttpParam, 'name' | 'examples' | 'schema' | 'required'>;
3
+ export declare type ParameterSpec = Pick<IHttpParam, 'name' | 'schema' | 'required'> & {
4
+ examples?: (Omit<INodeExample, 'id'> | Omit<INodeExternalExample, 'id'>)[];
5
+ };
4
6
  export declare function parameterOptions(parameter: ParameterSpec): ({
5
7
  value: string | number;
6
8
  } | {
@@ -1,4 +1,4 @@
1
- import { IServer } from '@stoplight/types';
1
+ import type { IServer } from '../../../utils/http-spec/IServer';
2
2
  export declare type ServersDropdownProps = {
3
3
  servers: IServer[];
4
4
  };
@@ -1,5 +1,6 @@
1
- import { Dictionary, IHttpOperation, IMediaTypeContent, IServer } from '@stoplight/types';
1
+ import { Dictionary, IHttpOperation, IMediaTypeContent } from '@stoplight/types';
2
2
  import { Request as HarRequest } from 'har-format';
3
+ import { IServer } from '../../utils/http-spec/IServer';
3
4
  import { HttpSecuritySchemeWithValues } from './Auth/authentication-utils';
4
5
  import { BodyParameterValues } from './Body/request-body-utils';
5
6
  import { MockData } from './Mocking/mocking-utils';
@@ -1,4 +1,4 @@
1
- import { IServer } from '@stoplight/types';
1
+ import type { IServer } from '../../utils/http-spec/IServer';
2
2
  export declare const chosenServerAtom: import("jotai").Atom<IServer | null | undefined> & {
3
3
  write: (get: {
4
4
  <Value>(atom: import("jotai").Atom<Value | Promise<Value>>): Value;
package/core.css CHANGED
@@ -52,6 +52,16 @@
52
52
  max-height: 162px; /* 4.5 lines plus padding */
53
53
  }
54
54
 
55
+ .sl-elements .Checkbox {
56
+ max-width: 15px;
57
+ padding-right: 3px;
58
+ }
59
+
60
+ .sl-elements .TextForCheckBox {
61
+ padding-top: 6px;
62
+ padding-left: 9px;
63
+ }
64
+
55
65
  .sl-elements .TextRequestBody {
56
66
  max-height: 200px;
57
67
  overflow-y: auto;
package/index.esm.js CHANGED
@@ -141,9 +141,9 @@ function isHttpService(maybeHttpService) {
141
141
  function isHttpOperation(maybeHttpOperation) {
142
142
  return isStoplightNode(maybeHttpOperation) && 'method' in maybeHttpOperation && 'path' in maybeHttpOperation;
143
143
  }
144
+ const properUrl = new RegExp(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/);
144
145
  function isProperUrl(url) {
145
- const properUrl = new RegExp(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/);
146
- return url.match(properUrl);
146
+ return properUrl.test(url);
147
147
  }
148
148
 
149
149
  function useParsedData(nodeType, data) {
@@ -158,6 +158,7 @@ const parserMap = {
158
158
  [NodeType.Generic]: parseUnknown,
159
159
  [NodeType.TableOfContents]: parseUnknown,
160
160
  [NodeType.SpectralRuleset]: parseUnknown,
161
+ [NodeType.Styleguide]: parseUnknown,
161
162
  [NodeType.Unknown]: parseUnknown,
162
163
  };
163
164
  function parseArticleData(rawData) {
@@ -235,6 +236,7 @@ const NodeTypeColors = {
235
236
  unknown: '',
236
237
  table_of_contents: '',
237
238
  spectral_ruleset: '',
239
+ styleguide: '',
238
240
  };
239
241
  const NodeTypePrettyName = {
240
242
  http_operation: 'Endpoint',
@@ -246,6 +248,7 @@ const NodeTypePrettyName = {
246
248
  unknown: '',
247
249
  table_of_contents: '',
248
250
  spectral_ruleset: '',
251
+ styleguide: '',
249
252
  };
250
253
  const NodeTypeIconDefs = {
251
254
  http_operation: faCrosshairs,
@@ -257,6 +260,7 @@ const NodeTypeIconDefs = {
257
260
  generic: faQuestionCircle,
258
261
  table_of_contents: faQuestionCircle,
259
262
  spectral_ruleset: faQuestionCircle,
263
+ styleguide: faQuestionCircle,
260
264
  };
261
265
  const HttpMethodColors = {
262
266
  get: 'success',
@@ -357,13 +361,16 @@ function createNamedContext(name, defaultValue) {
357
361
 
358
362
  const chosenServerAtom = atom(undefined);
359
363
 
364
+ function isValidServer(server) {
365
+ return server.url !== null && isProperUrl(server.url);
366
+ }
360
367
  const getServersToDisplay = (originalServers, mockUrl) => {
361
368
  const servers = originalServers
362
369
  .map((server, i) => {
363
370
  const fallbackDescription = originalServers.length === 1 ? 'Live Server' : `Server ${i + 1}`;
364
371
  return Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || fallbackDescription });
365
372
  })
366
- .filter(server => isProperUrl(server.url));
373
+ .filter(isValidServer);
367
374
  if (mockUrl) {
368
375
  servers.push({
369
376
  description: 'Mock Server',
@@ -379,7 +386,13 @@ const getServerUrlWithDefaultValues = (server) => {
379
386
  variables.forEach(([variableName, variableInfo]) => {
380
387
  urlString = urlString.replace(`{${variableName}}`, variableInfo.default);
381
388
  });
382
- let url = URI(urlString);
389
+ let url;
390
+ try {
391
+ url = URI(urlString);
392
+ }
393
+ catch (_b) {
394
+ return null;
395
+ }
383
396
  if (url.is('relative') && typeof window !== 'undefined') {
384
397
  url = url.absoluteTo(window.location.origin);
385
398
  }
@@ -969,9 +982,10 @@ function mapSchemaPropertiesToParameters(properties, required) {
969
982
  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 }))));
970
983
  }
971
984
 
972
- const ParameterEditor = ({ parameter, value, onChange, validate }) => {
985
+ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
973
986
  var _a, _b;
974
987
  const inputId = useUniqueId(`id_${parameter.name}_`);
988
+ const inputCheckId = useUniqueId(`id_${parameter.name}_checked`);
975
989
  const parameterValueOptions = parameterOptions(parameter);
976
990
  const examples = exampleOptions(parameter);
977
991
  const selectedExample = (_a = examples === null || examples === void 0 ? void 0 : examples.find(e => e.value === value)) !== null && _a !== void 0 ? _a : selectExampleOption;
@@ -982,10 +996,19 @@ const ParameterEditor = ({ parameter, value, onChange, validate }) => {
982
996
  React.createElement(Text, { mx: 3 }, ":"),
983
997
  React.createElement("div", null, parameterValueOptions ? (React.createElement(Select, { flex: 1, "aria-label": parameter.name, options: parameterValueOptions, value: value || '', onChange: onChange })) : (React.createElement(Flex, { flex: 1 },
984
998
  React.createElement(Input, { id: inputId, "aria-label": parameter.name, appearance: requiredButEmpty ? 'default' : 'minimal', flex: 1, placeholder: getPlaceholderForParameter(parameter), type: ((_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.type) === 'number' ? 'number' : 'text', required: true, intent: requiredButEmpty ? 'danger' : 'default', value: value || '', onChange: e => onChange && onChange(e.currentTarget.value) }),
985
- examples && (React.createElement(Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange })))))));
999
+ examples && (React.createElement(Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange }))))),
1000
+ canChangeOptional && !parameter.required && (React.createElement(React.Fragment, null,
1001
+ React.createElement("div", null),
1002
+ React.createElement("div", null),
1003
+ React.createElement("div", null,
1004
+ React.createElement(Flex, { flex: 1 },
1005
+ React.createElement(Input, { className: "Checkbox", "aria-label": `${parameter.name}-checkbox`, id: inputCheckId, flex: 1, type: "checkbox", intent: "success", size: "sm", checked: isOptional, onChange: e => onChangeOptional(!e.target.checked) }),
1006
+ React.createElement(Text, { className: "TextForCheckBox", flex: 1, as: "label", "aria-hidden": "true", "data-testid": "param-check", htmlFor: inputCheckId, fontSize: "base" },
1007
+ "Omit ",
1008
+ parameterDisplayName)))))));
986
1009
  };
987
1010
 
988
- const FormDataBody = ({ specification, values, onChangeValues }) => {
1011
+ const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
989
1012
  const schema = specification.schema;
990
1013
  const parameters = schema === null || schema === void 0 ? void 0 : schema.properties;
991
1014
  const required = schema === null || schema === void 0 ? void 0 : schema.required;
@@ -1000,6 +1023,7 @@ const FormDataBody = ({ specification, values, onChangeValues }) => {
1000
1023
  return (React.createElement(Panel, { defaultIsOpen: true },
1001
1024
  React.createElement(Panel.Titlebar, null, "Body"),
1002
1025
  React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, mapSchemaPropertiesToParameters(parameters, required).map(parameter => {
1026
+ var _a;
1003
1027
  const supportsFileUpload = parameterSupportsFileUpload(parameter);
1004
1028
  const value = values[parameter.name];
1005
1029
  if (supportsFileUpload) {
@@ -1007,7 +1031,7 @@ const FormDataBody = ({ specification, values, onChangeValues }) => {
1007
1031
  ? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
1008
1032
  : onChangeValues(omit(values, parameter.name)) }));
1009
1033
  }
1010
- return (React.createElement(ParameterEditor, { key: parameter.name, parameter: parameter, value: typeof value === 'string' ? value : undefined, onChange: (value) => onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: typeof value === 'number' ? String(value) : value })) }));
1034
+ return (React.createElement(ParameterEditor, { key: parameter.name, parameter: parameter, value: typeof value === 'string' ? value : undefined, onChange: (value) => onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: typeof value === 'number' ? String(value) : value })), onChangeOptional: value => onChangeParameterAllow(Object.assign(Object.assign({}, isAllowedEmptyValues), { [parameter.name]: value })), canChangeOptional: true, isOptional: (_a = isAllowedEmptyValues[parameter.name]) !== null && _a !== void 0 ? _a : false }));
1011
1035
  }))));
1012
1036
  };
1013
1037
 
@@ -1081,6 +1105,7 @@ const useBodyParameterState = (mediaTypeContent) => {
1081
1105
  return initialParameterValues(parameters);
1082
1106
  }, [isFormDataBody, mediaTypeContent]);
1083
1107
  const [bodyParameterValues, setBodyParameterValues] = React.useState(initialState);
1108
+ const [isAllowedEmptyValue, setAllowedEmptyValue] = React.useState({});
1084
1109
  React.useEffect(() => {
1085
1110
  setBodyParameterValues(initialState);
1086
1111
  }, [initialState]);
@@ -1088,6 +1113,8 @@ const useBodyParameterState = (mediaTypeContent) => {
1088
1113
  return [
1089
1114
  bodyParameterValues,
1090
1115
  setBodyParameterValues,
1116
+ isAllowedEmptyValue,
1117
+ setAllowedEmptyValue,
1091
1118
  { isFormDataBody: true, bodySpecification: mediaTypeContent },
1092
1119
  ];
1093
1120
  }
@@ -1095,6 +1122,8 @@ const useBodyParameterState = (mediaTypeContent) => {
1095
1122
  return [
1096
1123
  bodyParameterValues,
1097
1124
  setBodyParameterValues,
1125
+ isAllowedEmptyValue,
1126
+ setAllowedEmptyValue,
1098
1127
  { isFormDataBody: false, bodySpecification: undefined },
1099
1128
  ];
1100
1129
  }
@@ -1231,14 +1260,14 @@ function buildFetchRequest({ httpOperation, mediaTypeContent, bodyInput, paramet
1231
1260
  .filter(({ value }) => value.length > 0);
1232
1261
  const [queryParamsWithAuth, headersWithAuth] = runAuthRequestEhancements(auth, queryParams, rawHeaders);
1233
1262
  const expandedPath = uriExpand(httpOperation.path, parameterValues);
1234
- const url = new URL(URI(serverUrl).segment(expandedPath).toString());
1235
- url.search = new URLSearchParams(queryParamsWithAuth.map(nameAndValueObjectToPair)).toString();
1263
+ const urlObject = new URL(serverUrl + expandedPath);
1264
+ urlObject.search = new URLSearchParams(queryParamsWithAuth.map(nameAndValueObjectToPair)).toString();
1236
1265
  const body = typeof bodyInput === 'object' ? yield createRequestBody(mediaTypeContent, bodyInput) : bodyInput;
1237
1266
  const headers = Object.assign(Object.assign(Object.assign({}, ((mediaTypeContent === null || mediaTypeContent === void 0 ? void 0 : mediaTypeContent.mediaType) !== 'multipart/form-data' && {
1238
1267
  'Content-Type': (_f = mediaTypeContent === null || mediaTypeContent === void 0 ? void 0 : mediaTypeContent.mediaType) !== null && _f !== void 0 ? _f : 'application/json',
1239
1268
  })), Object.fromEntries(headersWithAuth.map(nameAndValueObjectToPair))), mockData === null || mockData === void 0 ? void 0 : mockData.header);
1240
1269
  return [
1241
- url.toString(),
1270
+ urlObject.href,
1242
1271
  {
1243
1272
  credentials,
1244
1273
  method: httpOperation.method.toUpperCase(),
@@ -1306,7 +1335,8 @@ function buildHarRequest({ httpOperation, bodyInput, parameterValues, mediaTypeC
1306
1335
  headerParams.push({ name: 'Prefer', value: mockData.header.Prefer });
1307
1336
  }
1308
1337
  const [queryParamsWithAuth, headerParamsWithAuth] = runAuthRequestEhancements(auth, queryParams, headerParams);
1309
- const extendedPath = uriExpand(httpOperation.path, parameterValues);
1338
+ const expandedPath = uriExpand(httpOperation.path, parameterValues);
1339
+ const urlObject = new URL(serverUrl + expandedPath);
1310
1340
  let postData = undefined;
1311
1341
  if (shouldIncludeBody && typeof bodyInput === 'string') {
1312
1342
  postData = { mimeType, text: bodyInput };
@@ -1331,7 +1361,7 @@ function buildHarRequest({ httpOperation, bodyInput, parameterValues, mediaTypeC
1331
1361
  }
1332
1362
  return {
1333
1363
  method: httpOperation.method.toUpperCase(),
1334
- url: URI(serverUrl).segment(extendedPath).toString(),
1364
+ url: urlObject.href,
1335
1365
  httpVersion: 'HTTP/1.1',
1336
1366
  cookies: [],
1337
1367
  headers: [{ name: 'Content-Type', value: mimeType }, ...headerParamsWithAuth],
@@ -1465,7 +1495,7 @@ const useMockingOptions = () => useAtom(mockingOptionsAtom);
1465
1495
  const OperationParameters = ({ parameters, values, onChangeValue, validate, }) => {
1466
1496
  return (React.createElement(Panel, { defaultIsOpen: true },
1467
1497
  React.createElement(Panel.Titlebar, null, "Parameters"),
1468
- React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, parameters.map(parameter => (React.createElement(ParameterEditor, { key: parameter.name, parameter: parameter, value: values[parameter.name], onChange: (value) => onChangeValue(parameter.name, String(value)), validate: validate }))))));
1498
+ React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, parameters.map(parameter => (React.createElement(ParameterEditor, { key: parameter.name, parameter: parameter, value: values[parameter.name], onChange: (value) => onChangeValue(parameter.name, String(value)), validate: validate, isOptional: false, canChangeOptional: false, onChangeOptional: () => { } }))))));
1469
1499
  };
1470
1500
 
1471
1501
  const persistedParameterValuesAtom = atom({});
@@ -1577,7 +1607,7 @@ const ResponseError = ({ state: { error } }) => (React.createElement(Panel, { de
1577
1607
  React.createElement(Panel.Content, null, isNetworkError(error) ? React.createElement(NetworkErrorMessage, null) : React.createElement("p", null, error.message))));
1578
1608
  const NetworkErrorMessage = () => (React.createElement(React.Fragment, null,
1579
1609
  React.createElement("p", { className: "sl-pb-2" },
1580
- React.createElement("strong", null, "Network Error occured.")),
1610
+ React.createElement("strong", null, "Network Error occurred.")),
1581
1611
  React.createElement("p", { className: "sl-pb-2" }, "1. Double check that your computer is connected to the internet."),
1582
1612
  React.createElement("p", { className: "sl-pb-2" }, "2. Make sure the API is actually running and available under the specified URL."),
1583
1613
  React.createElement("p", null,
@@ -1617,6 +1647,7 @@ ServersDropdown.displayName = 'ServersDropdown';
1617
1647
  const defaultServers = [];
1618
1648
  const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embeddedInMd = false, tryItCredentialsPolicy, corsProxy, }) => {
1619
1649
  var _a, _b, _c, _d, _e, _f, _g;
1650
+ TryIt.displayName = 'TryIt';
1620
1651
  const isDark = useThemeIsDark();
1621
1652
  const [response, setResponse] = React.useState();
1622
1653
  const [requestData, setRequestData] = React.useState();
@@ -1625,7 +1656,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1625
1656
  const mediaTypeContent = (_c = (_b = (_a = httpOperation.request) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.contents) === null || _c === void 0 ? void 0 : _c[requestBodyIndex !== null && requestBodyIndex !== void 0 ? requestBodyIndex : 0];
1626
1657
  const { allParameters, updateParameterValue, parameterValuesWithDefaults } = useRequestParameters(httpOperation);
1627
1658
  const [mockingOptions, setMockingOptions] = useMockingOptions();
1628
- const [bodyParameterValues, setBodyParameterValues, formDataState] = useBodyParameterState(mediaTypeContent);
1659
+ const [bodyParameterValues, setBodyParameterValues, isAllowedEmptyValues, setAllowedEmptyValues, formDataState] = useBodyParameterState(mediaTypeContent);
1629
1660
  const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
1630
1661
  const [operationAuthValue, setOperationAuthValue] = usePersistedSecuritySchemeWithValues();
1631
1662
  const servers = React.useMemo(() => {
@@ -1636,6 +1667,12 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1636
1667
  const [chosenServer, setChosenServer] = useAtom(chosenServerAtom);
1637
1668
  const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
1638
1669
  const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
1670
+ const getValues = () => Object.keys(bodyParameterValues)
1671
+ .filter(param => { var _a; return (_a = !isAllowedEmptyValues[param]) !== null && _a !== void 0 ? _a : true; })
1672
+ .reduce((previousValue, currentValue) => {
1673
+ previousValue[currentValue] = bodyParameterValues[currentValue];
1674
+ return previousValue;
1675
+ }, {});
1639
1676
  React.useEffect(() => {
1640
1677
  const currentUrl = chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url;
1641
1678
  const exists = currentUrl && servers.find(s => s.url === currentUrl);
@@ -1649,7 +1686,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1649
1686
  React.useEffect(() => {
1650
1687
  let isMounted = true;
1651
1688
  if (onRequestChange || embeddedInMd) {
1652
- buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
1689
+ buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
1653
1690
  corsProxy })).then(request => {
1654
1691
  if (isMounted) {
1655
1692
  if (onRequestChange) {
@@ -1669,6 +1706,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1669
1706
  parameterValuesWithDefaults,
1670
1707
  formDataState.isFormDataBody,
1671
1708
  bodyParameterValues,
1709
+ isAllowedEmptyValues,
1672
1710
  textRequestBody,
1673
1711
  operationAuthValue,
1674
1712
  mockingOptions,
@@ -1687,7 +1725,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1687
1725
  parameterValues: parameterValuesWithDefaults,
1688
1726
  httpOperation,
1689
1727
  mediaTypeContent,
1690
- bodyInput: formDataState.isFormDataBody ? bodyParameterValues : textRequestBody,
1728
+ bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody,
1691
1729
  mockData,
1692
1730
  auth: operationAuthValue,
1693
1731
  chosenServer,
@@ -1723,7 +1761,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
1723
1761
  const tryItPanelContents = (React.createElement(React.Fragment, null,
1724
1762
  ((_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,
1725
1763
  allParameters.length > 0 && (React.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
1726
- 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,
1764
+ formDataState.isFormDataBody ? (React.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues, onChangeParameterAllow: setAllowedEmptyValues, isAllowedEmptyValues: isAllowedEmptyValues })) : mediaTypeContent ? (React.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
1727
1765
  React.createElement(Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
1728
1766
  React.createElement(HStack, { alignItems: "center", spacing: 2 },
1729
1767
  React.createElement(Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
@@ -2376,29 +2414,34 @@ function parseHttpRequest(data) {
2376
2414
  id: '?http-operation-id?',
2377
2415
  method: data.method,
2378
2416
  path: uri.is('absolute') ? uri.path() : data.url,
2379
- servers: [{ url: uri.is('absolute') ? uri.origin() : data.baseUrl || '' }],
2417
+ servers: [{ id: `?http-server-${uri.href()}?`, url: uri.is('absolute') ? uri.origin() : data.baseUrl || '' }],
2380
2418
  request: Object.assign({ query: Object.entries(data.query || {}).map(([key, value]) => {
2381
2419
  const defaultVal = Array.isArray(value) ? value[0] : value;
2382
2420
  return {
2421
+ id: `?http-query-${key}-id?`,
2383
2422
  name: key,
2384
2423
  style: HttpParamStyles.Form,
2385
2424
  schema: { default: defaultVal },
2386
2425
  required: isHttpRequestParamRequired(defaultVal),
2387
2426
  };
2388
2427
  }), headers: Object.entries(data.headers || {}).map(([key, value]) => ({
2428
+ id: `?http-header-${key}-id?`,
2389
2429
  name: key,
2390
2430
  style: HttpParamStyles.Simple,
2391
2431
  schema: { default: value },
2392
2432
  required: isHttpRequestParamRequired(value),
2393
2433
  })), path: pathParam === null || pathParam === void 0 ? void 0 : pathParam.map(name => ({
2434
+ id: `?http-param-${name}-id?`,
2394
2435
  name,
2395
2436
  style: HttpParamStyles.Simple,
2396
2437
  required: true,
2397
2438
  })) }, (data.body
2398
2439
  ? {
2399
2440
  body: {
2441
+ id: '?http-request-body?',
2400
2442
  contents: [
2401
2443
  {
2444
+ id: '?http-request-body-media?',
2402
2445
  mediaType: 'application/json',
2403
2446
  schema: { default: data.body },
2404
2447
  },