@stoplight/elements-core 7.5.9 → 7.5.13
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/components/Docs/story-helper.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/core.css +87 -0
- package/index.esm.js +55 -21
- package/index.js +55 -21
- package/index.mjs +55 -21
- package/package.json +5 -5
- package/styles.min.css +1 -1
- package/utils/guards.d.ts +1 -1
- package/utils/http-spec/IServer.d.ts +1 -1
|
@@ -5,5 +5,5 @@ interface HelperReturn<P> {
|
|
|
5
5
|
createStory(name: string, input: Partial<P>): Story<P>;
|
|
6
6
|
createHoistedStory(input: Partial<P>): Story<P>;
|
|
7
7
|
}
|
|
8
|
-
export declare const createStoriesForDocsComponent: <P>(Component: React.ComponentType<P
|
|
8
|
+
export declare const createStoriesForDocsComponent: <P>(Component: React.ComponentType<P>, title?: string | undefined) => HelperReturn<P>;
|
|
9
9
|
export {};
|
|
@@ -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>;
|
package/core.css
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
.sl-elements {
|
|
2
|
+
font-size: 13px;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.sl-elements .svg-inline--fa {
|
|
6
|
+
display: inline-block;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/* Docs */
|
|
10
|
+
|
|
11
|
+
.sl-elements .DocsSkeleton {
|
|
12
|
+
animation: 500ms linear infinite alternate skeleton-glow;
|
|
13
|
+
background: rgba(206, 217, 224, 0.2);
|
|
14
|
+
background-clip: padding-box !important;
|
|
15
|
+
border-color: rgba(206, 217, 224, 0.2) !important;
|
|
16
|
+
border-radius: 2px;
|
|
17
|
+
box-shadow: none !important;
|
|
18
|
+
color: transparent !important;
|
|
19
|
+
cursor: default;
|
|
20
|
+
pointer-events: none;
|
|
21
|
+
user-select: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.sl-elements .Model {
|
|
25
|
+
--fs-code: 12px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Table of Contents */
|
|
29
|
+
|
|
30
|
+
.sl-elements .ElementsTableOfContentsItem:hover {
|
|
31
|
+
text-decoration: none;
|
|
32
|
+
color: inherit;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* TryIt */
|
|
36
|
+
|
|
37
|
+
.sl-elements .ParameterGrid {
|
|
38
|
+
display: grid;
|
|
39
|
+
grid-template-columns: fit-content(120px) 20px auto;
|
|
40
|
+
row-gap: 3px;
|
|
41
|
+
align-items: center;
|
|
42
|
+
padding-bottom: 0;
|
|
43
|
+
margin-bottom: 16px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sl-elements .TryItPanel > :nth-child(2) {
|
|
47
|
+
/* This, along with the padding:0 margin: 16s above causes margin collapse to guarantee correct spacing around the panels & send button */
|
|
48
|
+
overflow: auto;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.sl-elements .OperationParametersContent {
|
|
52
|
+
max-height: 162px; /* 4.5 lines plus padding */
|
|
53
|
+
}
|
|
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
|
+
|
|
65
|
+
.sl-elements .TextRequestBody {
|
|
66
|
+
max-height: 200px;
|
|
67
|
+
overflow-y: auto;
|
|
68
|
+
padding-bottom: 0;
|
|
69
|
+
margin-bottom: 16px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* HttpOperation */
|
|
73
|
+
|
|
74
|
+
.sl-elements .HttpOperation .JsonSchemaViewer .sl-markdown-viewer p {
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
line-height: 1.5em;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.sl-elements .HttpOperation__Parameters .sl-markdown-viewer p {
|
|
80
|
+
font-size: 12px;
|
|
81
|
+
line-height: 1.5em;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.sl-elements .Model .JsonSchemaViewer .sl-markdown-viewer p {
|
|
85
|
+
font-size: 12px;
|
|
86
|
+
line-height: 1.5em;
|
|
87
|
+
}
|
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
|
-
|
|
146
|
-
return url.match(properUrl);
|
|
146
|
+
return properUrl.test(url);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
function useParsedData(nodeType, data) {
|
|
@@ -357,13 +357,16 @@ function createNamedContext(name, defaultValue) {
|
|
|
357
357
|
|
|
358
358
|
const chosenServerAtom = atom(undefined);
|
|
359
359
|
|
|
360
|
+
function isValidServer(server) {
|
|
361
|
+
return server.url !== null && isProperUrl(server.url);
|
|
362
|
+
}
|
|
360
363
|
const getServersToDisplay = (originalServers, mockUrl) => {
|
|
361
364
|
const servers = originalServers
|
|
362
365
|
.map((server, i) => {
|
|
363
366
|
const fallbackDescription = originalServers.length === 1 ? 'Live Server' : `Server ${i + 1}`;
|
|
364
367
|
return Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || fallbackDescription });
|
|
365
368
|
})
|
|
366
|
-
.filter(
|
|
369
|
+
.filter(isValidServer);
|
|
367
370
|
if (mockUrl) {
|
|
368
371
|
servers.push({
|
|
369
372
|
description: 'Mock Server',
|
|
@@ -379,7 +382,13 @@ const getServerUrlWithDefaultValues = (server) => {
|
|
|
379
382
|
variables.forEach(([variableName, variableInfo]) => {
|
|
380
383
|
urlString = urlString.replace(`{${variableName}}`, variableInfo.default);
|
|
381
384
|
});
|
|
382
|
-
let url
|
|
385
|
+
let url;
|
|
386
|
+
try {
|
|
387
|
+
url = URI(urlString);
|
|
388
|
+
}
|
|
389
|
+
catch (_b) {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
383
392
|
if (url.is('relative') && typeof window !== 'undefined') {
|
|
384
393
|
url = url.absoluteTo(window.location.origin);
|
|
385
394
|
}
|
|
@@ -969,9 +978,10 @@ function mapSchemaPropertiesToParameters(properties, required) {
|
|
|
969
978
|
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
979
|
}
|
|
971
980
|
|
|
972
|
-
const ParameterEditor = ({ parameter, value, onChange, validate }) => {
|
|
981
|
+
const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
|
|
973
982
|
var _a, _b;
|
|
974
983
|
const inputId = useUniqueId(`id_${parameter.name}_`);
|
|
984
|
+
const inputCheckId = useUniqueId(`id_${parameter.name}_checked`);
|
|
975
985
|
const parameterValueOptions = parameterOptions(parameter);
|
|
976
986
|
const examples = exampleOptions(parameter);
|
|
977
987
|
const selectedExample = (_a = examples === null || examples === void 0 ? void 0 : examples.find(e => e.value === value)) !== null && _a !== void 0 ? _a : selectExampleOption;
|
|
@@ -982,10 +992,19 @@ const ParameterEditor = ({ parameter, value, onChange, validate }) => {
|
|
|
982
992
|
React.createElement(Text, { mx: 3 }, ":"),
|
|
983
993
|
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
994
|
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 })))))
|
|
995
|
+
examples && (React.createElement(Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange }))))),
|
|
996
|
+
canChangeOptional && !parameter.required && (React.createElement(React.Fragment, null,
|
|
997
|
+
React.createElement("div", null),
|
|
998
|
+
React.createElement("div", null),
|
|
999
|
+
React.createElement("div", null,
|
|
1000
|
+
React.createElement(Flex, { flex: 1 },
|
|
1001
|
+
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) }),
|
|
1002
|
+
React.createElement(Text, { className: "TextForCheckBox", flex: 1, as: "label", "aria-hidden": "true", "data-testid": "param-check", htmlFor: inputCheckId, fontSize: "base" },
|
|
1003
|
+
"Omit ",
|
|
1004
|
+
parameterDisplayName)))))));
|
|
986
1005
|
};
|
|
987
1006
|
|
|
988
|
-
const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
1007
|
+
const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
|
|
989
1008
|
const schema = specification.schema;
|
|
990
1009
|
const parameters = schema === null || schema === void 0 ? void 0 : schema.properties;
|
|
991
1010
|
const required = schema === null || schema === void 0 ? void 0 : schema.required;
|
|
@@ -1000,6 +1019,7 @@ const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
|
1000
1019
|
return (React.createElement(Panel, { defaultIsOpen: true },
|
|
1001
1020
|
React.createElement(Panel.Titlebar, null, "Body"),
|
|
1002
1021
|
React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, mapSchemaPropertiesToParameters(parameters, required).map(parameter => {
|
|
1022
|
+
var _a;
|
|
1003
1023
|
const supportsFileUpload = parameterSupportsFileUpload(parameter);
|
|
1004
1024
|
const value = values[parameter.name];
|
|
1005
1025
|
if (supportsFileUpload) {
|
|
@@ -1007,7 +1027,7 @@ const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
|
1007
1027
|
? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
|
|
1008
1028
|
: onChangeValues(omit(values, parameter.name)) }));
|
|
1009
1029
|
}
|
|
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 })) }));
|
|
1030
|
+
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
1031
|
}))));
|
|
1012
1032
|
};
|
|
1013
1033
|
|
|
@@ -1081,6 +1101,7 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1081
1101
|
return initialParameterValues(parameters);
|
|
1082
1102
|
}, [isFormDataBody, mediaTypeContent]);
|
|
1083
1103
|
const [bodyParameterValues, setBodyParameterValues] = React.useState(initialState);
|
|
1104
|
+
const [isAllowedEmptyValue, setAllowedEmptyValue] = React.useState({});
|
|
1084
1105
|
React.useEffect(() => {
|
|
1085
1106
|
setBodyParameterValues(initialState);
|
|
1086
1107
|
}, [initialState]);
|
|
@@ -1088,6 +1109,8 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1088
1109
|
return [
|
|
1089
1110
|
bodyParameterValues,
|
|
1090
1111
|
setBodyParameterValues,
|
|
1112
|
+
isAllowedEmptyValue,
|
|
1113
|
+
setAllowedEmptyValue,
|
|
1091
1114
|
{ isFormDataBody: true, bodySpecification: mediaTypeContent },
|
|
1092
1115
|
];
|
|
1093
1116
|
}
|
|
@@ -1095,6 +1118,8 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1095
1118
|
return [
|
|
1096
1119
|
bodyParameterValues,
|
|
1097
1120
|
setBodyParameterValues,
|
|
1121
|
+
isAllowedEmptyValue,
|
|
1122
|
+
setAllowedEmptyValue,
|
|
1098
1123
|
{ isFormDataBody: false, bodySpecification: undefined },
|
|
1099
1124
|
];
|
|
1100
1125
|
}
|
|
@@ -1231,14 +1256,14 @@ function buildFetchRequest({ httpOperation, mediaTypeContent, bodyInput, paramet
|
|
|
1231
1256
|
.filter(({ value }) => value.length > 0);
|
|
1232
1257
|
const [queryParamsWithAuth, headersWithAuth] = runAuthRequestEhancements(auth, queryParams, rawHeaders);
|
|
1233
1258
|
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1234
|
-
const
|
|
1235
|
-
|
|
1259
|
+
const urlObject = new URL(serverUrl + expandedPath);
|
|
1260
|
+
urlObject.search = new URLSearchParams(queryParamsWithAuth.map(nameAndValueObjectToPair)).toString();
|
|
1236
1261
|
const body = typeof bodyInput === 'object' ? yield createRequestBody(mediaTypeContent, bodyInput) : bodyInput;
|
|
1237
1262
|
const headers = Object.assign(Object.assign(Object.assign({}, ((mediaTypeContent === null || mediaTypeContent === void 0 ? void 0 : mediaTypeContent.mediaType) !== 'multipart/form-data' && {
|
|
1238
1263
|
'Content-Type': (_f = mediaTypeContent === null || mediaTypeContent === void 0 ? void 0 : mediaTypeContent.mediaType) !== null && _f !== void 0 ? _f : 'application/json',
|
|
1239
1264
|
})), Object.fromEntries(headersWithAuth.map(nameAndValueObjectToPair))), mockData === null || mockData === void 0 ? void 0 : mockData.header);
|
|
1240
1265
|
return [
|
|
1241
|
-
|
|
1266
|
+
urlObject.href,
|
|
1242
1267
|
{
|
|
1243
1268
|
credentials,
|
|
1244
1269
|
method: httpOperation.method.toUpperCase(),
|
|
@@ -1306,7 +1331,8 @@ function buildHarRequest({ httpOperation, bodyInput, parameterValues, mediaTypeC
|
|
|
1306
1331
|
headerParams.push({ name: 'Prefer', value: mockData.header.Prefer });
|
|
1307
1332
|
}
|
|
1308
1333
|
const [queryParamsWithAuth, headerParamsWithAuth] = runAuthRequestEhancements(auth, queryParams, headerParams);
|
|
1309
|
-
const
|
|
1334
|
+
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1335
|
+
const urlObject = new URL(serverUrl + expandedPath);
|
|
1310
1336
|
let postData = undefined;
|
|
1311
1337
|
if (shouldIncludeBody && typeof bodyInput === 'string') {
|
|
1312
1338
|
postData = { mimeType, text: bodyInput };
|
|
@@ -1331,7 +1357,7 @@ function buildHarRequest({ httpOperation, bodyInput, parameterValues, mediaTypeC
|
|
|
1331
1357
|
}
|
|
1332
1358
|
return {
|
|
1333
1359
|
method: httpOperation.method.toUpperCase(),
|
|
1334
|
-
url:
|
|
1360
|
+
url: urlObject.href,
|
|
1335
1361
|
httpVersion: 'HTTP/1.1',
|
|
1336
1362
|
cookies: [],
|
|
1337
1363
|
headers: [{ name: 'Content-Type', value: mimeType }, ...headerParamsWithAuth],
|
|
@@ -1465,7 +1491,7 @@ const useMockingOptions = () => useAtom(mockingOptionsAtom);
|
|
|
1465
1491
|
const OperationParameters = ({ parameters, values, onChangeValue, validate, }) => {
|
|
1466
1492
|
return (React.createElement(Panel, { defaultIsOpen: true },
|
|
1467
1493
|
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 }))))));
|
|
1494
|
+
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
1495
|
};
|
|
1470
1496
|
|
|
1471
1497
|
const persistedParameterValuesAtom = atom({});
|
|
@@ -1617,6 +1643,7 @@ ServersDropdown.displayName = 'ServersDropdown';
|
|
|
1617
1643
|
const defaultServers = [];
|
|
1618
1644
|
const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embeddedInMd = false, tryItCredentialsPolicy, corsProxy, }) => {
|
|
1619
1645
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1646
|
+
TryIt.displayName = 'TryIt';
|
|
1620
1647
|
const isDark = useThemeIsDark();
|
|
1621
1648
|
const [response, setResponse] = React.useState();
|
|
1622
1649
|
const [requestData, setRequestData] = React.useState();
|
|
@@ -1625,7 +1652,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1625
1652
|
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
1653
|
const { allParameters, updateParameterValue, parameterValuesWithDefaults } = useRequestParameters(httpOperation);
|
|
1627
1654
|
const [mockingOptions, setMockingOptions] = useMockingOptions();
|
|
1628
|
-
const [bodyParameterValues, setBodyParameterValues, formDataState] = useBodyParameterState(mediaTypeContent);
|
|
1655
|
+
const [bodyParameterValues, setBodyParameterValues, isAllowedEmptyValues, setAllowedEmptyValues, formDataState] = useBodyParameterState(mediaTypeContent);
|
|
1629
1656
|
const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
|
|
1630
1657
|
const [operationAuthValue, setOperationAuthValue] = usePersistedSecuritySchemeWithValues();
|
|
1631
1658
|
const servers = React.useMemo(() => {
|
|
@@ -1636,6 +1663,12 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1636
1663
|
const [chosenServer, setChosenServer] = useAtom(chosenServerAtom);
|
|
1637
1664
|
const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
|
|
1638
1665
|
const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
|
|
1666
|
+
const getValues = () => Object.keys(bodyParameterValues)
|
|
1667
|
+
.filter(param => { var _a; return (_a = !isAllowedEmptyValues[param]) !== null && _a !== void 0 ? _a : true; })
|
|
1668
|
+
.reduce((previousValue, currentValue) => {
|
|
1669
|
+
previousValue[currentValue] = bodyParameterValues[currentValue];
|
|
1670
|
+
return previousValue;
|
|
1671
|
+
}, {});
|
|
1639
1672
|
React.useEffect(() => {
|
|
1640
1673
|
const currentUrl = chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url;
|
|
1641
1674
|
const exists = currentUrl && servers.find(s => s.url === currentUrl);
|
|
@@ -1649,7 +1682,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1649
1682
|
React.useEffect(() => {
|
|
1650
1683
|
let isMounted = true;
|
|
1651
1684
|
if (onRequestChange || embeddedInMd) {
|
|
1652
|
-
buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ?
|
|
1685
|
+
buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
|
|
1653
1686
|
corsProxy })).then(request => {
|
|
1654
1687
|
if (isMounted) {
|
|
1655
1688
|
if (onRequestChange) {
|
|
@@ -1669,6 +1702,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1669
1702
|
parameterValuesWithDefaults,
|
|
1670
1703
|
formDataState.isFormDataBody,
|
|
1671
1704
|
bodyParameterValues,
|
|
1705
|
+
isAllowedEmptyValues,
|
|
1672
1706
|
textRequestBody,
|
|
1673
1707
|
operationAuthValue,
|
|
1674
1708
|
mockingOptions,
|
|
@@ -1687,7 +1721,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1687
1721
|
parameterValues: parameterValuesWithDefaults,
|
|
1688
1722
|
httpOperation,
|
|
1689
1723
|
mediaTypeContent,
|
|
1690
|
-
bodyInput: formDataState.isFormDataBody ?
|
|
1724
|
+
bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody,
|
|
1691
1725
|
mockData,
|
|
1692
1726
|
auth: operationAuthValue,
|
|
1693
1727
|
chosenServer,
|
|
@@ -1723,7 +1757,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1723
1757
|
const tryItPanelContents = (React.createElement(React.Fragment, null,
|
|
1724
1758
|
((_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
1759
|
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,
|
|
1760
|
+
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
1761
|
React.createElement(Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
|
|
1728
1762
|
React.createElement(HStack, { alignItems: "center", spacing: 2 },
|
|
1729
1763
|
React.createElement(Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
|
|
@@ -2295,7 +2329,7 @@ const SidebarLayout = React.forwardRef(({ sidebar, children, maxContentWidth = M
|
|
|
2295
2329
|
paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
|
|
2296
2330
|
minWidth: `${sidebarWidth}px`,
|
|
2297
2331
|
} }, sidebar),
|
|
2298
|
-
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full" },
|
|
2332
|
+
React.createElement(Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full", overflowY: "auto" },
|
|
2299
2333
|
React.createElement(Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
|
|
2300
2334
|
});
|
|
2301
2335
|
|
|
@@ -2350,8 +2384,8 @@ const SchemaAndDescription = ({ title: titleProp, schema }) => {
|
|
|
2350
2384
|
React__default.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
|
|
2351
2385
|
};
|
|
2352
2386
|
const CodeComponent = props => {
|
|
2353
|
-
const { title, jsonSchema, http, children } = props;
|
|
2354
|
-
const value = String(Array.isArray(children) ? children[0] : children);
|
|
2387
|
+
const { title, jsonSchema, http, resolved, children } = props;
|
|
2388
|
+
const value = resolved || String(Array.isArray(children) ? children[0] : children);
|
|
2355
2389
|
const parsedValue = useParsedValue(value);
|
|
2356
2390
|
if (jsonSchema) {
|
|
2357
2391
|
if (!isJSONSchema(parsedValue)) {
|
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) {
|
|
@@ -411,13 +411,16 @@ function createNamedContext(name, defaultValue) {
|
|
|
411
411
|
|
|
412
412
|
const chosenServerAtom = jotai.atom(undefined);
|
|
413
413
|
|
|
414
|
+
function isValidServer(server) {
|
|
415
|
+
return server.url !== null && isProperUrl(server.url);
|
|
416
|
+
}
|
|
414
417
|
const getServersToDisplay = (originalServers, mockUrl) => {
|
|
415
418
|
const servers = originalServers
|
|
416
419
|
.map((server, i) => {
|
|
417
420
|
const fallbackDescription = originalServers.length === 1 ? 'Live Server' : `Server ${i + 1}`;
|
|
418
421
|
return Object.assign(Object.assign({}, server), { url: getServerUrlWithDefaultValues(server), description: server.description || fallbackDescription });
|
|
419
422
|
})
|
|
420
|
-
.filter(
|
|
423
|
+
.filter(isValidServer);
|
|
421
424
|
if (mockUrl) {
|
|
422
425
|
servers.push({
|
|
423
426
|
description: 'Mock Server',
|
|
@@ -433,7 +436,13 @@ const getServerUrlWithDefaultValues = (server) => {
|
|
|
433
436
|
variables.forEach(([variableName, variableInfo]) => {
|
|
434
437
|
urlString = urlString.replace(`{${variableName}}`, variableInfo.default);
|
|
435
438
|
});
|
|
436
|
-
let url
|
|
439
|
+
let url;
|
|
440
|
+
try {
|
|
441
|
+
url = URI__default["default"](urlString);
|
|
442
|
+
}
|
|
443
|
+
catch (_b) {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
437
446
|
if (url.is('relative') && typeof window !== 'undefined') {
|
|
438
447
|
url = url.absoluteTo(window.location.origin);
|
|
439
448
|
}
|
|
@@ -1023,9 +1032,10 @@ function mapSchemaPropertiesToParameters(properties, required) {
|
|
|
1023
1032
|
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
1033
|
}
|
|
1025
1034
|
|
|
1026
|
-
const ParameterEditor = ({ parameter, value, onChange, validate }) => {
|
|
1035
|
+
const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
|
|
1027
1036
|
var _a, _b;
|
|
1028
1037
|
const inputId = useUniqueId(`id_${parameter.name}_`);
|
|
1038
|
+
const inputCheckId = useUniqueId(`id_${parameter.name}_checked`);
|
|
1029
1039
|
const parameterValueOptions = parameterOptions(parameter);
|
|
1030
1040
|
const examples = exampleOptions(parameter);
|
|
1031
1041
|
const selectedExample = (_a = examples === null || examples === void 0 ? void 0 : examples.find(e => e.value === value)) !== null && _a !== void 0 ? _a : selectExampleOption;
|
|
@@ -1036,10 +1046,19 @@ const ParameterEditor = ({ parameter, value, onChange, validate }) => {
|
|
|
1036
1046
|
React__namespace.createElement(mosaic.Text, { mx: 3 }, ":"),
|
|
1037
1047
|
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
1048
|
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 })))))
|
|
1049
|
+
examples && (React__namespace.createElement(mosaic.Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange }))))),
|
|
1050
|
+
canChangeOptional && !parameter.required && (React__namespace.createElement(React__namespace.Fragment, null,
|
|
1051
|
+
React__namespace.createElement("div", null),
|
|
1052
|
+
React__namespace.createElement("div", null),
|
|
1053
|
+
React__namespace.createElement("div", null,
|
|
1054
|
+
React__namespace.createElement(mosaic.Flex, { flex: 1 },
|
|
1055
|
+
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) }),
|
|
1056
|
+
React__namespace.createElement(mosaic.Text, { className: "TextForCheckBox", flex: 1, as: "label", "aria-hidden": "true", "data-testid": "param-check", htmlFor: inputCheckId, fontSize: "base" },
|
|
1057
|
+
"Omit ",
|
|
1058
|
+
parameterDisplayName)))))));
|
|
1040
1059
|
};
|
|
1041
1060
|
|
|
1042
|
-
const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
1061
|
+
const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
|
|
1043
1062
|
const schema = specification.schema;
|
|
1044
1063
|
const parameters = schema === null || schema === void 0 ? void 0 : schema.properties;
|
|
1045
1064
|
const required = schema === null || schema === void 0 ? void 0 : schema.required;
|
|
@@ -1054,6 +1073,7 @@ const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
|
1054
1073
|
return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
|
|
1055
1074
|
React__namespace.createElement(mosaic.Panel.Titlebar, null, "Body"),
|
|
1056
1075
|
React__namespace.createElement(mosaic.Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, mapSchemaPropertiesToParameters(parameters, required).map(parameter => {
|
|
1076
|
+
var _a;
|
|
1057
1077
|
const supportsFileUpload = parameterSupportsFileUpload(parameter);
|
|
1058
1078
|
const value = values[parameter.name];
|
|
1059
1079
|
if (supportsFileUpload) {
|
|
@@ -1061,7 +1081,7 @@ const FormDataBody = ({ specification, values, onChangeValues }) => {
|
|
|
1061
1081
|
? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
|
|
1062
1082
|
: onChangeValues(omit__default["default"](values, parameter.name)) }));
|
|
1063
1083
|
}
|
|
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 })) }));
|
|
1084
|
+
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
1085
|
}))));
|
|
1066
1086
|
};
|
|
1067
1087
|
|
|
@@ -1135,6 +1155,7 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1135
1155
|
return initialParameterValues(parameters);
|
|
1136
1156
|
}, [isFormDataBody, mediaTypeContent]);
|
|
1137
1157
|
const [bodyParameterValues, setBodyParameterValues] = React__namespace.useState(initialState);
|
|
1158
|
+
const [isAllowedEmptyValue, setAllowedEmptyValue] = React__namespace.useState({});
|
|
1138
1159
|
React__namespace.useEffect(() => {
|
|
1139
1160
|
setBodyParameterValues(initialState);
|
|
1140
1161
|
}, [initialState]);
|
|
@@ -1142,6 +1163,8 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1142
1163
|
return [
|
|
1143
1164
|
bodyParameterValues,
|
|
1144
1165
|
setBodyParameterValues,
|
|
1166
|
+
isAllowedEmptyValue,
|
|
1167
|
+
setAllowedEmptyValue,
|
|
1145
1168
|
{ isFormDataBody: true, bodySpecification: mediaTypeContent },
|
|
1146
1169
|
];
|
|
1147
1170
|
}
|
|
@@ -1149,6 +1172,8 @@ const useBodyParameterState = (mediaTypeContent) => {
|
|
|
1149
1172
|
return [
|
|
1150
1173
|
bodyParameterValues,
|
|
1151
1174
|
setBodyParameterValues,
|
|
1175
|
+
isAllowedEmptyValue,
|
|
1176
|
+
setAllowedEmptyValue,
|
|
1152
1177
|
{ isFormDataBody: false, bodySpecification: undefined },
|
|
1153
1178
|
];
|
|
1154
1179
|
}
|
|
@@ -1285,14 +1310,14 @@ function buildFetchRequest({ httpOperation, mediaTypeContent, bodyInput, paramet
|
|
|
1285
1310
|
.filter(({ value }) => value.length > 0);
|
|
1286
1311
|
const [queryParamsWithAuth, headersWithAuth] = runAuthRequestEhancements(auth, queryParams, rawHeaders);
|
|
1287
1312
|
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1313
|
+
const urlObject = new URL(serverUrl + expandedPath);
|
|
1314
|
+
urlObject.search = new URLSearchParams(queryParamsWithAuth.map(nameAndValueObjectToPair)).toString();
|
|
1290
1315
|
const body = typeof bodyInput === 'object' ? yield createRequestBody(mediaTypeContent, bodyInput) : bodyInput;
|
|
1291
1316
|
const headers = Object.assign(Object.assign(Object.assign({}, ((mediaTypeContent === null || mediaTypeContent === void 0 ? void 0 : mediaTypeContent.mediaType) !== 'multipart/form-data' && {
|
|
1292
1317
|
'Content-Type': (_f = mediaTypeContent === null || mediaTypeContent === void 0 ? void 0 : mediaTypeContent.mediaType) !== null && _f !== void 0 ? _f : 'application/json',
|
|
1293
1318
|
})), Object.fromEntries(headersWithAuth.map(nameAndValueObjectToPair))), mockData === null || mockData === void 0 ? void 0 : mockData.header);
|
|
1294
1319
|
return [
|
|
1295
|
-
|
|
1320
|
+
urlObject.href,
|
|
1296
1321
|
{
|
|
1297
1322
|
credentials,
|
|
1298
1323
|
method: httpOperation.method.toUpperCase(),
|
|
@@ -1360,7 +1385,8 @@ function buildHarRequest({ httpOperation, bodyInput, parameterValues, mediaTypeC
|
|
|
1360
1385
|
headerParams.push({ name: 'Prefer', value: mockData.header.Prefer });
|
|
1361
1386
|
}
|
|
1362
1387
|
const [queryParamsWithAuth, headerParamsWithAuth] = runAuthRequestEhancements(auth, queryParams, headerParams);
|
|
1363
|
-
const
|
|
1388
|
+
const expandedPath = uriExpand(httpOperation.path, parameterValues);
|
|
1389
|
+
const urlObject = new URL(serverUrl + expandedPath);
|
|
1364
1390
|
let postData = undefined;
|
|
1365
1391
|
if (shouldIncludeBody && typeof bodyInput === 'string') {
|
|
1366
1392
|
postData = { mimeType, text: bodyInput };
|
|
@@ -1385,7 +1411,7 @@ function buildHarRequest({ httpOperation, bodyInput, parameterValues, mediaTypeC
|
|
|
1385
1411
|
}
|
|
1386
1412
|
return {
|
|
1387
1413
|
method: httpOperation.method.toUpperCase(),
|
|
1388
|
-
url:
|
|
1414
|
+
url: urlObject.href,
|
|
1389
1415
|
httpVersion: 'HTTP/1.1',
|
|
1390
1416
|
cookies: [],
|
|
1391
1417
|
headers: [{ name: 'Content-Type', value: mimeType }, ...headerParamsWithAuth],
|
|
@@ -1519,7 +1545,7 @@ const useMockingOptions = () => jotai.useAtom(mockingOptionsAtom);
|
|
|
1519
1545
|
const OperationParameters = ({ parameters, values, onChangeValue, validate, }) => {
|
|
1520
1546
|
return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
|
|
1521
1547
|
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 }))))));
|
|
1548
|
+
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
1549
|
};
|
|
1524
1550
|
|
|
1525
1551
|
const persistedParameterValuesAtom = jotai.atom({});
|
|
@@ -1671,6 +1697,7 @@ ServersDropdown.displayName = 'ServersDropdown';
|
|
|
1671
1697
|
const defaultServers = [];
|
|
1672
1698
|
const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embeddedInMd = false, tryItCredentialsPolicy, corsProxy, }) => {
|
|
1673
1699
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1700
|
+
TryIt.displayName = 'TryIt';
|
|
1674
1701
|
const isDark = mosaic.useThemeIsDark();
|
|
1675
1702
|
const [response, setResponse] = React__namespace.useState();
|
|
1676
1703
|
const [requestData, setRequestData] = React__namespace.useState();
|
|
@@ -1679,7 +1706,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1679
1706
|
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
1707
|
const { allParameters, updateParameterValue, parameterValuesWithDefaults } = useRequestParameters(httpOperation);
|
|
1681
1708
|
const [mockingOptions, setMockingOptions] = useMockingOptions();
|
|
1682
|
-
const [bodyParameterValues, setBodyParameterValues, formDataState] = useBodyParameterState(mediaTypeContent);
|
|
1709
|
+
const [bodyParameterValues, setBodyParameterValues, isAllowedEmptyValues, setAllowedEmptyValues, formDataState] = useBodyParameterState(mediaTypeContent);
|
|
1683
1710
|
const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
|
|
1684
1711
|
const [operationAuthValue, setOperationAuthValue] = usePersistedSecuritySchemeWithValues();
|
|
1685
1712
|
const servers = React__namespace.useMemo(() => {
|
|
@@ -1690,6 +1717,12 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1690
1717
|
const [chosenServer, setChosenServer] = jotai.useAtom(chosenServerAtom);
|
|
1691
1718
|
const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
|
|
1692
1719
|
const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
|
|
1720
|
+
const getValues = () => Object.keys(bodyParameterValues)
|
|
1721
|
+
.filter(param => { var _a; return (_a = !isAllowedEmptyValues[param]) !== null && _a !== void 0 ? _a : true; })
|
|
1722
|
+
.reduce((previousValue, currentValue) => {
|
|
1723
|
+
previousValue[currentValue] = bodyParameterValues[currentValue];
|
|
1724
|
+
return previousValue;
|
|
1725
|
+
}, {});
|
|
1693
1726
|
React__namespace.useEffect(() => {
|
|
1694
1727
|
const currentUrl = chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url;
|
|
1695
1728
|
const exists = currentUrl && servers.find(s => s.url === currentUrl);
|
|
@@ -1703,7 +1736,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1703
1736
|
React__namespace.useEffect(() => {
|
|
1704
1737
|
let isMounted = true;
|
|
1705
1738
|
if (onRequestChange || embeddedInMd) {
|
|
1706
|
-
buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ?
|
|
1739
|
+
buildHarRequest(Object.assign(Object.assign({ mediaTypeContent, parameterValues: parameterValuesWithDefaults, httpOperation, bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody, auth: operationAuthValue }, (isMockingEnabled && { mockData: getMockData(mockUrl, httpOperation, mockingOptions) })), { chosenServer,
|
|
1707
1740
|
corsProxy })).then(request => {
|
|
1708
1741
|
if (isMounted) {
|
|
1709
1742
|
if (onRequestChange) {
|
|
@@ -1723,6 +1756,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1723
1756
|
parameterValuesWithDefaults,
|
|
1724
1757
|
formDataState.isFormDataBody,
|
|
1725
1758
|
bodyParameterValues,
|
|
1759
|
+
isAllowedEmptyValues,
|
|
1726
1760
|
textRequestBody,
|
|
1727
1761
|
operationAuthValue,
|
|
1728
1762
|
mockingOptions,
|
|
@@ -1741,7 +1775,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1741
1775
|
parameterValues: parameterValuesWithDefaults,
|
|
1742
1776
|
httpOperation,
|
|
1743
1777
|
mediaTypeContent,
|
|
1744
|
-
bodyInput: formDataState.isFormDataBody ?
|
|
1778
|
+
bodyInput: formDataState.isFormDataBody ? getValues() : textRequestBody,
|
|
1745
1779
|
mockData,
|
|
1746
1780
|
auth: operationAuthValue,
|
|
1747
1781
|
chosenServer,
|
|
@@ -1777,7 +1811,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
|
|
|
1777
1811
|
const tryItPanelContents = (React__namespace.createElement(React__namespace.Fragment, null,
|
|
1778
1812
|
((_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
1813
|
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,
|
|
1814
|
+
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
1815
|
React__namespace.createElement(mosaic.Panel.Content, { className: "SendButtonHolder", mt: 4, pt: !isOnlySendButton && !embeddedInMd ? 0 : undefined },
|
|
1782
1816
|
React__namespace.createElement(mosaic.HStack, { alignItems: "center", spacing: 2 },
|
|
1783
1817
|
React__namespace.createElement(mosaic.Button, { appearance: "primary", loading: loading, disabled: loading, onPress: handleSendRequest, size: "sm" }, "Send API Request"),
|
|
@@ -2349,7 +2383,7 @@ const SidebarLayout = React__namespace.forwardRef(({ sidebar, children, maxConte
|
|
|
2349
2383
|
paddingLeft: `calc((100% - ${maxContentWidth}px) / 2)`,
|
|
2350
2384
|
minWidth: `${sidebarWidth}px`,
|
|
2351
2385
|
} }, sidebar),
|
|
2352
|
-
React__namespace.createElement(mosaic.Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full" },
|
|
2386
|
+
React__namespace.createElement(mosaic.Box, { ref: scrollRef, bg: "canvas", px: 24, flex: 1, w: "full", overflowY: "auto" },
|
|
2353
2387
|
React__namespace.createElement(mosaic.Box, { style: { maxWidth: `${maxContentWidth - sidebarWidth}px` }, py: 16 }, children))));
|
|
2354
2388
|
});
|
|
2355
2389
|
|
|
@@ -2404,8 +2438,8 @@ const SchemaAndDescription = ({ title: titleProp, schema }) => {
|
|
|
2404
2438
|
React__default["default"].createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
|
|
2405
2439
|
};
|
|
2406
2440
|
const CodeComponent = props => {
|
|
2407
|
-
const { title, jsonSchema, http, children } = props;
|
|
2408
|
-
const value = String(Array.isArray(children) ? children[0] : children);
|
|
2441
|
+
const { title, jsonSchema, http, resolved, children } = props;
|
|
2442
|
+
const value = resolved || String(Array.isArray(children) ? children[0] : children);
|
|
2409
2443
|
const parsedValue = useParsedValue(value);
|
|
2410
2444
|
if (jsonSchema) {
|
|
2411
2445
|
if (!isJSONSchema(parsedValue)) {
|