@stoplight/elements-core 8.1.4 → 8.3.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/index.js CHANGED
@@ -19,7 +19,11 @@ var cn = require('classnames');
19
19
  var utils = require('jotai/utils');
20
20
  var jotai = require('jotai');
21
21
  var URI = require('urijs');
22
+ var isString = require('lodash/isString.js');
22
23
  var mosaicCodeViewer = require('@stoplight/mosaic-code-viewer');
24
+ var cloneDeep = require('lodash/cloneDeep.js');
25
+ var find = require('lodash/find.js');
26
+ var findKey = require('lodash/findKey.js');
23
27
  var httpsnippetLite = require('httpsnippet-lite');
24
28
  var hash = require('@stoplight/http-spec/hash');
25
29
  var capitalize = require('lodash/capitalize.js');
@@ -34,7 +38,6 @@ var keyBy = require('lodash/keyBy.js');
34
38
  var last = require('lodash/last.js');
35
39
  var map = require('lodash/map.js');
36
40
  var mapValues = require('lodash/mapValues.js');
37
- var isString = require('lodash/isString.js');
38
41
  var pickBy = require('lodash/pickBy.js');
39
42
  var mosaicCodeEditor = require('@stoplight/mosaic-code-editor');
40
43
  var Sampler = require('@stoplight/json-schema-sampler');
@@ -43,6 +46,7 @@ var uniq = require('lodash/uniq.js');
43
46
  var orderBy = require('lodash/orderBy.js');
44
47
  var uniqBy = require('lodash/uniqBy.js');
45
48
  var formatXml = require('xml-formatter');
49
+ var memoize = require('lodash/memoize.js');
46
50
  var entries = require('lodash/entries.js');
47
51
  var keys = require('lodash/keys.js');
48
52
  var sortBy = require('lodash/sortBy.js');
@@ -83,6 +87,10 @@ var isPlainObject__default = /*#__PURE__*/_interopDefaultLegacy(isPlainObject);
83
87
  var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
84
88
  var cn__default = /*#__PURE__*/_interopDefaultLegacy(cn);
85
89
  var URI__default = /*#__PURE__*/_interopDefaultLegacy(URI);
90
+ var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
91
+ var cloneDeep__default = /*#__PURE__*/_interopDefaultLegacy(cloneDeep);
92
+ var find__default = /*#__PURE__*/_interopDefaultLegacy(find);
93
+ var findKey__default = /*#__PURE__*/_interopDefaultLegacy(findKey);
86
94
  var capitalize__default = /*#__PURE__*/_interopDefaultLegacy(capitalize);
87
95
  var filter__default = /*#__PURE__*/_interopDefaultLegacy(filter);
88
96
  var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
@@ -92,7 +100,6 @@ var keyBy__default = /*#__PURE__*/_interopDefaultLegacy(keyBy);
92
100
  var last__default = /*#__PURE__*/_interopDefaultLegacy(last);
93
101
  var map__default = /*#__PURE__*/_interopDefaultLegacy(map);
94
102
  var mapValues__default = /*#__PURE__*/_interopDefaultLegacy(mapValues);
95
- var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
96
103
  var pickBy__default = /*#__PURE__*/_interopDefaultLegacy(pickBy);
97
104
  var Sampler__namespace = /*#__PURE__*/_interopNamespace(Sampler);
98
105
  var compact__default = /*#__PURE__*/_interopDefaultLegacy(compact);
@@ -100,6 +107,7 @@ var uniq__default = /*#__PURE__*/_interopDefaultLegacy(uniq);
100
107
  var orderBy__default = /*#__PURE__*/_interopDefaultLegacy(orderBy);
101
108
  var uniqBy__default = /*#__PURE__*/_interopDefaultLegacy(uniqBy);
102
109
  var formatXml__default = /*#__PURE__*/_interopDefaultLegacy(formatXml);
110
+ var memoize__default = /*#__PURE__*/_interopDefaultLegacy(memoize);
103
111
  var entries__default = /*#__PURE__*/_interopDefaultLegacy(entries);
104
112
  var keys__default = /*#__PURE__*/_interopDefaultLegacy(keys);
105
113
  var sortBy__default = /*#__PURE__*/_interopDefaultLegacy(sortBy);
@@ -218,8 +226,8 @@ const ElementsOptionsContext = React__namespace.createContext(DEFAULT_CONTEXT);
218
226
  const useOptionsCtx = () => {
219
227
  return React__namespace.useContext(ElementsOptionsContext) || DEFAULT_CONTEXT;
220
228
  };
