@stoplight/elements-core 9.0.12 → 9.0.13-alpha-0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/TableOfContents/types.d.ts +7 -0
- package/components/TryIt/Parameters/parameter-utils.d.ts +4 -4
- package/index.esm.js +134 -26
- package/index.js +134 -26
- package/index.mjs +134 -26
- package/package.json +1 -1
|
@@ -21,6 +21,7 @@ export declare type TableOfContentsGroup = {
|
|
|
21
21
|
title: string;
|
|
22
22
|
items: TableOfContentsGroupItem[];
|
|
23
23
|
itemsType?: 'article' | 'http_operation' | 'http_webhook' | 'model';
|
|
24
|
+
index: string;
|
|
24
25
|
};
|
|
25
26
|
export declare type TableOfContentsExternalLink = {
|
|
26
27
|
title: string;
|
|
@@ -33,5 +34,11 @@ export declare type TableOfContentsNode<T = 'http_service' | 'http_operation' |
|
|
|
33
34
|
type: T;
|
|
34
35
|
meta: string;
|
|
35
36
|
version?: string;
|
|
37
|
+
index: string;
|
|
36
38
|
};
|
|
37
39
|
export declare type TableOfContentsNodeGroup = TableOfContentsNode<'http_service'> & TableOfContentsGroup;
|
|
40
|
+
export declare type ActiveItemContextType = {
|
|
41
|
+
activeId: string | undefined;
|
|
42
|
+
lastActiveIndex: string;
|
|
43
|
+
setLastActiveIndex: React.Dispatch<React.SetStateAction<string>>;
|
|
44
|
+
};
|
|
@@ -4,12 +4,12 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema';
|
|
|
4
4
|
export declare type ParameterSpec = Pick<IHttpParam, 'name' | 'schema' | 'required'> & {
|
|
5
5
|
examples?: (Omit<INodeExample, 'id'> | Omit<INodeExternalExample, 'id'>)[];
|
|
6
6
|
};
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function encodeSafeSelectorValue(value: string | number): string | number;
|
|
8
|
+
export declare function decodeSafeSelectorValue(value: string | number): string | number;
|
|
9
|
+
export declare function parameterOptions(parameter: ParameterSpec): {
|
|
8
10
|
value: string | number;
|
|
9
|
-
} | {
|
|
10
11
|
label: string;
|
|
11
|
-
|
|
12
|
-
})[] | null;
|
|
12
|
+
}[] | null;
|
|
13
13
|
export declare const selectExampleOption: {
|
|
14
14
|
value: string;
|
|
15
15
|
label: string;
|
package/index.esm.js
CHANGED
|
@@ -1340,8 +1340,50 @@ const booleanOptions = [
|
|
|
1340
1340
|
{ label: 'False', value: 'false' },
|
|
1341
1341
|
{ label: 'True', value: 'true' },
|
|
1342
1342
|
];
|
|
1343
|
+
function encodeSafeSelectorValue(value) {
|
|
1344
|
+
if (typeof value === 'number') {
|
|
1345
|
+
return value;
|
|
1346
|
+
}
|
|
1347
|
+
const hasSpecialChars = /["'\[\]\\(){}]/.test(value);
|
|
1348
|
+
if (!hasSpecialChars) {
|
|
1349
|
+
return value;
|
|
1350
|
+
}
|
|
1351
|
+
try {
|
|
1352
|
+
return 'b64:' + btoa(value);
|
|
1353
|
+
}
|
|
1354
|
+
catch (e) {
|
|
1355
|
+
return 'enc:' + encodeURIComponent(value);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
function decodeSafeSelectorValue(value) {
|
|
1359
|
+
if (typeof value === 'number') {
|
|
1360
|
+
return value;
|
|
1361
|
+
}
|
|
1362
|
+
if (value.startsWith('b64:')) {
|
|
1363
|
+
try {
|
|
1364
|
+
return atob(value.substring(4));
|
|
1365
|
+
}
|
|
1366
|
+
catch (e) {
|
|
1367
|
+
return value;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
if (value.startsWith('enc:')) {
|
|
1371
|
+
try {
|
|
1372
|
+
return decodeURIComponent(value.substring(4));
|
|
1373
|
+
}
|
|
1374
|
+
catch (e) {
|
|
1375
|
+
return value;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
return value;
|
|
1379
|
+
}
|
|
1343
1380
|
function enumOptions(enumValues, required) {
|
|
1344
|
-
const options = map(enumValues, v =>
|
|
1381
|
+
const options = map(enumValues, v => {
|
|
1382
|
+
var _a;
|
|
1383
|
+
const stringValue = typeof v === 'object' && v !== null ? (_a = safeStringify(v)) !== null && _a !== void 0 ? _a : String(v) : typeof v === 'number' ? v : String(v);
|
|
1384
|
+
const safeValue = encodeSafeSelectorValue(stringValue);
|
|
1385
|
+
return { value: safeValue, label: String(stringValue) };
|
|
1386
|
+
});
|
|
1345
1387
|
return required ? options : [{ label: 'Not Set', value: '' }, ...options];
|
|
1346
1388
|
}
|
|
1347
1389
|
function parameterOptions(parameter) {
|
|
@@ -1371,15 +1413,16 @@ function parameterSupportsFileUpload(parameter) {
|
|
|
1371
1413
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1372
1414
|
}
|
|
1373
1415
|
function stringifyValue(value) {
|
|
1374
|
-
|
|
1416
|
+
var _a;
|
|
1417
|
+
if (typeof value === 'object' && value !== null) {
|
|
1418
|
+
return (_a = safeStringify(value)) !== null && _a !== void 0 ? _a : String(value);
|
|
1419
|
+
}
|
|
1420
|
+
return String(value);
|
|
1375
1421
|
}
|
|
1376
1422
|
function exampleValue(example) {
|
|
1377
1423
|
const value = 'value' in example ? example.value : example.externalValue;
|
|
1378
1424
|
return stringifyValue(value);
|
|
1379
1425
|
}
|
|
1380
|
-
function escapeQuotes(value) {
|
|
1381
|
-
return value.replace(/"/g, '\\"');
|
|
1382
|
-
}
|
|
1383
1426
|
function getPlaceholderForParameter(parameter) {
|
|
1384
1427
|
var _a, _b;
|
|
1385
1428
|
const { value: parameterValue, isDefault } = getValueForParameter(parameter);
|
|
@@ -1405,14 +1448,14 @@ const getValueForParameter = (parameter) => {
|
|
|
1405
1448
|
if (typeof defaultValue !== 'undefined') {
|
|
1406
1449
|
return { value: stringifyValue(defaultValue), isDefault: true };
|
|
1407
1450
|
}
|
|
1408
|
-
const
|
|
1409
|
-
if (examples.length > 0) {
|
|
1410
|
-
return { value: exampleValue(examples[0]) };
|
|
1411
|
-
}
|
|
1412
|
-
const enums = (_c = (_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.enum) !== null && _c !== void 0 ? _c : [];
|
|
1451
|
+
const enums = (_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.enum) !== null && _b !== void 0 ? _b : [];
|
|
1413
1452
|
if (enums.length > 0) {
|
|
1414
1453
|
return { value: stringifyValue(enums[0]) };
|
|
1415
1454
|
}
|
|
1455
|
+
const examples = (_c = parameter.examples) !== null && _c !== void 0 ? _c : [];
|
|
1456
|
+
if (examples.length > 0) {
|
|
1457
|
+
return { value: exampleValue(examples[0]) };
|
|
1458
|
+
}
|
|
1416
1459
|
return { value: '' };
|
|
1417
1460
|
};
|
|
1418
1461
|
const getInitialValueForParameter = (parameter) => {
|
|
@@ -1468,11 +1511,19 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
|
|
|
1468
1511
|
const examples = exampleOptions(parameter);
|
|
1469
1512
|
const selectedExample = (_a = examples === null || examples === void 0 ? void 0 : examples.find(e => e.value === value)) !== null && _a !== void 0 ? _a : selectExampleOption;
|
|
1470
1513
|
const parameterDisplayName = `${parameter.name}${parameter.required ? '*' : ''}`;
|
|
1514
|
+
const encodedValue = React.useMemo(() => {
|
|
1515
|
+
if (!value || !parameterValueOptions)
|
|
1516
|
+
return value || '';
|
|
1517
|
+
const matchingOption = parameterValueOptions.find(opt => {
|
|
1518
|
+
return String(decodeSafeSelectorValue(opt.value)) === value;
|
|
1519
|
+
});
|
|
1520
|
+
return matchingOption ? String(matchingOption.value) : value;
|
|
1521
|
+
}, [value, parameterValueOptions]);
|
|
1471
1522
|
const requiredButEmpty = validate && parameter.required && !value;
|
|
1472
1523
|
return (React.createElement(React.Fragment, null,
|
|
1473
1524
|
React.createElement(Text, { as: "label", "aria-hidden": "true", "data-testid": "param-label", htmlFor: inputId, fontSize: "base" }, parameterDisplayName),
|
|
1474
1525
|
React.createElement(Text, { mx: 3 }, ":"),
|
|
1475
|
-
React.createElement("div", null, parameterValueOptions ? (React.createElement(Select, { flex: 1, "aria-label": parameter.name, options: parameterValueOptions, value:
|
|
1526
|
+
React.createElement("div", null, parameterValueOptions ? (React.createElement(Select, { flex: 1, "aria-label": parameter.name, options: parameterValueOptions, value: encodedValue, onChange: val => onChange && onChange(String(decodeSafeSelectorValue(val))), placeholder: getPlaceholderForSelectedParameter(parameter) })) : (React.createElement(Flex, { flex: 1 },
|
|
1476
1527
|
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) }),
|
|
1477
1528
|
examples && (React.createElement(Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange }))))),
|
|
1478
1529
|
canChangeOptional && !parameter.required && (React.createElement(React.Fragment, null,
|
|
@@ -2327,10 +2378,17 @@ ServersDropdown.displayName = 'ServersDropdown';
|
|
|
2327
2378
|
|
|
2328
2379
|
const VariableEditor = ({ variable, value, onChange }) => {
|
|
2329
2380
|
const inputId = useUniqueId(`id_${variable.name}_`);
|
|
2381
|
+
const encodedOptions = React.useMemo(() => (variable.enum ? variable.enum.map(s => ({ value: encodeSafeSelectorValue(s), label: String(s) })) : []), [variable.enum]);
|
|
2382
|
+
const encodedValue = React.useMemo(() => {
|
|
2383
|
+
if (!value || !variable.enum)
|
|
2384
|
+
return value || variable.default;
|
|
2385
|
+
const matchingOption = encodedOptions.find(opt => decodeSafeSelectorValue(String(opt.value)) === value);
|
|
2386
|
+
return matchingOption ? String(matchingOption.value) : value;
|
|
2387
|
+
}, [value, variable.enum, variable.default, encodedOptions]);
|
|
2330
2388
|
return (React.createElement(React.Fragment, null,
|
|
2331
2389
|
React.createElement(Text, { as: "label", "aria-hidden": "true", "data-testid": "param-label", htmlFor: inputId, fontSize: "base" }, variable.name),
|
|
2332
2390
|
React.createElement(Text, { mx: 3 }, ":"),
|
|
2333
|
-
React.createElement("div", null, variable.enum ? (React.createElement(Select, { flex: 1, "aria-label": variable.name, options:
|
|
2391
|
+
React.createElement("div", null, variable.enum ? (React.createElement(Select, { flex: 1, "aria-label": variable.name, options: encodedOptions, value: encodedValue, onChange: val => onChange && onChange(decodeSafeSelectorValue(String(val))) })) : (React.createElement(Flex, { flex: 1 },
|
|
2334
2392
|
React.createElement(Input, { id: inputId, "aria-label": variable.name, appearance: 'minimal', flex: 1, placeholder: variable.default, type: "text", required: true, intent: 'default', value: value || '', onChange: e => onChange && onChange(e.currentTarget.value) }))))));
|
|
2335
2393
|
};
|
|
2336
2394
|
|
|
@@ -3496,7 +3554,7 @@ function findFirstNode(items) {
|
|
|
3496
3554
|
return;
|
|
3497
3555
|
}
|
|
3498
3556
|
function isDivider(item) {
|
|
3499
|
-
return Object.keys(item).length ===
|
|
3557
|
+
return Object.keys(item).length === 2 && 'title' in item && 'index' in item;
|
|
3500
3558
|
}
|
|
3501
3559
|
function isGroup(item) {
|
|
3502
3560
|
return Object.keys(item).length >= 2 && 'title' in item && 'items' in item;
|
|
@@ -3508,13 +3566,33 @@ function isNode(item) {
|
|
|
3508
3566
|
return 'title' in item && 'slug' in item && 'id' in item && 'meta' in item && 'type' in item;
|
|
3509
3567
|
}
|
|
3510
3568
|
function isExternalLink(item) {
|
|
3511
|
-
return Object.keys(item).length ===
|
|
3569
|
+
return Object.keys(item).length === 3 && 'title' in item && 'url' in item && 'index' in item;
|
|
3512
3570
|
}
|
|
3513
3571
|
|
|
3514
|
-
const
|
|
3572
|
+
const ActiveItemContext = React.createContext({
|
|
3573
|
+
activeId: undefined,
|
|
3574
|
+
lastActiveIndex: '',
|
|
3575
|
+
setLastActiveIndex: () => { },
|
|
3576
|
+
});
|
|
3515
3577
|
const LinkContext = React.createContext(undefined);
|
|
3516
3578
|
LinkContext.displayName = 'LinkContext';
|
|
3517
3579
|
const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, isInResponsiveMode = false, onLinkClick, }) => {
|
|
3580
|
+
const [lastActiveIndex, setLastActiveIndex] = useState('');
|
|
3581
|
+
const value = React.useMemo(() => ({
|
|
3582
|
+
lastActiveIndex,
|
|
3583
|
+
setLastActiveIndex,
|
|
3584
|
+
activeId,
|
|
3585
|
+
}), [lastActiveIndex, activeId]);
|
|
3586
|
+
const updateTocTree = React.useCallback((arr, parentId) => {
|
|
3587
|
+
return arr.map((item, key) => {
|
|
3588
|
+
let newItem = Object.assign(Object.assign({}, item), { index: parentId + key + '-' });
|
|
3589
|
+
if (isGroup(item) || isNodeGroup(item)) {
|
|
3590
|
+
newItem.items = updateTocTree(item.items, parentId + key + '-');
|
|
3591
|
+
}
|
|
3592
|
+
return newItem;
|
|
3593
|
+
});
|
|
3594
|
+
}, []);
|
|
3595
|
+
const updatedTree = updateTocTree(tree, '');
|
|
3518
3596
|
const container = React.useRef(null);
|
|
3519
3597
|
const child = React.useRef(null);
|
|
3520
3598
|
const firstRender = useFirstRender();
|
|
@@ -3534,18 +3612,30 @@ const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefaul
|
|
|
3534
3612
|
return (React.createElement(Box, { ref: container, w: "full", bg: isInResponsiveMode ? 'canvas' : 'canvas-100', overflowY: "auto" },
|
|
3535
3613
|
React.createElement(Box, { ref: child, my: 3 },
|
|
3536
3614
|
React.createElement(LinkContext.Provider, { value: Link },
|
|
3537
|
-
React.createElement(
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3615
|
+
React.createElement(ActiveItemContext.Provider, { value: value },
|
|
3616
|
+
React.createElement(TOCContainer, { updatedTree: updatedTree }, updatedTree.map((item, key) => {
|
|
3617
|
+
if (isDivider(item)) {
|
|
3618
|
+
return React.createElement(Divider, { key: key, item: item, isInResponsiveMode: isInResponsiveMode });
|
|
3619
|
+
}
|
|
3620
|
+
return (React.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3621
|
+
})))))));
|
|
3543
3622
|
});
|
|
3544
3623
|
TableOfContents.displayName = 'TableOfContents';
|
|
3545
3624
|
const Divider = React.memo(({ item, isInResponsiveMode = false }) => {
|
|
3546
3625
|
return (React.createElement(Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
|
|
3547
3626
|
});
|
|
3548
3627
|
Divider.displayName = 'Divider';
|
|
3628
|
+
const TOCContainer = React.memo(({ children, updatedTree }) => {
|
|
3629
|
+
const { setLastActiveIndex } = React.useContext(ActiveItemContext);
|
|
3630
|
+
React.useEffect(() => {
|
|
3631
|
+
const firstNode = findFirstNode(updatedTree);
|
|
3632
|
+
if (firstNode) {
|
|
3633
|
+
setLastActiveIndex(firstNode.index);
|
|
3634
|
+
}
|
|
3635
|
+
}, []);
|
|
3636
|
+
return React.createElement(Box, null, children);
|
|
3637
|
+
});
|
|
3638
|
+
TOCContainer.displayName = 'TOCContainer';
|
|
3549
3639
|
const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick }) => {
|
|
3550
3640
|
if (isExternalLink(item)) {
|
|
3551
3641
|
return (React.createElement(Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
|
|
@@ -3563,9 +3653,24 @@ const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsi
|
|
|
3563
3653
|
});
|
|
3564
3654
|
GroupItem.displayName = 'GroupItem';
|
|
3565
3655
|
const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick = () => { } }) => {
|
|
3566
|
-
const activeId = React.useContext(
|
|
3656
|
+
const { activeId, lastActiveIndex } = React.useContext(ActiveItemContext);
|
|
3567
3657
|
const [isOpen, setIsOpen] = React.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
|
|
3568
|
-
const
|
|
3658
|
+
const isActiveGroup = React.useCallback((items, activeId, contextIndex) => {
|
|
3659
|
+
return items.some(element => {
|
|
3660
|
+
const hasSlugOrId = 'slug' in element || 'id' in element;
|
|
3661
|
+
const hasItems = 'items' in element && Array.isArray(element.items);
|
|
3662
|
+
if (!hasSlugOrId && !hasItems)
|
|
3663
|
+
return false;
|
|
3664
|
+
if (activeId &&
|
|
3665
|
+
'index' in element &&
|
|
3666
|
+
(element.slug === activeId || element.id === activeId) &&
|
|
3667
|
+
element.index === contextIndex) {
|
|
3668
|
+
return true;
|
|
3669
|
+
}
|
|
3670
|
+
return hasItems ? isActiveGroup(element.items, activeId, contextIndex) : false;
|
|
3671
|
+
});
|
|
3672
|
+
}, []);
|
|
3673
|
+
const hasActive = isActiveGroup(item.items, activeId, lastActiveIndex);
|
|
3569
3674
|
React.useEffect(() => {
|
|
3570
3675
|
const openByDefault = isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
|
|
3571
3676
|
if (isOpen !== openByDefault) {
|
|
@@ -3615,8 +3720,10 @@ const Item = React.memo(({ depth, isActive, id, title, meta, icon, isInResponsiv
|
|
|
3615
3720
|
});
|
|
3616
3721
|
Item.displayName = 'Item';
|
|
3617
3722
|
const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, onClick, onLinkClick = () => { } }) => {
|
|
3618
|
-
const activeId = React.useContext(
|
|
3619
|
-
const
|
|
3723
|
+
const { activeId, lastActiveIndex, setLastActiveIndex } = React.useContext(ActiveItemContext);
|
|
3724
|
+
const { index } = item;
|
|
3725
|
+
const isSlugMatched = activeId === item.slug || activeId === item.id;
|
|
3726
|
+
const isActive = lastActiveIndex === index && isSlugMatched;
|
|
3620
3727
|
const LinkComponent = React.useContext(LinkContext);
|
|
3621
3728
|
const handleClick = (e) => {
|
|
3622
3729
|
if (isActive) {
|
|
@@ -3624,6 +3731,7 @@ const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
|
3624
3731
|
e.preventDefault();
|
|
3625
3732
|
}
|
|
3626
3733
|
else {
|
|
3734
|
+
setLastActiveIndex(index);
|
|
3627
3735
|
onLinkClick();
|
|
3628
3736
|
}
|
|
3629
3737
|
if (onClick) {
|
|
@@ -3631,7 +3739,7 @@ const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
|
3631
3739
|
}
|
|
3632
3740
|
};
|
|
3633
3741
|
return (React.createElement(Box, { as: LinkComponent, to: resolveRelativeLink(item.slug), display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
|
|
3634
|
-
React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
|
|
3742
|
+
React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: e => handleClick(e) })));
|
|
3635
3743
|
});
|
|
3636
3744
|
Node.displayName = 'Node';
|
|
3637
3745
|
const Version = ({ value }) => {
|
package/index.js
CHANGED
|
@@ -1361,8 +1361,50 @@ const booleanOptions = [
|
|
|
1361
1361
|
{ label: 'False', value: 'false' },
|
|
1362
1362
|
{ label: 'True', value: 'true' },
|
|
1363
1363
|
];
|
|
1364
|
+
function encodeSafeSelectorValue(value) {
|
|
1365
|
+
if (typeof value === 'number') {
|
|
1366
|
+
return value;
|
|
1367
|
+
}
|
|
1368
|
+
const hasSpecialChars = /["'\[\]\\(){}]/.test(value);
|
|
1369
|
+
if (!hasSpecialChars) {
|
|
1370
|
+
return value;
|
|
1371
|
+
}
|
|
1372
|
+
try {
|
|
1373
|
+
return 'b64:' + btoa(value);
|
|
1374
|
+
}
|
|
1375
|
+
catch (e) {
|
|
1376
|
+
return 'enc:' + encodeURIComponent(value);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
function decodeSafeSelectorValue(value) {
|
|
1380
|
+
if (typeof value === 'number') {
|
|
1381
|
+
return value;
|
|
1382
|
+
}
|
|
1383
|
+
if (value.startsWith('b64:')) {
|
|
1384
|
+
try {
|
|
1385
|
+
return atob(value.substring(4));
|
|
1386
|
+
}
|
|
1387
|
+
catch (e) {
|
|
1388
|
+
return value;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
if (value.startsWith('enc:')) {
|
|
1392
|
+
try {
|
|
1393
|
+
return decodeURIComponent(value.substring(4));
|
|
1394
|
+
}
|
|
1395
|
+
catch (e) {
|
|
1396
|
+
return value;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
return value;
|
|
1400
|
+
}
|
|
1364
1401
|
function enumOptions(enumValues, required) {
|
|
1365
|
-
const options = map(enumValues, v =>
|
|
1402
|
+
const options = map(enumValues, v => {
|
|
1403
|
+
var _a;
|
|
1404
|
+
const stringValue = typeof v === 'object' && v !== null ? (_a = json.safeStringify(v)) !== null && _a !== void 0 ? _a : String(v) : typeof v === 'number' ? v : String(v);
|
|
1405
|
+
const safeValue = encodeSafeSelectorValue(stringValue);
|
|
1406
|
+
return { value: safeValue, label: String(stringValue) };
|
|
1407
|
+
});
|
|
1366
1408
|
return required ? options : [{ label: 'Not Set', value: '' }, ...options];
|
|
1367
1409
|
}
|
|
1368
1410
|
function parameterOptions(parameter) {
|
|
@@ -1392,15 +1434,16 @@ function parameterSupportsFileUpload(parameter) {
|
|
|
1392
1434
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1393
1435
|
}
|
|
1394
1436
|
function stringifyValue(value) {
|
|
1395
|
-
|
|
1437
|
+
var _a;
|
|
1438
|
+
if (typeof value === 'object' && value !== null) {
|
|
1439
|
+
return (_a = json.safeStringify(value)) !== null && _a !== void 0 ? _a : String(value);
|
|
1440
|
+
}
|
|
1441
|
+
return String(value);
|
|
1396
1442
|
}
|
|
1397
1443
|
function exampleValue(example) {
|
|
1398
1444
|
const value = 'value' in example ? example.value : example.externalValue;
|
|
1399
1445
|
return stringifyValue(value);
|
|
1400
1446
|
}
|
|
1401
|
-
function escapeQuotes(value) {
|
|
1402
|
-
return value.replace(/"/g, '\\"');
|
|
1403
|
-
}
|
|
1404
1447
|
function getPlaceholderForParameter(parameter) {
|
|
1405
1448
|
var _a, _b;
|
|
1406
1449
|
const { value: parameterValue, isDefault } = getValueForParameter(parameter);
|
|
@@ -1426,14 +1469,14 @@ const getValueForParameter = (parameter) => {
|
|
|
1426
1469
|
if (typeof defaultValue !== 'undefined') {
|
|
1427
1470
|
return { value: stringifyValue(defaultValue), isDefault: true };
|
|
1428
1471
|
}
|
|
1429
|
-
const
|
|
1430
|
-
if (examples.length > 0) {
|
|
1431
|
-
return { value: exampleValue(examples[0]) };
|
|
1432
|
-
}
|
|
1433
|
-
const enums = (_c = (_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.enum) !== null && _c !== void 0 ? _c : [];
|
|
1472
|
+
const enums = (_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.enum) !== null && _b !== void 0 ? _b : [];
|
|
1434
1473
|
if (enums.length > 0) {
|
|
1435
1474
|
return { value: stringifyValue(enums[0]) };
|
|
1436
1475
|
}
|
|
1476
|
+
const examples = (_c = parameter.examples) !== null && _c !== void 0 ? _c : [];
|
|
1477
|
+
if (examples.length > 0) {
|
|
1478
|
+
return { value: exampleValue(examples[0]) };
|
|
1479
|
+
}
|
|
1437
1480
|
return { value: '' };
|
|
1438
1481
|
};
|
|
1439
1482
|
const getInitialValueForParameter = (parameter) => {
|
|
@@ -1489,11 +1532,19 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
|
|
|
1489
1532
|
const examples = exampleOptions(parameter);
|
|
1490
1533
|
const selectedExample = (_a = examples === null || examples === void 0 ? void 0 : examples.find(e => e.value === value)) !== null && _a !== void 0 ? _a : selectExampleOption;
|
|
1491
1534
|
const parameterDisplayName = `${parameter.name}${parameter.required ? '*' : ''}`;
|
|
1535
|
+
const encodedValue = React__namespace.useMemo(() => {
|
|
1536
|
+
if (!value || !parameterValueOptions)
|
|
1537
|
+
return value || '';
|
|
1538
|
+
const matchingOption = parameterValueOptions.find(opt => {
|
|
1539
|
+
return String(decodeSafeSelectorValue(opt.value)) === value;
|
|
1540
|
+
});
|
|
1541
|
+
return matchingOption ? String(matchingOption.value) : value;
|
|
1542
|
+
}, [value, parameterValueOptions]);
|
|
1492
1543
|
const requiredButEmpty = validate && parameter.required && !value;
|
|
1493
1544
|
return (React__namespace.createElement(React__namespace.Fragment, null,
|
|
1494
1545
|
React__namespace.createElement(mosaic.Text, { as: "label", "aria-hidden": "true", "data-testid": "param-label", htmlFor: inputId, fontSize: "base" }, parameterDisplayName),
|
|
1495
1546
|
React__namespace.createElement(mosaic.Text, { mx: 3 }, ":"),
|
|
1496
|
-
React__namespace.createElement("div", null, parameterValueOptions ? (React__namespace.createElement(mosaic.Select, { flex: 1, "aria-label": parameter.name, options: parameterValueOptions, value:
|
|
1547
|
+
React__namespace.createElement("div", null, parameterValueOptions ? (React__namespace.createElement(mosaic.Select, { flex: 1, "aria-label": parameter.name, options: parameterValueOptions, value: encodedValue, onChange: val => onChange && onChange(String(decodeSafeSelectorValue(val))), placeholder: getPlaceholderForSelectedParameter(parameter) })) : (React__namespace.createElement(mosaic.Flex, { flex: 1 },
|
|
1497
1548
|
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) }),
|
|
1498
1549
|
examples && (React__namespace.createElement(mosaic.Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange }))))),
|
|
1499
1550
|
canChangeOptional && !parameter.required && (React__namespace.createElement(React__namespace.Fragment, null,
|
|
@@ -2348,10 +2399,17 @@ ServersDropdown.displayName = 'ServersDropdown';
|
|
|
2348
2399
|
|
|
2349
2400
|
const VariableEditor = ({ variable, value, onChange }) => {
|
|
2350
2401
|
const inputId = useUniqueId(`id_${variable.name}_`);
|
|
2402
|
+
const encodedOptions = React__namespace.useMemo(() => (variable.enum ? variable.enum.map(s => ({ value: encodeSafeSelectorValue(s), label: String(s) })) : []), [variable.enum]);
|
|
2403
|
+
const encodedValue = React__namespace.useMemo(() => {
|
|
2404
|
+
if (!value || !variable.enum)
|
|
2405
|
+
return value || variable.default;
|
|
2406
|
+
const matchingOption = encodedOptions.find(opt => decodeSafeSelectorValue(String(opt.value)) === value);
|
|
2407
|
+
return matchingOption ? String(matchingOption.value) : value;
|
|
2408
|
+
}, [value, variable.enum, variable.default, encodedOptions]);
|
|
2351
2409
|
return (React__namespace.createElement(React__namespace.Fragment, null,
|
|
2352
2410
|
React__namespace.createElement(mosaic.Text, { as: "label", "aria-hidden": "true", "data-testid": "param-label", htmlFor: inputId, fontSize: "base" }, variable.name),
|
|
2353
2411
|
React__namespace.createElement(mosaic.Text, { mx: 3 }, ":"),
|
|
2354
|
-
React__namespace.createElement("div", null, variable.enum ? (React__namespace.createElement(mosaic.Select, { flex: 1, "aria-label": variable.name, options:
|
|
2412
|
+
React__namespace.createElement("div", null, variable.enum ? (React__namespace.createElement(mosaic.Select, { flex: 1, "aria-label": variable.name, options: encodedOptions, value: encodedValue, onChange: val => onChange && onChange(decodeSafeSelectorValue(String(val))) })) : (React__namespace.createElement(mosaic.Flex, { flex: 1 },
|
|
2355
2413
|
React__namespace.createElement(mosaic.Input, { id: inputId, "aria-label": variable.name, appearance: 'minimal', flex: 1, placeholder: variable.default, type: "text", required: true, intent: 'default', value: value || '', onChange: e => onChange && onChange(e.currentTarget.value) }))))));
|
|
2356
2414
|
};
|
|
2357
2415
|
|
|
@@ -3517,7 +3575,7 @@ function findFirstNode(items) {
|
|
|
3517
3575
|
return;
|
|
3518
3576
|
}
|
|
3519
3577
|
function isDivider(item) {
|
|
3520
|
-
return Object.keys(item).length ===
|
|
3578
|
+
return Object.keys(item).length === 2 && 'title' in item && 'index' in item;
|
|
3521
3579
|
}
|
|
3522
3580
|
function isGroup(item) {
|
|
3523
3581
|
return Object.keys(item).length >= 2 && 'title' in item && 'items' in item;
|
|
@@ -3529,13 +3587,33 @@ function isNode(item) {
|
|
|
3529
3587
|
return 'title' in item && 'slug' in item && 'id' in item && 'meta' in item && 'type' in item;
|
|
3530
3588
|
}
|
|
3531
3589
|
function isExternalLink(item) {
|
|
3532
|
-
return Object.keys(item).length ===
|
|
3590
|
+
return Object.keys(item).length === 3 && 'title' in item && 'url' in item && 'index' in item;
|
|
3533
3591
|
}
|
|
3534
3592
|
|
|
3535
|
-
const
|
|
3593
|
+
const ActiveItemContext = React__namespace.createContext({
|
|
3594
|
+
activeId: undefined,
|
|
3595
|
+
lastActiveIndex: '',
|
|
3596
|
+
setLastActiveIndex: () => { },
|
|
3597
|
+
});
|
|
3536
3598
|
const LinkContext = React__namespace.createContext(undefined);
|
|
3537
3599
|
LinkContext.displayName = 'LinkContext';
|
|
3538
3600
|
const TableOfContents = React__namespace.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, isInResponsiveMode = false, onLinkClick, }) => {
|
|
3601
|
+
const [lastActiveIndex, setLastActiveIndex] = React.useState('');
|
|
3602
|
+
const value = React__namespace.useMemo(() => ({
|
|
3603
|
+
lastActiveIndex,
|
|
3604
|
+
setLastActiveIndex,
|
|
3605
|
+
activeId,
|
|
3606
|
+
}), [lastActiveIndex, activeId]);
|
|
3607
|
+
const updateTocTree = React__namespace.useCallback((arr, parentId) => {
|
|
3608
|
+
return arr.map((item, key) => {
|
|
3609
|
+
let newItem = Object.assign(Object.assign({}, item), { index: parentId + key + '-' });
|
|
3610
|
+
if (isGroup(item) || isNodeGroup(item)) {
|
|
3611
|
+
newItem.items = updateTocTree(item.items, parentId + key + '-');
|
|
3612
|
+
}
|
|
3613
|
+
return newItem;
|
|
3614
|
+
});
|
|
3615
|
+
}, []);
|
|
3616
|
+
const updatedTree = updateTocTree(tree, '');
|
|
3539
3617
|
const container = React__namespace.useRef(null);
|
|
3540
3618
|
const child = React__namespace.useRef(null);
|
|
3541
3619
|
const firstRender = useFirstRender();
|
|
@@ -3555,18 +3633,30 @@ const TableOfContents = React__namespace.memo(({ tree, activeId, Link, maxDepthO
|
|
|
3555
3633
|
return (React__namespace.createElement(mosaic.Box, { ref: container, w: "full", bg: isInResponsiveMode ? 'canvas' : 'canvas-100', overflowY: "auto" },
|
|
3556
3634
|
React__namespace.createElement(mosaic.Box, { ref: child, my: 3 },
|
|
3557
3635
|
React__namespace.createElement(LinkContext.Provider, { value: Link },
|
|
3558
|
-
React__namespace.createElement(
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3636
|
+
React__namespace.createElement(ActiveItemContext.Provider, { value: value },
|
|
3637
|
+
React__namespace.createElement(TOCContainer, { updatedTree: updatedTree }, updatedTree.map((item, key) => {
|
|
3638
|
+
if (isDivider(item)) {
|
|
3639
|
+
return React__namespace.createElement(Divider, { key: key, item: item, isInResponsiveMode: isInResponsiveMode });
|
|
3640
|
+
}
|
|
3641
|
+
return (React__namespace.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3642
|
+
})))))));
|
|
3564
3643
|
});
|
|
3565
3644
|
TableOfContents.displayName = 'TableOfContents';
|
|
3566
3645
|
const Divider = React__namespace.memo(({ item, isInResponsiveMode = false }) => {
|
|
3567
3646
|
return (React__namespace.createElement(mosaic.Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
|
|
3568
3647
|
});
|
|
3569
3648
|
Divider.displayName = 'Divider';
|
|
3649
|
+
const TOCContainer = React__namespace.memo(({ children, updatedTree }) => {
|
|
3650
|
+
const { setLastActiveIndex } = React__namespace.useContext(ActiveItemContext);
|
|
3651
|
+
React__namespace.useEffect(() => {
|
|
3652
|
+
const firstNode = findFirstNode(updatedTree);
|
|
3653
|
+
if (firstNode) {
|
|
3654
|
+
setLastActiveIndex(firstNode.index);
|
|
3655
|
+
}
|
|
3656
|
+
}, []);
|
|
3657
|
+
return React__namespace.createElement(mosaic.Box, null, children);
|
|
3658
|
+
});
|
|
3659
|
+
TOCContainer.displayName = 'TOCContainer';
|
|
3570
3660
|
const GroupItem = React__namespace.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick }) => {
|
|
3571
3661
|
if (isExternalLink(item)) {
|
|
3572
3662
|
return (React__namespace.createElement(mosaic.Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
|
|
@@ -3584,9 +3674,24 @@ const GroupItem = React__namespace.memo(({ item, depth, maxDepthOpenByDefault, i
|
|
|
3584
3674
|
});
|
|
3585
3675
|
GroupItem.displayName = 'GroupItem';
|
|
3586
3676
|
const Group = React__namespace.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick = () => { } }) => {
|
|
3587
|
-
const activeId = React__namespace.useContext(
|
|
3677
|
+
const { activeId, lastActiveIndex } = React__namespace.useContext(ActiveItemContext);
|
|
3588
3678
|
const [isOpen, setIsOpen] = React__namespace.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
|
|
3589
|
-
const
|
|
3679
|
+
const isActiveGroup = React__namespace.useCallback((items, activeId, contextIndex) => {
|
|
3680
|
+
return items.some(element => {
|
|
3681
|
+
const hasSlugOrId = 'slug' in element || 'id' in element;
|
|
3682
|
+
const hasItems = 'items' in element && Array.isArray(element.items);
|
|
3683
|
+
if (!hasSlugOrId && !hasItems)
|
|
3684
|
+
return false;
|
|
3685
|
+
if (activeId &&
|
|
3686
|
+
'index' in element &&
|
|
3687
|
+
(element.slug === activeId || element.id === activeId) &&
|
|
3688
|
+
element.index === contextIndex) {
|
|
3689
|
+
return true;
|
|
3690
|
+
}
|
|
3691
|
+
return hasItems ? isActiveGroup(element.items, activeId, contextIndex) : false;
|
|
3692
|
+
});
|
|
3693
|
+
}, []);
|
|
3694
|
+
const hasActive = isActiveGroup(item.items, activeId, lastActiveIndex);
|
|
3590
3695
|
React__namespace.useEffect(() => {
|
|
3591
3696
|
const openByDefault = isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
|
|
3592
3697
|
if (isOpen !== openByDefault) {
|
|
@@ -3636,8 +3741,10 @@ const Item = React__namespace.memo(({ depth, isActive, id, title, meta, icon, is
|
|
|
3636
3741
|
});
|
|
3637
3742
|
Item.displayName = 'Item';
|
|
3638
3743
|
const Node = React__namespace.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, onClick, onLinkClick = () => { } }) => {
|
|
3639
|
-
const activeId = React__namespace.useContext(
|
|
3640
|
-
const
|
|
3744
|
+
const { activeId, lastActiveIndex, setLastActiveIndex } = React__namespace.useContext(ActiveItemContext);
|
|
3745
|
+
const { index } = item;
|
|
3746
|
+
const isSlugMatched = activeId === item.slug || activeId === item.id;
|
|
3747
|
+
const isActive = lastActiveIndex === index && isSlugMatched;
|
|
3641
3748
|
const LinkComponent = React__namespace.useContext(LinkContext);
|
|
3642
3749
|
const handleClick = (e) => {
|
|
3643
3750
|
if (isActive) {
|
|
@@ -3645,6 +3752,7 @@ const Node = React__namespace.memo(({ item, depth, meta, showAsActive, isInRespo
|
|
|
3645
3752
|
e.preventDefault();
|
|
3646
3753
|
}
|
|
3647
3754
|
else {
|
|
3755
|
+
setLastActiveIndex(index);
|
|
3648
3756
|
onLinkClick();
|
|
3649
3757
|
}
|
|
3650
3758
|
if (onClick) {
|
|
@@ -3652,7 +3760,7 @@ const Node = React__namespace.memo(({ item, depth, meta, showAsActive, isInRespo
|
|
|
3652
3760
|
}
|
|
3653
3761
|
};
|
|
3654
3762
|
return (React__namespace.createElement(mosaic.Box, { as: LinkComponent, to: resolveRelativeLink(item.slug), display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
|
|
3655
|
-
React__namespace.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
|
|
3763
|
+
React__namespace.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React__namespace.createElement(mosaic.Box, { as: mosaic.Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: e => handleClick(e) })));
|
|
3656
3764
|
});
|
|
3657
3765
|
Node.displayName = 'Node';
|
|
3658
3766
|
const Version = ({ value }) => {
|
package/index.mjs
CHANGED
|
@@ -1340,8 +1340,50 @@ const booleanOptions = [
|
|
|
1340
1340
|
{ label: 'False', value: 'false' },
|
|
1341
1341
|
{ label: 'True', value: 'true' },
|
|
1342
1342
|
];
|
|
1343
|
+
function encodeSafeSelectorValue(value) {
|
|
1344
|
+
if (typeof value === 'number') {
|
|
1345
|
+
return value;
|
|
1346
|
+
}
|
|
1347
|
+
const hasSpecialChars = /["'\[\]\\(){}]/.test(value);
|
|
1348
|
+
if (!hasSpecialChars) {
|
|
1349
|
+
return value;
|
|
1350
|
+
}
|
|
1351
|
+
try {
|
|
1352
|
+
return 'b64:' + btoa(value);
|
|
1353
|
+
}
|
|
1354
|
+
catch (e) {
|
|
1355
|
+
return 'enc:' + encodeURIComponent(value);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
function decodeSafeSelectorValue(value) {
|
|
1359
|
+
if (typeof value === 'number') {
|
|
1360
|
+
return value;
|
|
1361
|
+
}
|
|
1362
|
+
if (value.startsWith('b64:')) {
|
|
1363
|
+
try {
|
|
1364
|
+
return atob(value.substring(4));
|
|
1365
|
+
}
|
|
1366
|
+
catch (e) {
|
|
1367
|
+
return value;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
if (value.startsWith('enc:')) {
|
|
1371
|
+
try {
|
|
1372
|
+
return decodeURIComponent(value.substring(4));
|
|
1373
|
+
}
|
|
1374
|
+
catch (e) {
|
|
1375
|
+
return value;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
return value;
|
|
1379
|
+
}
|
|
1343
1380
|
function enumOptions(enumValues, required) {
|
|
1344
|
-
const options = map(enumValues, v =>
|
|
1381
|
+
const options = map(enumValues, v => {
|
|
1382
|
+
var _a;
|
|
1383
|
+
const stringValue = typeof v === 'object' && v !== null ? (_a = safeStringify(v)) !== null && _a !== void 0 ? _a : String(v) : typeof v === 'number' ? v : String(v);
|
|
1384
|
+
const safeValue = encodeSafeSelectorValue(stringValue);
|
|
1385
|
+
return { value: safeValue, label: String(stringValue) };
|
|
1386
|
+
});
|
|
1345
1387
|
return required ? options : [{ label: 'Not Set', value: '' }, ...options];
|
|
1346
1388
|
}
|
|
1347
1389
|
function parameterOptions(parameter) {
|
|
@@ -1371,15 +1413,16 @@ function parameterSupportsFileUpload(parameter) {
|
|
|
1371
1413
|
((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
|
|
1372
1414
|
}
|
|
1373
1415
|
function stringifyValue(value) {
|
|
1374
|
-
|
|
1416
|
+
var _a;
|
|
1417
|
+
if (typeof value === 'object' && value !== null) {
|
|
1418
|
+
return (_a = safeStringify(value)) !== null && _a !== void 0 ? _a : String(value);
|
|
1419
|
+
}
|
|
1420
|
+
return String(value);
|
|
1375
1421
|
}
|
|
1376
1422
|
function exampleValue(example) {
|
|
1377
1423
|
const value = 'value' in example ? example.value : example.externalValue;
|
|
1378
1424
|
return stringifyValue(value);
|
|
1379
1425
|
}
|
|
1380
|
-
function escapeQuotes(value) {
|
|
1381
|
-
return value.replace(/"/g, '\\"');
|
|
1382
|
-
}
|
|
1383
1426
|
function getPlaceholderForParameter(parameter) {
|
|
1384
1427
|
var _a, _b;
|
|
1385
1428
|
const { value: parameterValue, isDefault } = getValueForParameter(parameter);
|
|
@@ -1405,14 +1448,14 @@ const getValueForParameter = (parameter) => {
|
|
|
1405
1448
|
if (typeof defaultValue !== 'undefined') {
|
|
1406
1449
|
return { value: stringifyValue(defaultValue), isDefault: true };
|
|
1407
1450
|
}
|
|
1408
|
-
const
|
|
1409
|
-
if (examples.length > 0) {
|
|
1410
|
-
return { value: exampleValue(examples[0]) };
|
|
1411
|
-
}
|
|
1412
|
-
const enums = (_c = (_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.enum) !== null && _c !== void 0 ? _c : [];
|
|
1451
|
+
const enums = (_b = (_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.enum) !== null && _b !== void 0 ? _b : [];
|
|
1413
1452
|
if (enums.length > 0) {
|
|
1414
1453
|
return { value: stringifyValue(enums[0]) };
|
|
1415
1454
|
}
|
|
1455
|
+
const examples = (_c = parameter.examples) !== null && _c !== void 0 ? _c : [];
|
|
1456
|
+
if (examples.length > 0) {
|
|
1457
|
+
return { value: exampleValue(examples[0]) };
|
|
1458
|
+
}
|
|
1416
1459
|
return { value: '' };
|
|
1417
1460
|
};
|
|
1418
1461
|
const getInitialValueForParameter = (parameter) => {
|
|
@@ -1468,11 +1511,19 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
|
|
|
1468
1511
|
const examples = exampleOptions(parameter);
|
|
1469
1512
|
const selectedExample = (_a = examples === null || examples === void 0 ? void 0 : examples.find(e => e.value === value)) !== null && _a !== void 0 ? _a : selectExampleOption;
|
|
1470
1513
|
const parameterDisplayName = `${parameter.name}${parameter.required ? '*' : ''}`;
|
|
1514
|
+
const encodedValue = React.useMemo(() => {
|
|
1515
|
+
if (!value || !parameterValueOptions)
|
|
1516
|
+
return value || '';
|
|
1517
|
+
const matchingOption = parameterValueOptions.find(opt => {
|
|
1518
|
+
return String(decodeSafeSelectorValue(opt.value)) === value;
|
|
1519
|
+
});
|
|
1520
|
+
return matchingOption ? String(matchingOption.value) : value;
|
|
1521
|
+
}, [value, parameterValueOptions]);
|
|
1471
1522
|
const requiredButEmpty = validate && parameter.required && !value;
|
|
1472
1523
|
return (React.createElement(React.Fragment, null,
|
|
1473
1524
|
React.createElement(Text, { as: "label", "aria-hidden": "true", "data-testid": "param-label", htmlFor: inputId, fontSize: "base" }, parameterDisplayName),
|
|
1474
1525
|
React.createElement(Text, { mx: 3 }, ":"),
|
|
1475
|
-
React.createElement("div", null, parameterValueOptions ? (React.createElement(Select, { flex: 1, "aria-label": parameter.name, options: parameterValueOptions, value:
|
|
1526
|
+
React.createElement("div", null, parameterValueOptions ? (React.createElement(Select, { flex: 1, "aria-label": parameter.name, options: parameterValueOptions, value: encodedValue, onChange: val => onChange && onChange(String(decodeSafeSelectorValue(val))), placeholder: getPlaceholderForSelectedParameter(parameter) })) : (React.createElement(Flex, { flex: 1 },
|
|
1476
1527
|
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) }),
|
|
1477
1528
|
examples && (React.createElement(Select, { "aria-label": `${parameter.name}-select`, flex: 1, value: selectedExample.value, options: examples, onChange: onChange }))))),
|
|
1478
1529
|
canChangeOptional && !parameter.required && (React.createElement(React.Fragment, null,
|
|
@@ -2327,10 +2378,17 @@ ServersDropdown.displayName = 'ServersDropdown';
|
|
|
2327
2378
|
|
|
2328
2379
|
const VariableEditor = ({ variable, value, onChange }) => {
|
|
2329
2380
|
const inputId = useUniqueId(`id_${variable.name}_`);
|
|
2381
|
+
const encodedOptions = React.useMemo(() => (variable.enum ? variable.enum.map(s => ({ value: encodeSafeSelectorValue(s), label: String(s) })) : []), [variable.enum]);
|
|
2382
|
+
const encodedValue = React.useMemo(() => {
|
|
2383
|
+
if (!value || !variable.enum)
|
|
2384
|
+
return value || variable.default;
|
|
2385
|
+
const matchingOption = encodedOptions.find(opt => decodeSafeSelectorValue(String(opt.value)) === value);
|
|
2386
|
+
return matchingOption ? String(matchingOption.value) : value;
|
|
2387
|
+
}, [value, variable.enum, variable.default, encodedOptions]);
|
|
2330
2388
|
return (React.createElement(React.Fragment, null,
|
|
2331
2389
|
React.createElement(Text, { as: "label", "aria-hidden": "true", "data-testid": "param-label", htmlFor: inputId, fontSize: "base" }, variable.name),
|
|
2332
2390
|
React.createElement(Text, { mx: 3 }, ":"),
|
|
2333
|
-
React.createElement("div", null, variable.enum ? (React.createElement(Select, { flex: 1, "aria-label": variable.name, options:
|
|
2391
|
+
React.createElement("div", null, variable.enum ? (React.createElement(Select, { flex: 1, "aria-label": variable.name, options: encodedOptions, value: encodedValue, onChange: val => onChange && onChange(decodeSafeSelectorValue(String(val))) })) : (React.createElement(Flex, { flex: 1 },
|
|
2334
2392
|
React.createElement(Input, { id: inputId, "aria-label": variable.name, appearance: 'minimal', flex: 1, placeholder: variable.default, type: "text", required: true, intent: 'default', value: value || '', onChange: e => onChange && onChange(e.currentTarget.value) }))))));
|
|
2335
2393
|
};
|
|
2336
2394
|
|
|
@@ -3496,7 +3554,7 @@ function findFirstNode(items) {
|
|
|
3496
3554
|
return;
|
|
3497
3555
|
}
|
|
3498
3556
|
function isDivider(item) {
|
|
3499
|
-
return Object.keys(item).length ===
|
|
3557
|
+
return Object.keys(item).length === 2 && 'title' in item && 'index' in item;
|
|
3500
3558
|
}
|
|
3501
3559
|
function isGroup(item) {
|
|
3502
3560
|
return Object.keys(item).length >= 2 && 'title' in item && 'items' in item;
|
|
@@ -3508,13 +3566,33 @@ function isNode(item) {
|
|
|
3508
3566
|
return 'title' in item && 'slug' in item && 'id' in item && 'meta' in item && 'type' in item;
|
|
3509
3567
|
}
|
|
3510
3568
|
function isExternalLink(item) {
|
|
3511
|
-
return Object.keys(item).length ===
|
|
3569
|
+
return Object.keys(item).length === 3 && 'title' in item && 'url' in item && 'index' in item;
|
|
3512
3570
|
}
|
|
3513
3571
|
|
|
3514
|
-
const
|
|
3572
|
+
const ActiveItemContext = React.createContext({
|
|
3573
|
+
activeId: undefined,
|
|
3574
|
+
lastActiveIndex: '',
|
|
3575
|
+
setLastActiveIndex: () => { },
|
|
3576
|
+
});
|
|
3515
3577
|
const LinkContext = React.createContext(undefined);
|
|
3516
3578
|
LinkContext.displayName = 'LinkContext';
|
|
3517
3579
|
const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefault, externalScrollbar = false, isInResponsiveMode = false, onLinkClick, }) => {
|
|
3580
|
+
const [lastActiveIndex, setLastActiveIndex] = useState('');
|
|
3581
|
+
const value = React.useMemo(() => ({
|
|
3582
|
+
lastActiveIndex,
|
|
3583
|
+
setLastActiveIndex,
|
|
3584
|
+
activeId,
|
|
3585
|
+
}), [lastActiveIndex, activeId]);
|
|
3586
|
+
const updateTocTree = React.useCallback((arr, parentId) => {
|
|
3587
|
+
return arr.map((item, key) => {
|
|
3588
|
+
let newItem = Object.assign(Object.assign({}, item), { index: parentId + key + '-' });
|
|
3589
|
+
if (isGroup(item) || isNodeGroup(item)) {
|
|
3590
|
+
newItem.items = updateTocTree(item.items, parentId + key + '-');
|
|
3591
|
+
}
|
|
3592
|
+
return newItem;
|
|
3593
|
+
});
|
|
3594
|
+
}, []);
|
|
3595
|
+
const updatedTree = updateTocTree(tree, '');
|
|
3518
3596
|
const container = React.useRef(null);
|
|
3519
3597
|
const child = React.useRef(null);
|
|
3520
3598
|
const firstRender = useFirstRender();
|
|
@@ -3534,18 +3612,30 @@ const TableOfContents = React.memo(({ tree, activeId, Link, maxDepthOpenByDefaul
|
|
|
3534
3612
|
return (React.createElement(Box, { ref: container, w: "full", bg: isInResponsiveMode ? 'canvas' : 'canvas-100', overflowY: "auto" },
|
|
3535
3613
|
React.createElement(Box, { ref: child, my: 3 },
|
|
3536
3614
|
React.createElement(LinkContext.Provider, { value: Link },
|
|
3537
|
-
React.createElement(
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3615
|
+
React.createElement(ActiveItemContext.Provider, { value: value },
|
|
3616
|
+
React.createElement(TOCContainer, { updatedTree: updatedTree }, updatedTree.map((item, key) => {
|
|
3617
|
+
if (isDivider(item)) {
|
|
3618
|
+
return React.createElement(Divider, { key: key, item: item, isInResponsiveMode: isInResponsiveMode });
|
|
3619
|
+
}
|
|
3620
|
+
return (React.createElement(GroupItem, { key: key, item: item, depth: 0, maxDepthOpenByDefault: maxDepthOpenByDefault, onLinkClick: onLinkClick, isInResponsiveMode: isInResponsiveMode }));
|
|
3621
|
+
})))))));
|
|
3543
3622
|
});
|
|
3544
3623
|
TableOfContents.displayName = 'TableOfContents';
|
|
3545
3624
|
const Divider = React.memo(({ item, isInResponsiveMode = false }) => {
|
|
3546
3625
|
return (React.createElement(Box, { pl: 4, mb: 2, mt: 6, textTransform: "uppercase", fontSize: isInResponsiveMode ? 'lg' : 'sm', lineHeight: "relaxed", letterSpacing: "wide", fontWeight: "bold" }, item.title));
|
|
3547
3626
|
});
|
|
3548
3627
|
Divider.displayName = 'Divider';
|
|
3628
|
+
const TOCContainer = React.memo(({ children, updatedTree }) => {
|
|
3629
|
+
const { setLastActiveIndex } = React.useContext(ActiveItemContext);
|
|
3630
|
+
React.useEffect(() => {
|
|
3631
|
+
const firstNode = findFirstNode(updatedTree);
|
|
3632
|
+
if (firstNode) {
|
|
3633
|
+
setLastActiveIndex(firstNode.index);
|
|
3634
|
+
}
|
|
3635
|
+
}, []);
|
|
3636
|
+
return React.createElement(Box, null, children);
|
|
3637
|
+
});
|
|
3638
|
+
TOCContainer.displayName = 'TOCContainer';
|
|
3549
3639
|
const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick }) => {
|
|
3550
3640
|
if (isExternalLink(item)) {
|
|
3551
3641
|
return (React.createElement(Box, { as: "a", href: item.url, target: "_blank", rel: "noopener noreferrer", display: "block" },
|
|
@@ -3563,9 +3653,24 @@ const GroupItem = React.memo(({ item, depth, maxDepthOpenByDefault, isInResponsi
|
|
|
3563
3653
|
});
|
|
3564
3654
|
GroupItem.displayName = 'GroupItem';
|
|
3565
3655
|
const Group = React.memo(({ depth, item, maxDepthOpenByDefault, isInResponsiveMode, onLinkClick = () => { } }) => {
|
|
3566
|
-
const activeId = React.useContext(
|
|
3656
|
+
const { activeId, lastActiveIndex } = React.useContext(ActiveItemContext);
|
|
3567
3657
|
const [isOpen, setIsOpen] = React.useState(() => isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault));
|
|
3568
|
-
const
|
|
3658
|
+
const isActiveGroup = React.useCallback((items, activeId, contextIndex) => {
|
|
3659
|
+
return items.some(element => {
|
|
3660
|
+
const hasSlugOrId = 'slug' in element || 'id' in element;
|
|
3661
|
+
const hasItems = 'items' in element && Array.isArray(element.items);
|
|
3662
|
+
if (!hasSlugOrId && !hasItems)
|
|
3663
|
+
return false;
|
|
3664
|
+
if (activeId &&
|
|
3665
|
+
'index' in element &&
|
|
3666
|
+
(element.slug === activeId || element.id === activeId) &&
|
|
3667
|
+
element.index === contextIndex) {
|
|
3668
|
+
return true;
|
|
3669
|
+
}
|
|
3670
|
+
return hasItems ? isActiveGroup(element.items, activeId, contextIndex) : false;
|
|
3671
|
+
});
|
|
3672
|
+
}, []);
|
|
3673
|
+
const hasActive = isActiveGroup(item.items, activeId, lastActiveIndex);
|
|
3569
3674
|
React.useEffect(() => {
|
|
3570
3675
|
const openByDefault = isGroupOpenByDefault(depth, item, activeId, maxDepthOpenByDefault);
|
|
3571
3676
|
if (isOpen !== openByDefault) {
|
|
@@ -3615,8 +3720,10 @@ const Item = React.memo(({ depth, isActive, id, title, meta, icon, isInResponsiv
|
|
|
3615
3720
|
});
|
|
3616
3721
|
Item.displayName = 'Item';
|
|
3617
3722
|
const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode, onClick, onLinkClick = () => { } }) => {
|
|
3618
|
-
const activeId = React.useContext(
|
|
3619
|
-
const
|
|
3723
|
+
const { activeId, lastActiveIndex, setLastActiveIndex } = React.useContext(ActiveItemContext);
|
|
3724
|
+
const { index } = item;
|
|
3725
|
+
const isSlugMatched = activeId === item.slug || activeId === item.id;
|
|
3726
|
+
const isActive = lastActiveIndex === index && isSlugMatched;
|
|
3620
3727
|
const LinkComponent = React.useContext(LinkContext);
|
|
3621
3728
|
const handleClick = (e) => {
|
|
3622
3729
|
if (isActive) {
|
|
@@ -3624,6 +3731,7 @@ const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
|
3624
3731
|
e.preventDefault();
|
|
3625
3732
|
}
|
|
3626
3733
|
else {
|
|
3734
|
+
setLastActiveIndex(index);
|
|
3627
3735
|
onLinkClick();
|
|
3628
3736
|
}
|
|
3629
3737
|
if (onClick) {
|
|
@@ -3631,7 +3739,7 @@ const Node = React.memo(({ item, depth, meta, showAsActive, isInResponsiveMode,
|
|
|
3631
3739
|
}
|
|
3632
3740
|
};
|
|
3633
3741
|
return (React.createElement(Box, { as: LinkComponent, to: resolveRelativeLink(item.slug), display: "block", textDecoration: "no-underline", className: "ElementsTableOfContentsItem" },
|
|
3634
|
-
React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: handleClick })));
|
|
3742
|
+
React.createElement(Item, { id: getHtmlIdFromItemId(item.slug || item.id), isActive: isActive || showAsActive, depth: depth, title: item.title, icon: NODE_TYPE_TITLE_ICON[item.type] && (React.createElement(Box, { as: Icon, color: NODE_TYPE_ICON_COLOR[item.type], icon: NODE_TYPE_TITLE_ICON[item.type] })), meta: meta, isInResponsiveMode: isInResponsiveMode, onClick: e => handleClick(e) })));
|
|
3635
3743
|
});
|
|
3636
3744
|
Node.displayName = 'Node';
|
|
3637
3745
|
const Version = ({ value }) => {
|