@stoplight/elements-core 7.13.9 → 7.14.0
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/urlencoded-post-oneof.d.ts +3 -0
- package/components/TryIt/Body/FormDataBody.d.ts +8 -2
- package/components/TryIt/Parameters/parameter-utils.d.ts +6 -3
- package/components/TryIt/TryIt.stories.d.ts +1 -0
- package/index.esm.js +74 -19
- package/index.js +75 -19
- package/index.mjs +74 -19
- package/package.json +3 -2
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { Choice } from '@stoplight/json-schema-viewer';
|
|
1
2
|
import { IMediaTypeContent } from '@stoplight/types';
|
|
2
3
|
import * as React from 'react';
|
|
3
4
|
import { BodyParameterValues, ParameterOptional } from './request-body-utils';
|
|
4
|
-
interface FormDataBodyProps {
|
|
5
|
+
export interface FormDataBodyProps {
|
|
5
6
|
specification: IMediaTypeContent;
|
|
6
7
|
values: BodyParameterValues;
|
|
7
8
|
onChangeValues: (newValues: BodyParameterValues) => void;
|
|
@@ -9,4 +10,9 @@ interface FormDataBodyProps {
|
|
|
9
10
|
isAllowedEmptyValues: ParameterOptional;
|
|
10
11
|
}
|
|
11
12
|
export declare const FormDataBody: React.FC<FormDataBodyProps>;
|
|
12
|
-
export {
|
|
13
|
+
export interface OneOfMenuProps {
|
|
14
|
+
choices: Choice[];
|
|
15
|
+
choice: Choice;
|
|
16
|
+
onChange: (choice: Choice) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare function OneOfMenu({ choices: subSchemas, choice, onChange }: OneOfMenuProps): JSX.Element | null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { RegularNode, SchemaNode } from '@stoplight/json-schema-tree';
|
|
1
2
|
import type { IHttpParam, INodeExample, INodeExternalExample } from '@stoplight/types';
|
|
2
|
-
import { JSONSchema7Definition } from 'json-schema';
|
|
3
|
+
import { JSONSchema7, JSONSchema7Definition } from 'json-schema';
|
|
3
4
|
export declare type ParameterSpec = Pick<IHttpParam, 'name' | 'schema' | 'required'> & {
|
|
4
5
|
examples?: (Omit<INodeExample, 'id'> | Omit<INodeExternalExample, 'id'>)[];
|
|
5
6
|
};
|
|
@@ -17,7 +18,7 @@ export declare function exampleOptions(parameter: ParameterSpec): {
|
|
|
17
18
|
value: string;
|
|
18
19
|
label: string;
|
|
19
20
|
}[] | null;
|
|
20
|
-
export declare function parameterSupportsFileUpload(parameter
|
|
21
|
+
export declare function parameterSupportsFileUpload(parameter?: Pick<ParameterSpec, 'schema'>): boolean | undefined;
|
|
21
22
|
export declare function getPlaceholderForParameter(parameter: ParameterSpec): string;
|
|
22
23
|
export declare const initialParameterValues: (params: readonly ParameterSpec[]) => Record<string, string>;
|
|
23
24
|
export declare function mapSchemaPropertiesToParameters(properties: {
|
|
@@ -25,9 +26,11 @@ export declare function mapSchemaPropertiesToParameters(properties: {
|
|
|
25
26
|
}, required: string[] | undefined): {
|
|
26
27
|
required?: boolean | undefined;
|
|
27
28
|
name: string;
|
|
28
|
-
schema:
|
|
29
|
+
schema: JSONSchema7 | undefined;
|
|
29
30
|
examples: {
|
|
30
31
|
key: string;
|
|
31
32
|
value: any;
|
|
32
33
|
}[] | undefined;
|
|
33
34
|
}[];
|
|
35
|
+
export declare function toParameterSpec(jsonTreeNode: RegularNode): ParameterSpec;
|
|
36
|
+
export declare function isRequired(n: SchemaNode): boolean | undefined;
|
|
@@ -6,6 +6,7 @@ export declare const SimpleGET: Story<TryItProps>;
|
|
|
6
6
|
export declare const WithParameters: Story<TryItProps>;
|
|
7
7
|
export declare const WithVariables: Story<TryItProps>;
|
|
8
8
|
export declare const UrlEncoded: Story<TryItProps>;
|
|
9
|
+
export declare const UrlEncodedOneOf: Story<TryItProps>;
|
|
9
10
|
export declare const Multipart: Story<TryItProps>;
|
|
10
11
|
export declare const RequestBodySchema: Story<TryItProps>;
|
|
11
12
|
export declare const RequestBodyExamples: Story<TryItProps>;
|
package/index.esm.js
CHANGED
|
@@ -25,8 +25,11 @@ import filter from 'lodash/filter.js';
|
|
|
25
25
|
import flatten from 'lodash/flatten.js';
|
|
26
26
|
import { nanoid } from 'nanoid';
|
|
27
27
|
import curry from 'lodash/curry.js';
|
|
28
|
+
import { isRegularNode, SchemaTree } from '@stoplight/json-schema-tree';
|
|
29
|
+
import { useChoices, visibleChildren, JsonSchemaViewer } from '@stoplight/json-schema-viewer';
|
|
28
30
|
import omit from 'lodash/omit.js';
|
|
29
31
|
import keyBy from 'lodash/keyBy.js';
|
|
32
|
+
import last from 'lodash/last.js';
|
|
30
33
|
import map from 'lodash/map.js';
|
|
31
34
|
import mapValues from 'lodash/mapValues.js';
|
|
32
35
|
import isString from 'lodash/isString.js';
|
|
@@ -40,7 +43,6 @@ import uniqBy from 'lodash/uniqBy.js';
|
|
|
40
43
|
import formatXml from 'xml-formatter';
|
|
41
44
|
import entries from 'lodash/entries.js';
|
|
42
45
|
import keys from 'lodash/keys.js';
|
|
43
|
-
import { JsonSchemaViewer } from '@stoplight/json-schema-viewer';
|
|
44
46
|
import sortBy from 'lodash/sortBy.js';
|
|
45
47
|
import isEmpty from 'lodash/isEmpty.js';
|
|
46
48
|
import isNil from 'lodash/isNil.js';
|
|
@@ -1176,7 +1178,9 @@ function exampleOptions(parameter) {
|
|
|
1176
1178
|
}
|
|
1177
1179
|
function parameterSupportsFileUpload(parameter) {
|
|
1178
1180
|
var _a, _b, _c;
|
|
1179
|
-
return (
|
|
1181
|
+
return (parameter &&
|
|
1182
|
+
parameter.schema &&
|
|
1183
|
+
((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
|
|
1180
1184
|
(((_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.contentEncoding) === 'base64' ||
|
|
1181
1185
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1182
1186
|
}
|
|
@@ -1232,6 +1236,35 @@ function mapSchemaPropertiesToParameters(properties, required) {
|
|
|
1232
1236
|
return Object.entries(properties).map(([name, schema]) => (Object.assign({ name, schema: typeof schema !== 'boolean' ? schema : undefined, examples: typeof schema !== 'boolean' && schema.examples && schema.examples[0]
|
|
1233
1237
|
? [{ key: 'example', value: schema.examples[0] }]
|
|
1234
1238
|
: undefined }, ((required === null || required === void 0 ? void 0 : required.includes(name)) && { required: true }))));
|
|
1239
|
+
}
|
|
1240
|
+
function toParameterSpec(jsonTreeNode) {
|
|
1241
|
+
var _a;
|
|
1242
|
+
const isBoolean = jsonTreeNode.primaryType === 'boolean';
|
|
1243
|
+
const schema = !isBoolean ? jsonTreeNode.fragment : undefined;
|
|
1244
|
+
const examples = !isBoolean && jsonTreeNode.fragment.examples && jsonTreeNode.fragment.examples[0]
|
|
1245
|
+
? [{ key: 'example', value: jsonTreeNode.fragment.examples[0] }]
|
|
1246
|
+
: undefined;
|
|
1247
|
+
const lastJsonPathSegment = (_a = last(jsonTreeNode.path)) !== null && _a !== void 0 ? _a : '<<UNKNOWN>>';
|
|
1248
|
+
return {
|
|
1249
|
+
name: lastJsonPathSegment,
|
|
1250
|
+
schema,
|
|
1251
|
+
examples,
|
|
1252
|
+
required: isRequired(jsonTreeNode),
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
function isRequired(n) {
|
|
1256
|
+
if (!isRegularNode(n)) {
|
|
1257
|
+
return undefined;
|
|
1258
|
+
}
|
|
1259
|
+
const name = last(n.path);
|
|
1260
|
+
if (name === undefined) {
|
|
1261
|
+
return undefined;
|
|
1262
|
+
}
|
|
1263
|
+
const parent = n.parent;
|
|
1264
|
+
if (parent === null || !isRegularNode(parent)) {
|
|
1265
|
+
return undefined;
|
|
1266
|
+
}
|
|
1267
|
+
return parent.required !== null && parent.required.includes(name);
|
|
1235
1268
|
}
|
|
1236
1269
|
|
|
1237
1270
|
const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
|
|
@@ -1261,31 +1294,53 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
|
|
|
1261
1294
|
};
|
|
1262
1295
|
|
|
1263
1296
|
const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
|
|
1264
|
-
const schema =
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1297
|
+
const schema = React.useMemo(() => {
|
|
1298
|
+
var _a;
|
|
1299
|
+
const schema = (_a = specification.schema) !== null && _a !== void 0 ? _a : {};
|
|
1300
|
+
const tree = new SchemaTree(schema, { mergeAllOf: true, refResolver: null });
|
|
1301
|
+
tree.populate();
|
|
1302
|
+
return tree.root.children[0];
|
|
1303
|
+
}, [specification]);
|
|
1304
|
+
const { selectedChoice, choices, setSelectedChoice } = useChoices(schema);
|
|
1305
|
+
const formFieldRows = visibleChildren(selectedChoice.type);
|
|
1306
|
+
const onSchemaChange = (choice) => {
|
|
1307
|
+
onChangeValues({});
|
|
1308
|
+
setSelectedChoice(choice);
|
|
1309
|
+
};
|
|
1275
1310
|
return (React.createElement(Panel, { defaultIsOpen: true },
|
|
1276
|
-
React.createElement(Panel.Titlebar,
|
|
1277
|
-
React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" },
|
|
1278
|
-
|
|
1311
|
+
React.createElement(Panel.Titlebar, { rightComponent: React.createElement(OneOfMenu, { choices: choices, choice: selectedChoice, onChange: onSchemaChange }) }, "Body"),
|
|
1312
|
+
React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, formFieldRows
|
|
1313
|
+
.filter(isRegularNode)
|
|
1314
|
+
.map(toParameterSpec)
|
|
1315
|
+
.map(parameter => {
|
|
1316
|
+
var _a, _b;
|
|
1279
1317
|
const supportsFileUpload = parameterSupportsFileUpload(parameter);
|
|
1280
|
-
const value = values[parameter.name];
|
|
1318
|
+
const value = values[(_a = parameter.name) !== null && _a !== void 0 ? _a : ''];
|
|
1281
1319
|
if (supportsFileUpload) {
|
|
1282
1320
|
return (React.createElement(FileUploadParameterEditor, { key: parameter.name, parameter: parameter, value: value instanceof File ? value : undefined, onChange: newValue => newValue
|
|
1283
1321
|
? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
|
|
1284
1322
|
: onChangeValues(omit(values, parameter.name)) }));
|
|
1285
1323
|
}
|
|
1286
|
-
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: (
|
|
1324
|
+
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: (_b = isAllowedEmptyValues[parameter.name]) !== null && _b !== void 0 ? _b : false }));
|
|
1287
1325
|
}))));
|
|
1288
|
-
};
|
|
1326
|
+
};
|
|
1327
|
+
function OneOfMenu({ choices: subSchemas, choice, onChange }) {
|
|
1328
|
+
var _a;
|
|
1329
|
+
const onSubSchemaSelect = React.useCallback(onChange, [onChange]);
|
|
1330
|
+
const menuItems = React.useMemo(() => subSchemas.map(subSchema => {
|
|
1331
|
+
const label = subSchema.title;
|
|
1332
|
+
return {
|
|
1333
|
+
id: `request-subschema-${label}`,
|
|
1334
|
+
title: label,
|
|
1335
|
+
onPress: () => onSubSchemaSelect(subSchema),
|
|
1336
|
+
};
|
|
1337
|
+
}), [subSchemas, onSubSchemaSelect]);
|
|
1338
|
+
if (!subSchemas || subSchemas.length < 2) {
|
|
1339
|
+
return null;
|
|
1340
|
+
}
|
|
1341
|
+
const title = (_a = choice === null || choice === void 0 ? void 0 : choice.title) !== null && _a !== void 0 ? _a : 'Variants';
|
|
1342
|
+
return (React.createElement(Menu, { "aria-label": title, items: menuItems, renderTrigger: ({ isOpen }) => (React.createElement(Button, { appearance: "minimal", size: "sm", iconRight: ['fas', 'sort'], active: isOpen, "data-testid": "oneof-menu" }, title)) }));
|
|
1343
|
+
}
|
|
1289
1344
|
|
|
1290
1345
|
const fileToBase64 = (file) => new Promise((resolve, reject) => {
|
|
1291
1346
|
const reader = new FileReader();
|
package/index.js
CHANGED
|
@@ -27,8 +27,11 @@ var filter = require('lodash/filter.js');
|
|
|
27
27
|
var flatten = require('lodash/flatten.js');
|
|
28
28
|
var nanoid = require('nanoid');
|
|
29
29
|
var curry = require('lodash/curry.js');
|
|
30
|
+
var jsonSchemaTree = require('@stoplight/json-schema-tree');
|
|
31
|
+
var jsonSchemaViewer = require('@stoplight/json-schema-viewer');
|
|
30
32
|
var omit = require('lodash/omit.js');
|
|
31
33
|
var keyBy = require('lodash/keyBy.js');
|
|
34
|
+
var last = require('lodash/last.js');
|
|
32
35
|
var map = require('lodash/map.js');
|
|
33
36
|
var mapValues = require('lodash/mapValues.js');
|
|
34
37
|
var isString = require('lodash/isString.js');
|
|
@@ -42,7 +45,6 @@ var uniqBy = require('lodash/uniqBy.js');
|
|
|
42
45
|
var formatXml = require('xml-formatter');
|
|
43
46
|
var entries = require('lodash/entries.js');
|
|
44
47
|
var keys = require('lodash/keys.js');
|
|
45
|
-
var jsonSchemaViewer = require('@stoplight/json-schema-viewer');
|
|
46
48
|
var sortBy = require('lodash/sortBy.js');
|
|
47
49
|
var isEmpty = require('lodash/isEmpty.js');
|
|
48
50
|
var isNil = require('lodash/isNil.js');
|
|
@@ -87,6 +89,7 @@ var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
|
|
|
87
89
|
var curry__default = /*#__PURE__*/_interopDefaultLegacy(curry);
|
|
88
90
|
var omit__default = /*#__PURE__*/_interopDefaultLegacy(omit);
|
|
89
91
|
var keyBy__default = /*#__PURE__*/_interopDefaultLegacy(keyBy);
|
|
92
|
+
var last__default = /*#__PURE__*/_interopDefaultLegacy(last);
|
|
90
93
|
var map__default = /*#__PURE__*/_interopDefaultLegacy(map);
|
|
91
94
|
var mapValues__default = /*#__PURE__*/_interopDefaultLegacy(mapValues);
|
|
92
95
|
var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
|
|
@@ -1232,7 +1235,9 @@ function exampleOptions(parameter) {
|
|
|
1232
1235
|
}
|
|
1233
1236
|
function parameterSupportsFileUpload(parameter) {
|
|
1234
1237
|
var _a, _b, _c;
|
|
1235
|
-
return (
|
|
1238
|
+
return (parameter &&
|
|
1239
|
+
parameter.schema &&
|
|
1240
|
+
((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
|
|
1236
1241
|
(((_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.contentEncoding) === 'base64' ||
|
|
1237
1242
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1238
1243
|
}
|
|
@@ -1288,6 +1293,35 @@ function mapSchemaPropertiesToParameters(properties, required) {
|
|
|
1288
1293
|
return Object.entries(properties).map(([name, schema]) => (Object.assign({ name, schema: typeof schema !== 'boolean' ? schema : undefined, examples: typeof schema !== 'boolean' && schema.examples && schema.examples[0]
|
|
1289
1294
|
? [{ key: 'example', value: schema.examples[0] }]
|
|
1290
1295
|
: undefined }, ((required === null || required === void 0 ? void 0 : required.includes(name)) && { required: true }))));
|
|
1296
|
+
}
|
|
1297
|
+
function toParameterSpec(jsonTreeNode) {
|
|
1298
|
+
var _a;
|
|
1299
|
+
const isBoolean = jsonTreeNode.primaryType === 'boolean';
|
|
1300
|
+
const schema = !isBoolean ? jsonTreeNode.fragment : undefined;
|
|
1301
|
+
const examples = !isBoolean && jsonTreeNode.fragment.examples && jsonTreeNode.fragment.examples[0]
|
|
1302
|
+
? [{ key: 'example', value: jsonTreeNode.fragment.examples[0] }]
|
|
1303
|
+
: undefined;
|
|
1304
|
+
const lastJsonPathSegment = (_a = last__default["default"](jsonTreeNode.path)) !== null && _a !== void 0 ? _a : '<<UNKNOWN>>';
|
|
1305
|
+
return {
|
|
1306
|
+
name: lastJsonPathSegment,
|
|
1307
|
+
schema,
|
|
1308
|
+
examples,
|
|
1309
|
+
required: isRequired(jsonTreeNode),
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
function isRequired(n) {
|
|
1313
|
+
if (!jsonSchemaTree.isRegularNode(n)) {
|
|
1314
|
+
return undefined;
|
|
1315
|
+
}
|
|
1316
|
+
const name = last__default["default"](n.path);
|
|
1317
|
+
if (name === undefined) {
|
|
1318
|
+
return undefined;
|
|
1319
|
+
}
|
|
1320
|
+
const parent = n.parent;
|
|
1321
|
+
if (parent === null || !jsonSchemaTree.isRegularNode(parent)) {
|
|
1322
|
+
return undefined;
|
|
1323
|
+
}
|
|
1324
|
+
return parent.required !== null && parent.required.includes(name);
|
|
1291
1325
|
}
|
|
1292
1326
|
|
|
1293
1327
|
const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
|
|
@@ -1317,31 +1351,53 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
|
|
|
1317
1351
|
};
|
|
1318
1352
|
|
|
1319
1353
|
const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
|
|
1320
|
-
const schema =
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1354
|
+
const schema = React__namespace.useMemo(() => {
|
|
1355
|
+
var _a;
|
|
1356
|
+
const schema = (_a = specification.schema) !== null && _a !== void 0 ? _a : {};
|
|
1357
|
+
const tree = new jsonSchemaTree.SchemaTree(schema, { mergeAllOf: true, refResolver: null });
|
|
1358
|
+
tree.populate();
|
|
1359
|
+
return tree.root.children[0];
|
|
1360
|
+
}, [specification]);
|
|
1361
|
+
const { selectedChoice, choices, setSelectedChoice } = jsonSchemaViewer.useChoices(schema);
|
|
1362
|
+
const formFieldRows = jsonSchemaViewer.visibleChildren(selectedChoice.type);
|
|
1363
|
+
const onSchemaChange = (choice) => {
|
|
1364
|
+
onChangeValues({});
|
|
1365
|
+
setSelectedChoice(choice);
|
|
1366
|
+
};
|
|
1331
1367
|
return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
|
|
1332
|
-
React__namespace.createElement(mosaic.Panel.Titlebar,
|
|
1333
|
-
React__namespace.createElement(mosaic.Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" },
|
|
1334
|
-
|
|
1368
|
+
React__namespace.createElement(mosaic.Panel.Titlebar, { rightComponent: React__namespace.createElement(OneOfMenu, { choices: choices, choice: selectedChoice, onChange: onSchemaChange }) }, "Body"),
|
|
1369
|
+
React__namespace.createElement(mosaic.Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, formFieldRows
|
|
1370
|
+
.filter(jsonSchemaTree.isRegularNode)
|
|
1371
|
+
.map(toParameterSpec)
|
|
1372
|
+
.map(parameter => {
|
|
1373
|
+
var _a, _b;
|
|
1335
1374
|
const supportsFileUpload = parameterSupportsFileUpload(parameter);
|
|
1336
|
-
const value = values[parameter.name];
|
|
1375
|
+
const value = values[(_a = parameter.name) !== null && _a !== void 0 ? _a : ''];
|
|
1337
1376
|
if (supportsFileUpload) {
|
|
1338
1377
|
return (React__namespace.createElement(FileUploadParameterEditor, { key: parameter.name, parameter: parameter, value: value instanceof File ? value : undefined, onChange: newValue => newValue
|
|
1339
1378
|
? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
|
|
1340
1379
|
: onChangeValues(omit__default["default"](values, parameter.name)) }));
|
|
1341
1380
|
}
|
|
1342
|
-
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: (
|
|
1381
|
+
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: (_b = isAllowedEmptyValues[parameter.name]) !== null && _b !== void 0 ? _b : false }));
|
|
1343
1382
|
}))));
|
|
1344
|
-
};
|
|
1383
|
+
};
|
|
1384
|
+
function OneOfMenu({ choices: subSchemas, choice, onChange }) {
|
|
1385
|
+
var _a;
|
|
1386
|
+
const onSubSchemaSelect = React__namespace.useCallback(onChange, [onChange]);
|
|
1387
|
+
const menuItems = React__namespace.useMemo(() => subSchemas.map(subSchema => {
|
|
1388
|
+
const label = subSchema.title;
|
|
1389
|
+
return {
|
|
1390
|
+
id: `request-subschema-${label}`,
|
|
1391
|
+
title: label,
|
|
1392
|
+
onPress: () => onSubSchemaSelect(subSchema),
|
|
1393
|
+
};
|
|
1394
|
+
}), [subSchemas, onSubSchemaSelect]);
|
|
1395
|
+
if (!subSchemas || subSchemas.length < 2) {
|
|
1396
|
+
return null;
|
|
1397
|
+
}
|
|
1398
|
+
const title = (_a = choice === null || choice === void 0 ? void 0 : choice.title) !== null && _a !== void 0 ? _a : 'Variants';
|
|
1399
|
+
return (React__namespace.createElement(mosaic.Menu, { "aria-label": title, items: menuItems, renderTrigger: ({ isOpen }) => (React__namespace.createElement(mosaic.Button, { appearance: "minimal", size: "sm", iconRight: ['fas', 'sort'], active: isOpen, "data-testid": "oneof-menu" }, title)) }));
|
|
1400
|
+
}
|
|
1345
1401
|
|
|
1346
1402
|
const fileToBase64 = (file) => new Promise((resolve, reject) => {
|
|
1347
1403
|
const reader = new FileReader();
|
package/index.mjs
CHANGED
|
@@ -25,8 +25,11 @@ import filter from 'lodash/filter.js';
|
|
|
25
25
|
import flatten from 'lodash/flatten.js';
|
|
26
26
|
import { nanoid } from 'nanoid';
|
|
27
27
|
import curry from 'lodash/curry.js';
|
|
28
|
+
import { isRegularNode, SchemaTree } from '@stoplight/json-schema-tree';
|
|
29
|
+
import { useChoices, visibleChildren, JsonSchemaViewer } from '@stoplight/json-schema-viewer';
|
|
28
30
|
import omit from 'lodash/omit.js';
|
|
29
31
|
import keyBy from 'lodash/keyBy.js';
|
|
32
|
+
import last from 'lodash/last.js';
|
|
30
33
|
import map from 'lodash/map.js';
|
|
31
34
|
import mapValues from 'lodash/mapValues.js';
|
|
32
35
|
import isString from 'lodash/isString.js';
|
|
@@ -40,7 +43,6 @@ import uniqBy from 'lodash/uniqBy.js';
|
|
|
40
43
|
import formatXml from 'xml-formatter';
|
|
41
44
|
import entries from 'lodash/entries.js';
|
|
42
45
|
import keys from 'lodash/keys.js';
|
|
43
|
-
import { JsonSchemaViewer } from '@stoplight/json-schema-viewer';
|
|
44
46
|
import sortBy from 'lodash/sortBy.js';
|
|
45
47
|
import isEmpty from 'lodash/isEmpty.js';
|
|
46
48
|
import isNil from 'lodash/isNil.js';
|
|
@@ -1176,7 +1178,9 @@ function exampleOptions(parameter) {
|
|
|
1176
1178
|
}
|
|
1177
1179
|
function parameterSupportsFileUpload(parameter) {
|
|
1178
1180
|
var _a, _b, _c;
|
|
1179
|
-
return (
|
|
1181
|
+
return (parameter &&
|
|
1182
|
+
parameter.schema &&
|
|
1183
|
+
((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
|
|
1180
1184
|
(((_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.contentEncoding) === 'base64' ||
|
|
1181
1185
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1182
1186
|
}
|
|
@@ -1232,6 +1236,35 @@ function mapSchemaPropertiesToParameters(properties, required) {
|
|
|
1232
1236
|
return Object.entries(properties).map(([name, schema]) => (Object.assign({ name, schema: typeof schema !== 'boolean' ? schema : undefined, examples: typeof schema !== 'boolean' && schema.examples && schema.examples[0]
|
|
1233
1237
|
? [{ key: 'example', value: schema.examples[0] }]
|
|
1234
1238
|
: undefined }, ((required === null || required === void 0 ? void 0 : required.includes(name)) && { required: true }))));
|
|
1239
|
+
}
|
|
1240
|
+
function toParameterSpec(jsonTreeNode) {
|
|
1241
|
+
var _a;
|
|
1242
|
+
const isBoolean = jsonTreeNode.primaryType === 'boolean';
|
|
1243
|
+
const schema = !isBoolean ? jsonTreeNode.fragment : undefined;
|
|
1244
|
+
const examples = !isBoolean && jsonTreeNode.fragment.examples && jsonTreeNode.fragment.examples[0]
|
|
1245
|
+
? [{ key: 'example', value: jsonTreeNode.fragment.examples[0] }]
|
|
1246
|
+
: undefined;
|
|
1247
|
+
const lastJsonPathSegment = (_a = last(jsonTreeNode.path)) !== null && _a !== void 0 ? _a : '<<UNKNOWN>>';
|
|
1248
|
+
return {
|
|
1249
|
+
name: lastJsonPathSegment,
|
|
1250
|
+
schema,
|
|
1251
|
+
examples,
|
|
1252
|
+
required: isRequired(jsonTreeNode),
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
function isRequired(n) {
|
|
1256
|
+
if (!isRegularNode(n)) {
|
|
1257
|
+
return undefined;
|
|
1258
|
+
}
|
|
1259
|
+
const name = last(n.path);
|
|
1260
|
+
if (name === undefined) {
|
|
1261
|
+
return undefined;
|
|
1262
|
+
}
|
|
1263
|
+
const parent = n.parent;
|
|
1264
|
+
if (parent === null || !isRegularNode(parent)) {
|
|
1265
|
+
return undefined;
|
|
1266
|
+
}
|
|
1267
|
+
return parent.required !== null && parent.required.includes(name);
|
|
1235
1268
|
}
|
|
1236
1269
|
|
|
1237
1270
|
const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
|
|
@@ -1261,31 +1294,53 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
|
|
|
1261
1294
|
};
|
|
1262
1295
|
|
|
1263
1296
|
const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
|
|
1264
|
-
const schema =
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1297
|
+
const schema = React.useMemo(() => {
|
|
1298
|
+
var _a;
|
|
1299
|
+
const schema = (_a = specification.schema) !== null && _a !== void 0 ? _a : {};
|
|
1300
|
+
const tree = new SchemaTree(schema, { mergeAllOf: true, refResolver: null });
|
|
1301
|
+
tree.populate();
|
|
1302
|
+
return tree.root.children[0];
|
|
1303
|
+
}, [specification]);
|
|
1304
|
+
const { selectedChoice, choices, setSelectedChoice } = useChoices(schema);
|
|
1305
|
+
const formFieldRows = visibleChildren(selectedChoice.type);
|
|
1306
|
+
const onSchemaChange = (choice) => {
|
|
1307
|
+
onChangeValues({});
|
|
1308
|
+
setSelectedChoice(choice);
|
|
1309
|
+
};
|
|
1275
1310
|
return (React.createElement(Panel, { defaultIsOpen: true },
|
|
1276
|
-
React.createElement(Panel.Titlebar,
|
|
1277
|
-
React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" },
|
|
1278
|
-
|
|
1311
|
+
React.createElement(Panel.Titlebar, { rightComponent: React.createElement(OneOfMenu, { choices: choices, choice: selectedChoice, onChange: onSchemaChange }) }, "Body"),
|
|
1312
|
+
React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, formFieldRows
|
|
1313
|
+
.filter(isRegularNode)
|
|
1314
|
+
.map(toParameterSpec)
|
|
1315
|
+
.map(parameter => {
|
|
1316
|
+
var _a, _b;
|
|
1279
1317
|
const supportsFileUpload = parameterSupportsFileUpload(parameter);
|
|
1280
|
-
const value = values[parameter.name];
|
|
1318
|
+
const value = values[(_a = parameter.name) !== null && _a !== void 0 ? _a : ''];
|
|
1281
1319
|
if (supportsFileUpload) {
|
|
1282
1320
|
return (React.createElement(FileUploadParameterEditor, { key: parameter.name, parameter: parameter, value: value instanceof File ? value : undefined, onChange: newValue => newValue
|
|
1283
1321
|
? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
|
|
1284
1322
|
: onChangeValues(omit(values, parameter.name)) }));
|
|
1285
1323
|
}
|
|
1286
|
-
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: (
|
|
1324
|
+
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: (_b = isAllowedEmptyValues[parameter.name]) !== null && _b !== void 0 ? _b : false }));
|
|
1287
1325
|
}))));
|
|
1288
|
-
};
|
|
1326
|
+
};
|
|
1327
|
+
function OneOfMenu({ choices: subSchemas, choice, onChange }) {
|
|
1328
|
+
var _a;
|
|
1329
|
+
const onSubSchemaSelect = React.useCallback(onChange, [onChange]);
|
|
1330
|
+
const menuItems = React.useMemo(() => subSchemas.map(subSchema => {
|
|
1331
|
+
const label = subSchema.title;
|
|
1332
|
+
return {
|
|
1333
|
+
id: `request-subschema-${label}`,
|
|
1334
|
+
title: label,
|
|
1335
|
+
onPress: () => onSubSchemaSelect(subSchema),
|
|
1336
|
+
};
|
|
1337
|
+
}), [subSchemas, onSubSchemaSelect]);
|
|
1338
|
+
if (!subSchemas || subSchemas.length < 2) {
|
|
1339
|
+
return null;
|
|
1340
|
+
}
|
|
1341
|
+
const title = (_a = choice === null || choice === void 0 ? void 0 : choice.title) !== null && _a !== void 0 ? _a : 'Variants';
|
|
1342
|
+
return (React.createElement(Menu, { "aria-label": title, items: menuItems, renderTrigger: ({ isOpen }) => (React.createElement(Button, { appearance: "minimal", size: "sm", iconRight: ['fas', 'sort'], active: isOpen, "data-testid": "oneof-menu" }, title)) }));
|
|
1343
|
+
}
|
|
1289
1344
|
|
|
1290
1345
|
const fileToBase64 = (file) => new Promise((resolve, reject) => {
|
|
1291
1346
|
const reader = new FileReader();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stoplight/elements-core",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.14.0",
|
|
4
4
|
"main": "./index.js",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"web-components.min.js",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"@stoplight/json": "^3.18.1",
|
|
29
29
|
"@stoplight/json-schema-ref-parser": "^9.0.5",
|
|
30
30
|
"@stoplight/json-schema-sampler": "0.2.3",
|
|
31
|
-
"@stoplight/json-schema-
|
|
31
|
+
"@stoplight/json-schema-tree": "^2.2.5",
|
|
32
|
+
"@stoplight/json-schema-viewer": "^4.13.0",
|
|
32
33
|
"@stoplight/markdown-viewer": "^5.6.0",
|
|
33
34
|
"@stoplight/mosaic": "^1.44.4",
|
|
34
35
|
"@stoplight/mosaic-code-editor": "^1.44.4",
|