221
- function ElementsOptionsProvider({ children, nodeHasChanged }) {
222
- return (React__namespace.createElement(ElementsOptionsContext.Provider, { value: Object.assign({}, DEFAULT_CONTEXT, { nodeHasChanged }) }, children));
229
+ function ElementsOptionsProvider({ children, nodeHasChanged, renderExtensionAddon }) {
230
+ return (React__namespace.createElement(ElementsOptionsContext.Provider, { value: Object.assign({}, DEFAULT_CONTEXT, { nodeHasChanged, renderExtensionAddon }) }, children));
223
231
  }
224
232
 
225
233
  function isSMDASTRoot(maybeAst) {
@@ -504,6 +512,9 @@ const HttpMethodColors = {
504
512
  put: 'warning',
505
513
  patch: 'warning',
506
514
  delete: 'danger',
515
+ head: '#9061F9',
516
+ options: '#0D5AA7',
517
+ trace: '#0D0B28',
507
518
  };
508
519
  const HttpCodeColor = {
509
520
  0: 'red',
@@ -677,6 +688,29 @@ const getServerUrlWithVariableValues = (server, values) => {
677
688
  return urlString;
678
689
  };
679
690
 
691
+ const extractCodeSamples = (obj) => {
692
+ if (!json.isPlainObject(obj) || !json.isPlainObject(obj.extensions)) {
693
+ return [];
694
+ }
695
+ const codeSamples = obj.extensions['x-codeSamples'];
696
+ if (!Array.isArray(codeSamples)) {
697
+ return [];
698
+ }
699
+ return codeSamples.reduce((extracted, item) => {
700
+ if (json.isPlainObject(item) && isString__default["default"](item['lang']) && isString__default["default"](item['source'])) {
701
+ const lib = isString__default["default"](item['lib']) ? item['lib'] : undefined;
702
+ const label = isString__default["default"](item['label']) ? item['label'] : lib !== null && lib !== void 0 ? lib : item['lang'];
703
+ extracted.push({
704
+ lang: item['lang'],
705
+ lib,
706
+ label,
707
+ source: item['source'],
708
+ });
709
+ }
710
+ return extracted;
711
+ }, []);
712
+ };
713
+
680
714
  const persistAtom = (key, atomInstance) => {
681
715
  if (typeof window === 'undefined' || window.localStorage === undefined) {
682
716
  return atomInstance;
@@ -882,76 +916,149 @@ const requestSampleConfigs = {
882
916
  mosaicCodeViewerLanguage: 'swift',
883
917
  httpSnippetLanguage: 'swift',
884
918
  },
885
- };
886
- const getConfigFor = (language, library) => {
887
- var _a;
888
- const languageConfig = requestSampleConfigs[language];
889
- const libraryConfig = ((_a = languageConfig.libraries) === null || _a === void 0 ? void 0 : _a[library]) || {};
890
- return Object.assign(Object.assign({}, languageConfig), libraryConfig);
891
919
  };
892
920
 
893
- const selectedLanguageAtom = persistAtom('RequestSamples_selectedLanguage', jotai.atom('Shell'));
894
- const selectedLibraryAtom = persistAtom('RequestSamples_selectedLibrary', jotai.atom('cURL'));
921
+ const selectedLanguageAtom = persistAtom('RequestSamples_selectedLanguage', jotai.atom('shell'));
922
+ const selectedLibraryAtom = persistAtom('RequestSamples_selectedLibrary', jotai.atom('curl'));
895
923
  const fallbackText = 'Unable to generate code example';
896
- const RequestSamples = React__default["default"].memo(({ request, embeddedInMd = false }) => {
924
+ const RequestSamples = React.memo(({ request, embeddedInMd = false, customCodeSamples = [] }) => {
897
925
  const [selectedLanguage, setSelectedLanguage] = jotai.useAtom(selectedLanguageAtom);
898
926
  const [selectedLibrary, setSelectedLibrary] = jotai.useAtom(selectedLibraryAtom);
899
- const { httpSnippetLanguage, httpSnippetLibrary, mosaicCodeViewerLanguage } = getConfigFor(selectedLanguage, selectedLibrary);
900
- const [requestSample, setRequestSample] = React__default["default"].useState(null);
901
- React__default["default"].useEffect(() => {
902
- let isStale = false;
903
- convertRequestToSample(httpSnippetLanguage, httpSnippetLibrary, request)
904
- .then(example => {
905
- if (!isStale) {
906
- setRequestSample(example);
927
+ const allRequestSamples = React.useMemo(() => {
928
+ var _a;
929
+ const requestSamples = cloneDeep__default["default"](requestSampleConfigs);
930
+ Object.entries(requestSamples).forEach(([languageKey, value]) => {
931
+ var _a;
932
+ value.displayText = languageKey;
933
+ Object.entries(((_a = value.libraries) !== null && _a !== void 0 ? _a : (value.libraries = {}))).forEach(([libKey, value]) => {
934
+ value.displayText = `${languageKey} / ${libKey}`;
935
+ });
936
+ });
937
+ for (const customCodeSample of customCodeSamples) {
938
+ const existingLanguageSampleKey = findKey__default["default"](requestSamples, {
939
+ httpSnippetLanguage: customCodeSample.lang.toLowerCase(),
940
+ });
941
+ const existingLanguageSample = requestSamples[existingLanguageSampleKey];
942
+ if (!existingLanguageSample) {
943
+ const newLanguageSample = {
944
+ displayText: customCodeSample.lang,
945
+ mosaicCodeViewerLanguage: customCodeSample.lang,
946
+ httpSnippetLanguage: customCodeSample.lang,
947
+ libraries: {},
948
+ };
949
+ if (customCodeSample.lib) {
950
+ newLanguageSample.libraries[customCodeSample.lib] = {
951
+ displayText: `${customCodeSample.lang} / ${customCodeSample.lib}`,
952
+ httpSnippetLibrary: customCodeSample.lib,
953
+ sampleCode: customCodeSample.source,
954
+ };
955
+ }
956
+ else {
957
+ newLanguageSample.sampleCode = customCodeSample.source;
958
+ }
959
+ requestSamples[customCodeSample.label] = newLanguageSample;
907
960
  }
908
- })
909
- .catch(() => {
910
- if (!isStale) {
911
- setRequestSample(fallbackText);
961
+ else {
962
+ (_a = existingLanguageSample.libraries) !== null && _a !== void 0 ? _a : (existingLanguageSample.libraries = {});
963
+ if (customCodeSample.lib) {
964
+ const existingLibrarySampleKey = findKey__default["default"](existingLanguageSample.libraries, {
965
+ httpSnippetLibrary: customCodeSample.lib,
966
+ });
967
+ const existingLibrarySample = existingLanguageSample.libraries[existingLibrarySampleKey];
968
+ if (!existingLibrarySample) {
969
+ const newLibrarySample = {
970
+ displayText: `${existingLanguageSample} / ${customCodeSample.lib}`,
971
+ httpSnippetLibrary: customCodeSample.lib,
972
+ sampleCode: customCodeSample.source,
973
+ };
974
+ existingLanguageSample.libraries[customCodeSample.lib] = newLibrarySample;
975
+ }
976
+ else {
977
+ existingLibrarySample.displayText = `${existingLanguageSampleKey} / ${existingLibrarySampleKey}`;
978
+ existingLibrarySample.sampleCode = customCodeSample.source;
979
+ }
980
+ }
981
+ else {
982
+ existingLanguageSample.sampleCode = customCodeSample.source;
983
+ }
912
984
  }
913
- });
914
- return () => {
915
- isStale = true;
916
- };
917
- }, [request, httpSnippetLanguage, httpSnippetLibrary]);
918
- const menuItems = React.useMemo(() => {
919
- const items = Object.entries(requestSampleConfigs).map(([language, config]) => {
920
- const hasLibraries = config.libraries && Object.keys(config.libraries).length > 0;
985
+ }
986
+ return requestSamples;
987
+ }, [customCodeSamples]);
988
+ const [menuItems, selectedSampleConfig] = React.useMemo(() => {
989
+ var _a, _b;
990
+ const items = Object.entries(allRequestSamples).map(([languageLabel, languageConfig]) => {
991
+ var _a;
992
+ const hasLibraries = Object.keys((_a = languageConfig.libraries) !== null && _a !== void 0 ? _a : {}).length > 0;
921
993
  return {
922
- id: language,
923
- title: language,
924
- isChecked: selectedLanguage === language,
994
+ id: languageLabel,
995
+ title: languageLabel,
996
+ isChecked: selectedLanguage === languageConfig.httpSnippetLanguage,
997
+ closeOnPress: !hasLibraries,
925
998
  onPress: hasLibraries
926
999
  ? undefined
927
1000
  : () => {
928
- setSelectedLanguage(language);
1001
+ setSelectedLanguage(languageConfig.httpSnippetLanguage);
929
1002
  setSelectedLibrary('');
930
1003
  },
931
- children: config.libraries
932
- ? Object.keys(config.libraries).map(library => ({
933
- id: `${language}-${library}`,
934
- title: library,
935
- isChecked: selectedLanguage === language && selectedLibrary === library,
1004
+ children: hasLibraries
1005
+ ? Object.entries(languageConfig.libraries).map(([libraryLabel, libraryConfig]) => ({
1006
+ id: `${languageLabel}-${libraryLabel}`,
1007
+ title: libraryLabel,
1008
+ isChecked: selectedLanguage === languageConfig.httpSnippetLanguage &&
1009
+ selectedLibrary === libraryConfig.httpSnippetLibrary,
936
1010
  onPress: () => {
937
- setSelectedLanguage(language);
938
- setSelectedLibrary(library);
1011
+ setSelectedLanguage(languageConfig.httpSnippetLanguage);
1012
+ setSelectedLibrary(libraryConfig.httpSnippetLibrary);
939
1013
  },
940
1014
  }))
941
1015
  : undefined,
942
1016
  };
943
1017
  });
944
- return items;
945
- }, [selectedLanguage, selectedLibrary, setSelectedLanguage, setSelectedLibrary]);
1018
+ const selectedLanguageSample = find__default["default"](allRequestSamples, { httpSnippetLanguage: selectedLanguage });
1019
+ const selectedLibrarySample = find__default["default"]((_a = selectedLanguageSample === null || selectedLanguageSample === void 0 ? void 0 : selectedLanguageSample.libraries) !== null && _a !== void 0 ? _a : {}, {
1020
+ httpSnippetLibrary: selectedLibrary,
1021
+ });
1022
+ return [
1023
+ items,
1024
+ Object.assign(Object.assign(Object.assign({}, selectedLibrarySample), selectedLanguageSample), { displayText: (_b = selectedLibrarySample === null || selectedLibrarySample === void 0 ? void 0 : selectedLibrarySample.displayText) !== null && _b !== void 0 ? _b : selectedLanguageSample === null || selectedLanguageSample === void 0 ? void 0 : selectedLanguageSample.displayText }),
1025
+ ];
1026
+ }, [allRequestSamples, selectedLanguage, selectedLibrary, setSelectedLanguage, setSelectedLibrary]);
1027
+ const [requestSample, setRequestSample] = React.useState(null);
1028
+ React.useEffect(() => {
1029
+ let isStale = false;
1030
+ if (selectedSampleConfig) {
1031
+ if (selectedSampleConfig.sampleCode) {
1032
+ setRequestSample(selectedSampleConfig.sampleCode);
1033
+ }
1034
+ else {
1035
+ convertRequestToSample(selectedSampleConfig.httpSnippetLanguage, selectedSampleConfig.httpSnippetLibrary, request)
1036
+ .then(example => {
1037
+ if (!isStale) {
1038
+ setRequestSample(example);
1039
+ }
1040
+ })
1041
+ .catch(() => {
1042
+ if (!isStale) {
1043
+ setRequestSample(fallbackText);
1044
+ }
1045
+ });
1046
+ }
1047
+ }
1048
+ else {
1049
+ setRequestSample(fallbackText);
1050
+ }
1051
+ return () => {
1052
+ isStale = true;
1053
+ };
1054
+ }, [request, selectedSampleConfig]);
946
1055
  return (React__default["default"].createElement(mosaic.Panel, { rounded: embeddedInMd ? undefined : true, isCollapsible: embeddedInMd },
947
1056
  React__default["default"].createElement(mosaic.Panel.Titlebar, { rightComponent: React__default["default"].createElement(mosaic.CopyButton, { size: "sm", copyValue: requestSample || '' }) },
948
1057
  React__default["default"].createElement(mosaic.Box, { ml: -2 },
949
1058
  React__default["default"].createElement(mosaic.Menu, { "aria-label": "Request Sample Language", closeOnPress: true, items: menuItems, renderTrigger: ({ isOpen }) => (React__default["default"].createElement(mosaic.Button, { size: "sm", iconRight: "chevron-down", appearance: "minimal", active: isOpen },
950
1059
  "Request Sample: ",
951
- selectedLanguage,
952
- " ",
953
- selectedLibrary ? ` / ${selectedLibrary}` : '')) }))),
954
- React__default["default"].createElement(mosaic.Panel.Content, { p: 0 }, requestSample !== null && (React__default["default"].createElement(mosaicCodeViewer.CodeViewer, { "aria-label": requestSample, noCopyButton: true, maxHeight: "400px", language: mosaicCodeViewerLanguage, value: requestSample, style: embeddedInMd
1060
+ selectedSampleConfig.displayText)) }))),
1061
+ React__default["default"].createElement(mosaic.Panel.Content, { p: 0 }, requestSample !== null && (React__default["default"].createElement(mosaicCodeViewer.CodeViewer, { "aria-label": requestSample, noCopyButton: true, maxHeight: "400px", language: selectedSampleConfig === null || selectedSampleConfig === void 0 ? void 0 : selectedSampleConfig.mosaicCodeViewerLanguage, value: requestSample, style: embeddedInMd
955
1062
  ? undefined
956
1063
  :
957
1064
  {
@@ -2215,6 +2322,7 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2215
2322
  const { serverVariables: serverVariableValues, updateServerVariableValue } = useServerVariables();
2216
2323
  const isMockingEnabled = mockUrl && (chosenServer === null || chosenServer === void 0 ? void 0 : chosenServer.url) === mockUrl;
2217
2324
  const hasRequiredButEmptyParameters = allParameters.some(parameter => parameter.required && !parameterValuesWithDefaults[parameter.name]);
2325
+ const customCodeSamples = extractCodeSamples(httpOperation);
2218
2326
  const getValues = () => Object.keys(bodyParameterValues)
2219
2327
  .filter(param => { var _a; return (_a = !isAllowedEmptyValues[param]) !== null && _a !== void 0 ? _a : true; })
2220
2328
  .reduce((previousValue, currentValue) => {
@@ -2344,11 +2452,11 @@ const TryIt = ({ httpOperation, mockUrl, onRequestChange, requestBodyIndex, embe
2344
2452
  tryItPanelContents));
2345
2453
  }
2346
2454
  else {
2347
- tryItPanelElem = (React__namespace.createElement(mosaic.Box, { className: "TryItPanel", bg: "canvas-100", rounded: "lg" }, tryItPanelContents));
2455
+ tryItPanelElem = (React__namespace.createElement(mosaic.Box, { className: "TryItPanel", bg: "canvas-100" }, tryItPanelContents));
2348
2456
  }
2349
2457
  return (React__namespace.createElement(mosaic.Box, { rounded: "lg", overflowY: "hidden" },
2350
2458
  tryItPanelElem,
2351
- requestData && embeddedInMd && React__namespace.createElement(RequestSamples, { request: requestData, embeddedInMd: true }),
2459
+ requestData && embeddedInMd && (React__namespace.createElement(RequestSamples, { request: requestData, customCodeSamples: customCodeSamples, embeddedInMd: true })),
2352
2460
  response && !('error' in response) && React__namespace.createElement(TryItResponse, { response: response }),
2353
2461
  response && 'error' in response && React__namespace.createElement(ResponseError, { state: response })));
2354
2462
  };
@@ -2392,14 +2500,41 @@ const ResponseExamples = ({ httpOperation, responseMediaType, responseStatusCode
2392
2500
  const TryItWithRequestSamples = (_a) => {
2393
2501
  var { hideTryIt } = _a, props = tslib.__rest(_a, ["hideTryIt"]);
2394
2502
  const [requestData, setRequestData] = React__namespace.useState();
2503
+ const customCodeSamples = extractCodeSamples(props.httpOperation);
2395
2504
  return (React__namespace.createElement(mosaic.VStack, { spacing: 6 },
2396
2505
  !hideTryIt && (React__namespace.createElement(mosaic.InvertTheme, null,
2397
2506
  React__namespace.createElement(mosaic.Box, null,
2398
2507
  React__namespace.createElement(TryIt, Object.assign({}, props, { onRequestChange: setRequestData }))))),
2399
- requestData && React__namespace.createElement(RequestSamples, { request: requestData }),
2508
+ requestData && React__namespace.createElement(RequestSamples, { request: requestData, customCodeSamples: customCodeSamples }),
2400
2509
  React__namespace.createElement(ResponseExamples, Object.assign({}, props))));
2401
2510
  };
2402
2511
 
2512
+ const getVendorExtensions = memoize__default["default"]((data) => {
2513
+ const vendorExtensionNames = Object.keys(data).filter(item => item.startsWith('x-'));
2514
+ const vendorExtensions = vendorExtensionNames.reduce((previousValue, currentValue, currentIndex) => {
2515
+ return Object.assign(Object.assign({}, previousValue), { [currentValue]: data[currentValue] });
2516
+ }, {});
2517
+ return vendorExtensions;
2518
+ });
2519
+ const NodeVendorExtensions = React__namespace.memo(({ data }) => {
2520
+ const { renderExtensionAddon } = useOptionsCtx();
2521
+ if (!renderExtensionAddon) {
2522
+ return null;
2523
+ }
2524
+ const originalObject = getOriginalObject(data);
2525
+ const vendorExtensions = originalObject.extensions ? originalObject.extensions : getVendorExtensions(originalObject);
2526
+ const vendorExtensionKeys = Object.keys(vendorExtensions);
2527
+ if (vendorExtensionKeys.length === 0) {
2528
+ return null;
2529
+ }
2530
+ return (React__namespace.createElement(React__namespace.Fragment, null, renderExtensionAddon({
2531
+ nestingLevel: -1,
2532
+ schemaNode: originalObject,
2533
+ vendorExtensions,
2534
+ })));
2535
+ });
2536
+ NodeVendorExtensions.displayName = 'NodeVendorExtensions';
2537
+
2403
2538
  const TwoColumnLayout = React__default["default"].forwardRef(({ header, right, left, className }, ref) => (React__default["default"].createElement(mosaic.VStack, { ref: ref, w: "full", className: className, spacing: 8 },
2404
2539
  header,
2405
2540
  React__default["default"].createElement(mosaic.Flex, null,
@@ -2557,7 +2692,7 @@ const Body = ({ body, onChange }) => {
2557
2692
  var _a;
2558
2693
  const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2559
2694
  const [chosenContent, setChosenContent] = React__namespace.useState(0);
2560
- const { nodeHasChanged } = useOptionsCtx();
2695
+ const { nodeHasChanged, renderExtensionAddon } = useOptionsCtx();
2561
2696
  React__namespace.useEffect(() => {
2562
2697
  onChange === null || onChange === void 0 ? void 0 : onChange(chosenContent);
2563
2698
  }, [chosenContent]);
@@ -2572,7 +2707,7 @@ const Body = ({ body, onChange }) => {
2572
2707
  description && (React__namespace.createElement(mosaic.Box, { pos: "relative" },
2573
2708
  React__namespace.createElement(MarkdownViewer, { markdown: description }),
2574
2709
  React__namespace.createElement(mosaic.NodeAnnotation, { change: descriptionChanged }))),
2575
- isJSONSchema(schema) && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema), viewMode: "write", renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))));
2710
+ isJSONSchema(schema) && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema), viewMode: "write", renderRootTreeLines: true, nodeHasChanged: nodeHasChanged, renderExtensionAddon: renderExtensionAddon }))));
2576
2711
  };
2577
2712
  Body.displayName = 'HttpOperation.Body';
2578
2713
 
@@ -2596,12 +2731,12 @@ const defaultStyle = {
2596
2731
  cookie: types.HttpParamStyles.Form,
2597
2732
  };
2598
2733
  const Parameters = ({ parameters, parameterType }) => {
2599
- const { nodeHasChanged } = useOptionsCtx();
2734
+ const { nodeHasChanged, renderExtensionAddon } = useOptionsCtx();
2600
2735
  const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2601
2736
  const schema = React__namespace.useMemo(() => httpOperationParamsToSchema({ parameters, parameterType }), [parameters, parameterType]);
2602
2737
  if (!schema)
2603
2738
  return null;
2604
- return (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: schema, disableCrumbs: true, nodeHasChanged: nodeHasChanged }));
2739
+ return (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: schema, disableCrumbs: true, nodeHasChanged: nodeHasChanged, renderExtensionAddon: renderExtensionAddon }));
2605
2740
  };
2606
2741
  Parameters.displayName = 'HttpOperation.Parameters';
2607
2742
  const httpOperationParamsToSchema = ({ parameters, parameterType }) => {
@@ -2741,7 +2876,7 @@ const Response = ({ response, onMediaTypeChange }) => {
2741
2876
  const { contents = [], headers = [], description } = response;
2742
2877
  const [chosenContent, setChosenContent] = React__namespace.useState(0);
2743
2878
  const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2744
- const { nodeHasChanged } = useOptionsCtx();
2879
+ const { nodeHasChanged, renderExtensionAddon } = useOptionsCtx();
2745
2880
  const responseContent = contents[chosenContent];
2746
2881
  const schema = responseContent === null || responseContent === void 0 ? void 0 : responseContent.schema;
2747
2882
  React__namespace.useEffect(() => {
@@ -2759,7 +2894,7 @@ const Response = ({ response, onMediaTypeChange }) => {
2759
2894
  React__namespace.createElement(SectionSubtitle, { title: "Body", id: "response-body" },
2760
2895
  React__namespace.createElement(mosaic.Flex, { flex: 1, justify: "end" },
2761
2896
  React__namespace.createElement(mosaic.Select, { "aria-label": "Response Body Content Type", value: String(chosenContent), onChange: value => setChosenContent(parseInt(String(value), 10)), options: contents.map((content, index) => ({ label: content.mediaType, value: index })), size: "sm" }))),
2762
- schema && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, maxRefDepth: maxRefDepth, viewMode: "read", parentCrumbs: ['responses', response.code], renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))))));
2897
+ schema && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, maxRefDepth: maxRefDepth, viewMode: "read", parentCrumbs: ['responses', response.code], renderRootTreeLines: true, nodeHasChanged: nodeHasChanged, renderExtensionAddon: renderExtensionAddon }))))));
2763
2898
  };
2764
2899
  Response.displayName = 'HttpOperation.Response';
2765
2900
  const codeToIntentVal = (code) => {
@@ -2835,6 +2970,7 @@ const HttpOperationComponent = React__namespace.memo(({ className, data: unresol
2835
2970
  data.description && (React__namespace.createElement(mosaic.Box, { pos: "relative" },
2836
2971
  React__namespace.createElement(MarkdownViewer, { className: "HttpOperation__Description", markdown: data.description }),
2837
2972
  React__namespace.createElement(mosaic.NodeAnnotation, { change: descriptionChanged }))),
2973
+ React__namespace.createElement(NodeVendorExtensions, { data: data }),
2838
2974
  React__namespace.createElement(Request, { onChange: setTextRequestBodyIndex, operation: data }),
2839
2975
  data.responses && (React__namespace.createElement(Responses, { responses: data.responses, onMediaTypeChange: setResponseMediaType, onStatusCodeChange: setResponseStatusCode, isCompact: isCompact })),
2840
2976
  ((_a = data.callbacks) === null || _a === void 0 ? void 0 : _a.length) ? React__namespace.createElement(Callbacks, { callbacks: data.callbacks, isCompact: isCompact }) : null,
@@ -3086,7 +3222,7 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
3086
3222
  var _a, _b;
3087
3223
  const [resolveRef, maxRefDepth] = useSchemaInlineRefResolver();
3088
3224
  const data = useResolvedObject(unresolvedData);
3089
- const { nodeHasChanged } = useOptionsCtx();
3225
+ const { nodeHasChanged, renderExtensionAddon } = useOptionsCtx();
3090
3226
  const { ref: layoutRef, isCompact } = useIsCompact(layoutOptions);
3091
3227
  const nodeId = (_a = data === null || data === void 0 ? void 0 : data['x-stoplight']) === null || _a === void 0 ? void 0 : _a.id;
3092
3228
  const title = (_b = data.title) !== null && _b !== void 0 ? _b : nodeTitle;
@@ -3109,8 +3245,9 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
3109
3245
  data.description && data.type === 'object' && (React__namespace.createElement(mosaic.Box, { pos: "relative" },
3110
3246
  React__namespace.createElement(MarkdownViewer, { role: "textbox", markdown: data.description }),
3111
3247
  React__namespace.createElement(mosaic.NodeAnnotation, { change: descriptionChanged }))),
3248
+ React__namespace.createElement(NodeVendorExtensions, { data: data }),
3112
3249
  isCompact && modelExamples,
3113
- React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(data), nodeHasChanged: nodeHasChanged, skipTopLevelDescription: true })));
3250
+ React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(data), nodeHasChanged: nodeHasChanged, renderExtensionAddon: renderExtensionAddon, skipTopLevelDescription: true })));
3114
3251
  return (React__namespace.createElement(TwoColumnLayout, { ref: layoutRef, className: cn__default["default"]('Model', className), header: header, left: description, right: !isCompact && modelExamples }));
