@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.
- package/__fixtures__/operations/securedOperation.d.ts +2 -2
- package/components/Docs/HttpService/ServerInfo.d.ts +1 -1
- package/components/TryIt/Body/FormDataBody.d.ts +3 -1
- package/components/TryIt/Body/request-body-utils.d.ts +3 -2
- package/components/TryIt/Parameters/ParameterEditor.d.ts +3 -0
- package/components/TryIt/Parameters/parameter-utils.d.ts +4 -2
- package/components/TryIt/Servers/ServersDropdown.d.ts +1 -1
- package/components/TryIt/build-request.d.ts +2 -1
- package/components/TryIt/chosenServer.d.ts +1 -1
- package/core.css +10 -0
- package/index.esm.js +63 -20
- package/index.js +63 -20
- package/index.mjs +63 -20
- package/package.json +12 -10
- package/styles.min.css +1 -1
- package/utils/guards.d.ts +1 -1
- package/utils/http-spec/IServer.d.ts +3 -2
package/index.js
CHANGED
|
@@ -195,9 +195,9 @@ function isHttpService(maybeHttpService) {
|
|
|
195
195
|
function isHttpOperation(maybeHttpOperation) {
|
|
196
196
|
return isStoplightNode(maybeHttpOperation) && 'method' in maybeHttpOperation && 'path' in maybeHttpOperation;
|
|
197
197
|
}
|
|
198
|
+
const properUrl = new RegExp(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/);
|
|
198
199
|
function isProperUrl(url) {
|
|
199
|
-
|
|
200
|
-
return url.match(properUrl);
|
|
200
|
+
return properUrl.test(url);
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
function useParsedData(nodeType, data) {
|
|
@@ -212,6 +212,7 @@ const parserMap = {
|
|
|
212
212
|
[types.NodeType.Generic]: parseUnknown,
|
|
213
213
|
[types.NodeType.TableOfContents]: parseUnknown,
|
|
214
214
|
[types.NodeType.SpectralRuleset]: parseUnknown,
|
|
215
|
+
[types.NodeType.Styleguide]: parseUnknown,
|
|
215
216
|
[types.NodeType.Unknown]: parseUnknown,
|
|
216
217
|
};
|
|
217
218
|
function parseArticleData(rawData) {
|
|
@@ -289,6 +290,7 @@ const NodeTypeColors = {
|
|
|
289
290
|
unknown: '',
|
|
290
291
|
table_of_contents: '',
|
|
291
292
|
spectral_ruleset: '',
|
|
293
|
+
styleguide: '',
|
|
292
294
|
};
|
|
293
295
|
const NodeTypePrettyName = {
|
|
294
296
|
http_operation: 'Endpoint',
|
|
@@ -300,6 +302,7 @@ const NodeTypePrettyName = {
|
|
|
300
302
|
unknown: '',
|
|
301
303
|
table_of_contents: '',
|
|
302
304
|
spectral_ruleset: '',
|
|
305
|
+
styleguide: '',
|
|
303
306
|
};
|
|
304
307
|
const NodeTypeIconDefs = {
|
|
305
308
|
http_operation: freeSolidSvgIcons.faCrosshairs,
|
|
@@ -311,6 +314,7 @@ const NodeTypeIconDefs = {
|
|
|
311
314
|
generic: freeSolidSvgIcons.faQuestionCircle,
|
|
312
315
|
table_of_contents: freeSolidSvgIcons.faQuestionCircle,
|
|
313
316
|
spectral_ruleset: freeSolidSvgIcons.faQuestionCircle,
|
|
317
|
+
styleguide: freeSolidSvgIcons.faQuestionCircle,
|
|
314
318
|
};
|
|
315
319
|
const HttpMethodColors = {
|
|
316
320
|
get: 'success',
|
|
@@ -411,13 +415,16 @@ function createNamedContext(name, defaultValue) {
|
|
|
411
415
|
|
|
412
416
|
const chosenServerAtom = jotai.atom(undefined);
|
|
413
417
|
|
|
418
|
+
function isValidServer(server) {
|
|
419
|
+
return server.url !== null && isProperUrl(server.url);
|
|
420
|
+
}
|
|
414
421
|
const getServersToDisplay = (originalServers, mockUrl) => {
|
|
415
422
|
const servers = originalServers
|
|
416
423
|
.map((server, i) => {
|
|
417
424
|
const fallbackDescription = originalServers.length === 1 ? 'Live Server' : `Server ${i + 1}`;
|
|
418
425
|
return Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || fallbackDescription });
|
|
419
426
|
})
|
|
420
|
-
.filter(
|
|
427
|
+
.filter(isValidServer);
|
|
421
428
|
if (mockUrl) {
|
|
422
429
|
servers.push({
|
|
423
430
|
description: 'Mock Server',
|
|
@@ -433,7 +440,13 @@ const getServerUrlWithDefaultValues = (server) => {
|
|
|
433
440
|
variables.forEach(([variableName, variableInfo]) => {
|
|
434
441
|
urlString = urlString.replace(`{${variableName}}`, variableInfo.default);
|
|
435
442
|
});
|
|
436
|
-
let url
|
|
443
|
+
let url;
|
|
444
|
+
try {
|
|
445
|
+
url = URI__default["default"](urlString);
|
|
446
|
+
}
|
|
447
|
+
catch (_b) {
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
437
450
|
if (url.is('relative') && typeof window !== 'undefined') {
|
|
438
451
|
url = url.absoluteTo(window.location.origin);
|
|
439
452
|
}
|
|
@@ -1023,9 +1036,10 @@ function mapSchemaPropertiesToParameters(properties, required) {
|
|
|
1023
1036
|
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 }))));
|
|
1024
1037
|
}
|
|
1025
1038
|
|
|
1026
|
-
const ParameterEditor = ({ parameter, value, onChange, validate }) => {
|
|
1039
|
+
const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
|
|
1027
1040
|
var _a, _b;
|
|
1028
1041
|
const inputId = useUniqueId(`id_${parameter.name}_`);
|
|
1042
|
+
const inputCheckId = useUniqueId(`id_${parameter.name}_checked`);
|
|
1029
1043
|
const parameterValueOptions = parameterOptions(parameter);
|
|
1030
1044
|
const examples = exampleOptions(parameter);
|
|
1031
1045
|
const selectedExample = (_a = examples === null || examples === void 0 ? void 0 : examples.find(e => e.value === value)) !== null && _a !== void 0 ? _a : selectExampleOption;
|
|
@@ -1036,10 +1050,19 @@ const ParameterEditor = ({ parameter, value, onChange, validate }) => {
|
|
|
1036
1050
|
React__namespace.createElement(mosaic.Text, { mx: 3 }, ":"),
|
|
1037
1051
|
React__namespace.createElement("div", null, parameterValueOptions ? (React__namespace.createElement(mosaic.Select, { flex: 1, "aria-label": parameter.name, options: parameterValueOptions, value: value || '', onChange: onChange })) : (React__namespace.createElement(mosaic.Flex, { flex: 1 },
|
|
1038
1052
|
React__namespace.createElement(mosaic.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) }),
|
|
1039
|
-
examples && (React__namespace.createElement(mosaic.Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange })))))
|
|
1053
|
+
examples && (React__namespace.createElement(mosaic.Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange }))))),
|
|
1054
|
+
canChangeOptional && !parameter.required && (React__namespace.createElement(React__namespace.Fragment, null,
|
|
1055
|
+
React__namespace.createElement("div", null),
|
|
1056
|
+
React__namespace.createElement("div", null),
|
|
1057
|
+
React__namespace.createElement("div", null,
|
|
1058
|
+
React__namespace.createElement(mosaic.Flex, { flex: 1 },
|
|
1059
|
+
React__namespace.createElement(mosaic.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) }),
|
|
1060
|
+
React__namespace.createElement(mosaic.Text, { className: "TextForCheckBox", flex: 1, as: "label", "aria-hidden": "true", "data-testid": "param-check", htmlFor: inputCheckId, fontSize: "base" },
|
|
1061
|
+
"Omit ",
|
|
1062
|
+
parameterDisplayName)))))));
|
|
1040
1063
|
};
|
|
1041
1064
|
|
|
1042
|
-
const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
1065
|
+
const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
|
|
1043
1066
|
const schema = specification.schema;
|
|
1044
1067
|
const parameters = schema === null || schema === void 0 ? void 0 : schema.properties;
|
|
1045
1068
|
const required = schema === null || schema === void 0 ? void 0 : schema.required;
|
|
@@ -1054,6 +1077,7 @@ const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
|
1054
1077
|
return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
|
|
1055
1078
|
React__namespace.createElement(mosaic.Panel.Titlebar, null, "Body"),
|
|
1056
1079
|
React__namespace.createElement(mosaic.Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, mapSchemaPropertiesToParameters(parameters, required).map(parameter => {
|
|
1080
|
+
var _a;
|
|
1057
1081
|
const supportsFileUpload = parameterSupportsFileUpload(parameter);
|
|
1058
1082
|
const value = values[parameter.name];
|
|
1059
1083
|
if (supportsFileUpload) {
|
|
@@ -1061,7 +1085,7 @@ const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
|
1061
1085
|
? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
|
|
1062
1086
|
: onChangeValues(omit__default["default"](values, parameter.name)) }));
|
|
1063
1087
|
}
|
|
1064
|
-
return (React__namespace.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 })) }));
|
|
1088
|
+
return (React__namespace.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 }));
|
|
1065
1089
|
}))));
|
|
1066
1090
|
};
|
|
1067
1091
|
|
|
@@ -1135,6 +1159,7 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1135
1159
|
return initialParameterValues(parameters);
|
|
1136
1160
|
}, [isFormDataBody, mediaTypeContent]);
|
|
1137
1161
|
const [bodyParameterValues, setBodyParameterValues] = React__namespace.useState(initialState);
|
|
1162
|
+
const [isAllowedEmptyValue, setAllowedEmptyValue] = React__namespace.useState({});
|
|
1138
1163
|
React__namespace.useEffect(() => {
|
|
1139
1164
|
setBodyParameterValues(initialState);
|
|
1140
1165
|
}, [initialState]);
|
|
@@ -1142,6 +1167,8 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1142
1167
|
return [
|
|
1143
1168
|
bodyParameterValues,
|
|
1144
1169
|
setBodyParameterValues,
|
|
1170
|
+
isAllowedEmptyValue,
|
|
1171
|
+
setAllowedEmptyValue,
|
|
1145
1172
|
{ isFormDataBody: true, bodySpecification: mediaTypeContent },
|
|
1146
1173
|
];
|
|
1147
1174
|
}
|
|
@@ -1149,6 +1176,8 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1149
1176
|
return [
|
|
1150
1177
|
bodyParameterValues,
|
|
1151
1178
|
setBodyParameterValues,
|
|
1179
|
+
isAllowedEmptyValue,
|
|
1180
|
+
setAllowedEmptyValue,
|
|
1152
1181
|
{ isFormDataBody: false, bodySpecification: undefined },
|
|
1153
1182
|
];
|
|
1154
1183
|
}
|
|
@@ -1285,14 +1314,14 @@ function buildFetchRequest({ httpOperation, mediaTypeContent, bodyInput, paramet
|
|
|
1285
1314
|
.filter(({ value }) => value.length > 0);
|
|
1286
1315
|
const [queryParamsWithAuth, headersWithAuth] = runAuthRequestEhancements(auth, queryParams, rawHeaders);
|
|
1287
1316
|
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1317
|
+
const urlObject = new URL(serverUrl + expandedPath);
|
|
1318
|
+
urlObject.search = new URLSearchParams(queryParamsWithAuth.map(nameAndValueObjectToPair)).toString();
|
|
1290
1319
|
const body = typeof bodyInput === 'object' ? yield createRequestBody(mediaTypeContent, bodyInput) : bodyInput;
|
|
1291
1320
|
const headers = Object.assign(Object.assign(Object.assign({}, ((mediaTypeContent === null || mediaTypeContent === void 0 ? void 0 : mediaTypeContent.mediaType) !== 'multipart/form-data' && {
|
|
1292
1321
|
'Content-Type': (_f = mediaTypeContent === null || mediaTypeContent === void 0 ? void 0 : mediaTypeContent.mediaType) !== null && _f !== void 0 ? _f : 'application/json',
|
|
1293
1322
|
})), Object.fromEntries(headersWithAuth.map(nameAndValueObjectToPair))), mockData === null || mockData === void 0 ? void 0 : mockData.header);
|
|
1294
1323
|
return [
|
|
1295
|
-
|
|
1324
|
+
urlObject.href,
|
|
1296
1325
|
{
|
|
1297
1326
|
credentials,
|
|
1298
1327
|
method: httpOperation.method.toUpperCase(),
|
|
@@ -1360,7 +1389,8 @@ function buildHarRequest({ httpOperation, bodyInput, parameterValues, mediaTypeC
|
|
|
1360
1389
|
headerParams.push({ name: 'Prefer', value: mockData.header.Prefer });
|
|
1361
1390
|
}
|
|
1362
1391
|
const [queryParamsWithAuth, headerParamsWithAuth] = runAuthRequestEhancements(auth, queryParams, headerParams);
|
|
1363
|
-
const
|
|
1392
|
+
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1393
|
+
const urlObject = new URL(serverUrl + expandedPath);
|
|
1364
1394
|
let postData = undefined;
|
|
1365
1395
|
if (shouldIncludeBody && typeof bodyInput === 'string') {
|
|
1366
1396
|
postData = { mimeType, text: bodyInput };
|
|
@@ -1385,7 +1415,7 @@ function buildHarRequest({ httpOperation, bodyInput, parameterValues, mediaTypeC
|
|
|
1385
1415
|
}
|
|
1386
1416
|
return {
|
|
1387
1417
|
method: httpOperation.method.toUpperCase(),
|
|
1388
|
-
url:
|
|
1418
|
+
url: urlObject.href,
|
|
1389
1419
|
httpVersion: 'HTTP/1.1',
|
|
1390
1420
|
cookies: [],
|
|
1391
1421
|
headers: [{ name: 'Content-Type', value: mimeType }, ...headerParamsWithAuth],
|
|
@@ -1519,7 +1549,7 @@ const useMockingOptions = () => jotai.useAtom(mockingOptionsAtom);
|
|
|
1519
1549
|
const OperationParameters = ({ parameters, values, onChangeValue, validate, }) => {
|
|
1520
1550
|
return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
|
|
1521
1551
|
React__namespace.createElement(mosaic.Panel.Titlebar, null, "Parameters"),
|
|
1522
|
-
React__namespace.createElement(mosaic.Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, parameters.map(parameter => (React__namespace.createElement(ParameterEditor, { key: parameter.name, parameter: parameter, value: values[parameter.name], onChange: (value) => onChangeValue(parameter.name, String(value)), validate: validate }))))));
|
|
1552
|
+
React__namespace.createElement(mosaic.Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, parameters.map(parameter => (React__namespace.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: () => { } }))))));
|
|
1523
1553
|
};
|
|
1524
1554
|
|
|
1525
1555
|
const persistedParameterValuesAtom = jotai.atom({});
|
|
@@ -1631,7 +1661,7 @@ const ResponseError = ({ state: { error } }) => (React__namespace.createElement(
|
|
|
1631
1661
|
React__namespace.createElement(mosaic.Panel.Content, null, isNetworkError(error) ? React__namespace.createElement(NetworkErrorMessage, null) : React__namespace.createElement("p", null, error.message))));
|
|
1632
1662
|
const NetworkErrorMessage = () => (React__namespace.createElement(React__namespace.Fragment, null,
|
|
1633
1663
|
React__namespace.createElement("p", { className: "sl-pb-2" },
|
|
1634
|
-
React__namespace.createElement("strong", null, "Network Error
|
|
1664
|
+
React__namespace.createElement("strong", null, "Network Error occurred.")),
|
|
1635
1665
|
React__namespace.createElement("p", { className: "sl-pb-2" }, "1. Double check that your computer is connected to the internet."),
|
|
1636
1666
|
React__namespace.createElement("p", { className: "sl-pb-2" }, "2. Make sure the API is actually running and available under the specified URL."),
|
|
1637
1667
|
React__namespace.createElement("p", null,
|
|
@@ -1671,6 +1701,7 @@ ServersDropdown.displayName = 'ServersDropdown';
|
|
|
1671
1701
|
const defaultServers = [];
|
|
1672
1702
|
const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embeddedInMd = false, tryItCredentialsPolicy, corsProxy, }) => {
|
|
1673
1703
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1704
|
+
TryIt.displayName = 'TryIt';
|
|
1674
1705
|
const isDark = mosaic.useThemeIsDark();
|
|
1675
1706
|
const [response, setResponse] = React__namespace.useState();
|
|
1676
1707
|
const [requestData, setRequestData] = React__namespace.useState();
|
|
@@ -1679,7 +1710,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1679
1710
|
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];
|
|
1680
1711
|
const { allParameters, updateParameterValue, parameterValuesWithDefaults } = useRequestParameters(httpOperation);
|
|
1681
1712
|
const [mockingOptions, setMockingOptions] = useMockingOptions();
|
|
1682
|
-
const [bodyParameterValues, setBodyParameterValues, formDataState] = useBodyParameterState(mediaTypeContent);
|
|
1713
|
+
const [bodyParameterValues, setBodyParameterValues, isAllowedEmptyValues, setAllowedEmptyValues, formDataState] = useBodyParameterState(mediaTypeContent);
|
|
1683
1714
|
const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
|
|
1684
1715
|
const [operationAuthValue, setOperationAuthValue] = usePersistedSecuritySchemeWithValues();
|
|
1685
1716
|
const servers = React__namespace.useMemo(() => {
|
|
@@ -1690,6 +1721,12 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1690
1721
|
const [chosenServer, setChosenServer] = jotai.useAtom(chosenServerAtom);
|
|
1691
1722
|
const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
|
|
1692
1723
|
const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
|
|
1724
|
+
const getValues = () => Object.keys(bodyParameterValues)
|
|
1725
|
+
.filter(param => { var _a; return (_a = !isAllowedEmptyValues[param]) !== null && _a !== void 0 ? _a : true; })
|
|
1726
|
+
.reduce((previousValue, currentValue) => {
|
|
1727
|
+
previousValue[currentValue] = bodyParameterValues[currentValue];
|
|
1728
|
+
return previousValue;
|
|
1729
|
+
}, {});
|
|
1693
1730
|
React__namespace.useEffect(() => {
|
|
1694
1731
|
const currentUrl = chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url;
|
|
1695
1732
|
const exists = currentUrl && servers.find(s => s.url === currentUrl);
|
|
@@ -1703,7 +1740,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1703
1740
|
React__namespace.useEffect(() => {
|
|
1704
1741
|
let isMounted = true;
|
|
1705
1742
|
if (onRequestChange || embeddedInMd) {
|
|
1706
|
-
buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ?
|
|
1743
|
+
buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
|
|
1707
1744
|
corsProxy })).then(request => {
|
|
1708
1745
|
if (isMounted) {
|
|
1709
1746
|
if (onRequestChange) {
|
|
@@ -1723,6 +1760,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1723
1760
|
parameterValuesWithDefaults,
|
|
1724
1761
|
formDataState.isFormDataBody,
|
|
1725
1762
|
bodyParameterValues,
|
|
1763
|
+
isAllowedEmptyValues,
|
|
1726
1764
|
textRequestBody,
|
|
1727
1765
|
operationAuthValue,
|
|
1728
1766
|
mockingOptions,
|
|
@@ -1741,7 +1779,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1741
1779
|
parameterValues: parameterValuesWithDefaults,
|
|
1742
1780
|
httpOperation,
|
|
1743
1781
|
mediaTypeContent,
|
|
1744
|
-
bodyInput: formDataState.isFormDataBody ?
|
|
1782
|
+
bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody,
|
|
1745
1783
|
mockData,
|
|
1746
1784
|
auth: operationAuthValue,
|
|
1747
1785
|
chosenServer,
|
|
@@ -1777,7 +1815,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1777
1815
|
const tryItPanelContents = (React__namespace.createElement(React__namespace.Fragment, null,
|
|
1778
1816
|
((_e = httpOperation.security) === null || _e === void 0 ? void 0 : _e.length) ? (React__namespace.createElement(TryItAuth, { onChange: setOperationAuthValue, operationSecurityScheme: (_f = httpOperation.security) !== null && _f !== void 0 ? _f : [], value: operationAuthValue })) : null,
|
|
1779
1817
|
allParameters.length > 0 && (React__namespace.createElement(OperationParameters, { parameters: allParameters, values: parameterValuesWithDefaults, onChangeValue: updateParameterValue, validate: validateParameters })),
|
|
1780
|
-
formDataState.isFormDataBody ? (React__namespace.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues })) : mediaTypeContent ? (React__namespace.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
|
|
1818
|
+
formDataState.isFormDataBody ? (React__namespace.createElement(FormDataBody, { specification: formDataState.bodySpecification, values: bodyParameterValues, onChangeValues: setBodyParameterValues, onChangeParameterAllow: setAllowedEmptyValues, isAllowedEmptyValues: isAllowedEmptyValues })) : mediaTypeContent ? (React__namespace.createElement(RequestBody, { examples: (_g = mediaTypeContent.examples) !== null && _g !== void 0 ? _g : [], requestBody: textRequestBody, onChange: setTextRequestBody })) : null,
|
|
1781
1819
|
React__namespace.createElement(mosaic.Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
|
|
1782
1820
|
React__namespace.createElement(mosaic.HStack, { alignItems: "center", spacing: 2 },
|
|
1783
1821
|
React__namespace.createElement(mosaic.Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
|
|
@@ -2430,29 +2468,34 @@ function parseHttpRequest(data) {
|
|
|
2430
2468
|
id: '?http-operation-id?',
|
|
2431
2469
|
method: data.method,
|
|
2432
2470
|
path: uri.is('absolute') ? uri.path() : data.url,
|
|
2433
|
-
servers: [{ url: uri.is('absolute') ? uri.origin() : data.baseUrl || '' }],
|
|
2471
|
+
servers: [{ id: `?http-server-${uri.href()}?`, url: uri.is('absolute') ? uri.origin() : data.baseUrl || '' }],
|
|
2434
2472
|
request: Object.assign({ query: Object.entries(data.query || {}).map(([key, value]) => {
|
|
2435
2473
|
const defaultVal = Array.isArray(value) ? value[0] : value;
|
|
2436
2474
|
return {
|
|
2475
|
+
id: `?http-query-${key}-id?`,
|
|
2437
2476
|
name: key,
|
|
2438
2477
|
style: types.HttpParamStyles.Form,
|
|
2439
2478
|
schema: { default: defaultVal },
|
|
2440
2479
|
required: isHttpRequestParamRequired(defaultVal),
|
|
2441
2480
|
};
|
|
2442
2481
|
}), headers: Object.entries(data.headers || {}).map(([key, value]) => ({
|
|
2482
|
+
id: `?http-header-${key}-id?`,
|
|
2443
2483
|
name: key,
|
|
2444
2484
|
style: types.HttpParamStyles.Simple,
|
|
2445
2485
|
schema: { default: value },
|
|
2446
2486
|
required: isHttpRequestParamRequired(value),
|
|
2447
2487
|
})), path: pathParam === null || pathParam === void 0 ? void 0 : pathParam.map(name => ({
|
|
2488
|
+
id: `?http-param-${name}-id?`,
|
|
2448
2489
|
name,
|
|
2449
2490
|
style: types.HttpParamStyles.Simple,
|
|
2450
2491
|
required: true,
|
|
2451
2492
|
})) }, (data.body
|
|
2452
2493
|
? {
|
|
2453
2494
|
body: {
|
|
2495
|
+
id: '?http-request-body?',
|
|
2454
2496
|
contents: [
|
|
2455
2497
|
{
|
|
2498
|
+
id: '?http-request-body-media?',
|
|
2456
2499
|
mediaType: 'application/json',
|
|
2457
2500
|
schema: { default: data.body },
|
|
2458
2501
|
},
|
package/index.mjs
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
|
-
|
|
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(
|
|
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
|
|
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
|
|
1235
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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
|
|
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 ?
|
|
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 ?
|
|
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
|
},
|