3115
3252
  };
3116
3253
  const ModelExamples = React__namespace.memo(({ data, isCollapsible = false }) => {
@@ -3133,7 +3270,7 @@ const Model = reactErrorBoundary.withErrorBoundary(ModelComponent, { recoverable
3133
3270
 
3134
3271
  const Docs = React__namespace.memo((_a) => {
3135
3272
  var _b;
3136
- var { nodeType, nodeData, useNodeForRefResolving = false, refResolver, maxRefDepth, nodeHasChanged } = _a, commonProps = tslib.__rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver", "maxRefDepth", "nodeHasChanged"]);
3273
+ var { nodeType, nodeData, useNodeForRefResolving = false, refResolver, maxRefDepth, nodeHasChanged, renderExtensionAddon } = _a, commonProps = tslib.__rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver", "maxRefDepth", "nodeHasChanged", "renderExtensionAddon"]);
3137
3274
  const parsedNode = useParsedData(nodeType, nodeData);
3138
3275
  if (!parsedNode) {
3139
3276
  (_b = commonProps.nodeUnsupported) === null || _b === void 0 ? void 0 : _b.call(commonProps, 'dataEmpty');
@@ -3143,7 +3280,7 @@ const Docs = React__namespace.memo((_a) => {
3143
3280
  if (useNodeForRefResolving) {
3144
3281
  elem = (React__namespace.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver, maxRefDepth: maxRefDepth }, elem));
3145
3282
  }
3146
- return React__namespace.createElement(ElementsOptionsProvider, { nodeHasChanged: nodeHasChanged }, elem);
3283
+ return (React__namespace.createElement(ElementsOptionsProvider, { nodeHasChanged: nodeHasChanged, renderExtensionAddon: renderExtensionAddon }, elem));
3147
3284
  });
3148
3285
  const ParsedDocs = (_a) => {
3149
3286
  var { node, nodeUnsupported } = _a, commonProps = tslib.__rest(_a, ["node", "nodeUnsupported"]);
@@ -3249,6 +3386,9 @@ const NODE_META_COLOR = {
3249
3386
  put: 'warning',
3250
3387
  patch: 'warning',
3251
3388
  delete: 'danger',
3389
+ head: '#9061F9',
3390
+ options: '#0D5AA7',
3391
+ trace: '#0D0B28',
3252
3392
  };
3253
3393
 
3254
3394
  function getHtmlIdFromItemId(id) {
@@ -3602,12 +3742,13 @@ function isPartialHttpRequest(maybeHttpRequest) {
3602
3742
  }
3603
3743
  const SchemaAndDescription = ({ title: titleProp, schema }) => {
3604
3744
  const [resolveRef, maxRefDepth] = useSchemaInlineRefResolver();
3745
+ const { renderExtensionAddon } = useOptionsCtx();
3605
3746
  const title = titleProp !== null && titleProp !== void 0 ? titleProp : schema.title;
3606
3747
  return (React__default["default"].createElement(mosaic.Box, { py: 2 },
3607
3748
  title && (React__default["default"].createElement(mosaic.Flex, { alignItems: "center", p: 2 },
3608
3749
  React__default["default"].createElement(mosaic.Icon, { icon: NodeTypeIconDefs[types.NodeType.Model], color: NodeTypeColors[types.NodeType.Model] }),
3609
3750
  React__default["default"].createElement(mosaic.Box, { color: "muted", px: 2 }, title))),
3610
- React__default["default"].createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema) })));
3751
+ React__default["default"].createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema), renderExtensionAddon: renderExtensionAddon })));
3611
3752
  };
3612
3753
  const CodeComponent = props => {
3613
3754
  const { title, jsonSchema, http, resolved, children } = props;
@@ -3958,6 +4099,7 @@ Object.defineProperty(exports, 'DefaultSMDComponents', {
3958
4099
  });
3959
4100
  exports.DeprecatedBadge = DeprecatedBadge;
3960
4101
  exports.Docs = Docs;
4102
+ exports.ElementsOptionsProvider = ElementsOptionsProvider;
3961
4103
  exports.ExportButton = ExportButton;
3962
4104
  exports.HttpMethodColors = HttpMethodColors;
3963
4105
  exports.InlineRefResolverProvider = InlineRefResolverProvider;