@stoplight/elements-core 7.13.9 → 7.15.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.
@@ -0,0 +1,3 @@
1
+ import { IHttpOperation } from '@stoplight/types';
2
+ export declare const httpOperation: IHttpOperation;
3
+ export default httpOperation;
@@ -1,5 +1,13 @@
1
- declare const meta: import("@storybook/react").Meta<import("..").DocsComponentProps<string | import("@stoplight/markdown/ast-types/mdast").Root> & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
1
+ declare const meta: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, {
2
+ data: any;
3
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
2
4
  export default meta;
3
- export declare const Basic: import("@storybook/react").Story<import("..").DocsComponentProps<string | import("@stoplight/markdown/ast-types/mdast").Root> & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
4
- export declare const KitchenSink: import("@storybook/react").Story<import("..").DocsComponentProps<string | import("@stoplight/markdown/ast-types/mdast").Root> & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
5
- export declare const MultipleTryIts: import("@storybook/react").Story<import("..").DocsComponentProps<string | import("@stoplight/markdown/ast-types/mdast").Root> & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
5
+ export declare const Basic: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, {
6
+ data: any;
7
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
8
+ export declare const KitchenSink: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, {
9
+ data: any;
10
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
11
+ export declare const MultipleTryIts: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, {
12
+ data: any;
13
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
@@ -33,6 +33,7 @@ export interface DocsProps extends BaseDocsProps {
33
33
  nodeData: unknown;
34
34
  useNodeForRefResolving?: boolean;
35
35
  refResolver?: ReferenceResolver;
36
+ maxRefDepth?: number;
36
37
  }
37
38
  export interface DocsComponentProps<T = unknown> extends BaseDocsProps {
38
39
  data: T;
@@ -1,5 +1,5 @@
1
- import { Meta, Story } from '@storybook/react';
1
+ import { Story } from '@storybook/react';
2
2
  import { DocsProps } from './Docs';
3
- declare const _default: Meta<DocsProps>;
3
+ declare const _default: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, DocsProps>;
4
4
  export default _default;
5
5
  export declare const DocsStory: Story<DocsProps>;
@@ -1,3 +1,7 @@
1
- declare const meta: import("@storybook/react").Meta<import("./HttpOperation").HttpOperationProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
1
+ declare const meta: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, {
2
+ data: any;
3
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
2
4
  export default meta;
3
- export declare const Story: import("@storybook/react").Story<import("./HttpOperation").HttpOperationProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
5
+ export declare const Story: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, {
6
+ data: any;
7
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
@@ -1,3 +1,7 @@
1
- declare const meta: import("@storybook/react").Meta<import("./HttpService").HttpServiceProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
1
+ declare const meta: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, {
2
+ data: any;
3
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
2
4
  export default meta;
3
- export declare const Story: import("@storybook/react").Story<import("./HttpService").HttpServiceProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
5
+ export declare const Story: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, {
6
+ data: any;
7
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
@@ -1,3 +1,7 @@
1
- declare const meta: import("@storybook/react").Meta<import("./Model").ModelProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
1
+ declare const meta: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, {
2
+ data: any;
3
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
2
4
  export default meta;
3
- export declare const Story: import("@storybook/react").Story<import("./Model").ModelProps & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
5
+ export declare const Story: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, {
6
+ data: any;
7
+ } & import("@stoplight/react-error-boundary").ErrorBoundaryProps<{}>>;
@@ -1,13 +1,16 @@
1
1
  import type { ErrorBoundaryProps } from '@stoplight/react-error-boundary';
2
- import type { Meta, Story } from '@storybook/react';
2
+ import type { Meta, StoryFn } from '@storybook/react';
3
3
  import * as React from 'react';
4
4
  declare type DocsProps = {
5
- data: unknown;
5
+ data: any;
6
6
  } & ErrorBoundaryProps;
7
- interface HelperReturn<P extends Partial<DocsProps>> {
8
- meta: Meta<P>;
9
- createStory(name: string, input: Partial<P>): Story<P>;
10
- createHoistedStory(input: Partial<P>): Story<P>;
7
+ declare type storyOptions = DocsProps & {
8
+ layoutOptions?: object;
9
+ };
10
+ interface HelperReturn<P extends DocsProps> {
11
+ meta: Meta<DocsProps>;
12
+ createStory(name: string, input: storyOptions): StoryFn<P>;
13
+ createHoistedStory(input: storyOptions): StoryFn<P>;
11
14
  }
12
- export declare const createStoriesForDocsComponent: <P extends Partial<DocsProps> = DocsProps>(Component: React.ComponentType<P>, title?: string) => HelperReturn<P>;
15
+ export declare const createStoriesForDocsComponent: (Component: React.ComponentType<DocsProps>, title?: string) => HelperReturn<DocsProps>;
13
16
  export {};
@@ -1,5 +1,4 @@
1
- import { Meta, Story } from '@storybook/react';
2
1
  import { RequestSamplesProps } from './RequestSamples';
3
- declare const _default: Meta<RequestSamplesProps>;
2
+ declare const _default: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, RequestSamplesProps>;
4
3
  export default _default;
5
- export declare const HoistedStory: Story<RequestSamplesProps>;
4
+ export declare const HoistedStory: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, RequestSamplesProps>;
@@ -1,5 +1,4 @@
1
- import { Meta, Story } from '@storybook/react';
2
1
  import { ResponseExamplesProps } from './ResponseExamples';
3
- declare const _default: Meta<ResponseExamplesProps>;
2
+ declare const _default: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, ResponseExamplesProps>;
4
3
  export default _default;
5
- export declare const HoistedStory: Story<ResponseExamplesProps>;
4
+ export declare const HoistedStory: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, ResponseExamplesProps>;
@@ -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: Pick<ParameterSpec, 'schema'>): boolean;
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: import("json-schema").JSONSchema7 | undefined;
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;
@@ -1,13 +1,13 @@
1
- import { Meta, Story } from '@storybook/react';
2
1
  import { TryItProps } from './TryIt';
3
- declare const _default: Meta<TryItProps>;
2
+ declare const _default: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
4
3
  export default _default;
5
- export declare const SimpleGET: Story<TryItProps>;
6
- export declare const WithParameters: Story<TryItProps>;
7
- export declare const WithVariables: Story<TryItProps>;
8
- export declare const UrlEncoded: Story<TryItProps>;
9
- export declare const Multipart: Story<TryItProps>;
10
- export declare const RequestBodySchema: Story<TryItProps>;
11
- export declare const RequestBodyExamples: Story<TryItProps>;
12
- export declare const TryItAuth: Story<TryItProps>;
13
- export declare const TryItAuthDuplicated: Story<TryItProps>;
4
+ export declare const SimpleGET: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
5
+ export declare const WithParameters: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
6
+ export declare const WithVariables: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
7
+ export declare const UrlEncoded: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
8
+ export declare const UrlEncodedOneOf: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
9
+ export declare const Multipart: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
10
+ export declare const RequestBodySchema: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
11
+ export declare const RequestBodyExamples: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
12
+ export declare const TryItAuth: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
13
+ export declare const TryItAuthDuplicated: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItProps>;
@@ -1,6 +1,5 @@
1
- import { Meta, Story } from '@storybook/react';
2
1
  import { TryItWithRequestSamplesProps } from './TryItWithRequestSamples';
3
- declare const _default: Meta<TryItWithRequestSamplesProps>;
2
+ declare const _default: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0a347bb9").R, TryItWithRequestSamplesProps>;
4
3
  export default _default;
5
- export declare const WithParameters: Story<TryItWithRequestSamplesProps>;
6
- export declare const WithVariables: Story<TryItWithRequestSamplesProps>;
4
+ export declare const WithParameters: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItWithRequestSamplesProps>;
5
+ export declare const WithVariables: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, TryItWithRequestSamplesProps>;
@@ -1,12 +1,18 @@
1
1
  import * as React from 'react';
2
2
  import { ReferenceResolver } from '../utils/ref-resolving/ReferenceResolver';
3
+ declare type InlineRefResolverContext = {
4
+ resolver: ReferenceResolver | undefined;
5
+ maxRefDepth: number | undefined;
6
+ };
7
+ declare const InlineRefResolverContext: React.Context<InlineRefResolverContext | undefined>;
3
8
  declare type InlineRefResolverProviderProps = {
4
9
  document?: unknown;
5
10
  resolver?: ReferenceResolver;
11
+ maxRefDepth?: number;
6
12
  };
7
13
  export declare const InlineRefResolverProvider: React.FC<InlineRefResolverProviderProps>;
8
- export declare const useInlineRefResolver: () => ReferenceResolver | undefined;
14
+ export declare const useInlineRefResolver: () => InlineRefResolverContext | undefined;
9
15
  export declare const useDocument: () => object | undefined;
10
16
  export declare const useResolvedObject: (currentObject: object) => object;
11
- export declare const useSchemaInlineRefResolver: () => ReferenceResolver;
17
+ export declare const useSchemaInlineRefResolver: () => [ReferenceResolver, number | undefined];
12
18
  export {};
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';
@@ -117,23 +119,25 @@ const InlineRefResolverContext = React.createContext(undefined);
117
119
  InlineRefResolverContext.displayName = 'InlineRefResolverContext';
118
120
  const DocumentContext = React.createContext(undefined);
119
121
  DocumentContext.displayName = 'DocumentContext';
120
- const InlineRefResolverProvider = ({ children, document: maybeDocument, resolver, }) => {
122
+ const InlineRefResolverProvider = ({ children, document: maybeDocument, resolver, maxRefDepth, }) => {
121
123
  const document = isPlainObject$1(maybeDocument) ? maybeDocument : undefined;
122
124
  const computedResolver = React.useMemo(() => resolver || (document !== undefined ? defaultResolver(document) : undefined), [document, resolver]);
123
- return (React.createElement(InlineRefResolverContext.Provider, { value: computedResolver },
125
+ return (React.createElement(InlineRefResolverContext.Provider, { value: { resolver: computedResolver, maxRefDepth } },
124
126
  React.createElement(DocumentContext.Provider, { value: document }, children)));
125
127
  };
126
128
  const useInlineRefResolver = () => useContext(InlineRefResolverContext);
127
129
  const useDocument = () => useContext(DocumentContext);
128
130
  const useResolvedObject = (currentObject) => {
131
+ var _a;
129
132
  const document = useDocument();
130
- const resolver = useInlineRefResolver();
133
+ const { resolver } = (_a = useInlineRefResolver()) !== null && _a !== void 0 ? _a : {};
131
134
  return React.useMemo(() => createResolvedObject(currentObject, { contextObject: document, resolver }), [currentObject, document, resolver]);
132
135
  };
133
136
  const useSchemaInlineRefResolver = () => {
137
+ var _a;
134
138
  const document = useDocument();
135
- const resolver = useInlineRefResolver();
136
- return React.useCallback((...args) => {
139
+ const { resolver, maxRefDepth } = (_a = useInlineRefResolver()) !== null && _a !== void 0 ? _a : {};
140
+ const referenceResolver = React.useCallback((...args) => {
137
141
  const resolved = resolver === null || resolver === void 0 ? void 0 : resolver(...args);
138
142
  if (!isPlainObject$1(resolved)) {
139
143
  return resolved;
@@ -149,6 +153,7 @@ const useSchemaInlineRefResolver = () => {
149
153
  delete converted.$schema;
150
154
  return converted;
151
155
  }, [document, resolver]);
156
+ return [referenceResolver, maxRefDepth];
152
157
  };
153
158
 
154
159
  const DEFAULT_CONTEXT = {};
@@ -1176,7 +1181,9 @@ function exampleOptions(parameter) {
1176
1181
  }
1177
1182
  function parameterSupportsFileUpload(parameter) {
1178
1183
  var _a, _b, _c;
1179
- return (((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
1184
+ return (parameter &&
1185
+ parameter.schema &&
1186
+ ((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
1180
1187
  (((_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.contentEncoding) === 'base64' ||
1181
1188
  ((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
1182
1189
  }
@@ -1232,6 +1239,35 @@ function mapSchemaPropertiesToParameters(properties, required) {
1232
1239
  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
1240
  ? [{ key: 'example', value: schema.examples[0] }]
1234
1241
  : undefined }, ((required === null || required === void 0 ? void 0 : required.includes(name)) && { required: true }))));
1242
+ }
1243
+ function toParameterSpec(jsonTreeNode) {
1244
+ var _a;
1245
+ const isBoolean = jsonTreeNode.primaryType === 'boolean';
1246
+ const schema = !isBoolean ? jsonTreeNode.fragment : undefined;
1247
+ const examples = !isBoolean && jsonTreeNode.fragment.examples && jsonTreeNode.fragment.examples[0]
1248
+ ? [{ key: 'example', value: jsonTreeNode.fragment.examples[0] }]
1249
+ : undefined;
1250
+ const lastJsonPathSegment = (_a = last(jsonTreeNode.path)) !== null && _a !== void 0 ? _a : '<<UNKNOWN>>';
1251
+ return {
1252
+ name: lastJsonPathSegment,
1253
+ schema,
1254
+ examples,
1255
+ required: isRequired(jsonTreeNode),
1256
+ };
1257
+ }
1258
+ function isRequired(n) {
1259
+ if (!isRegularNode(n)) {
1260
+ return undefined;
1261
+ }
1262
+ const name = last(n.path);
1263
+ if (name === undefined) {
1264
+ return undefined;
1265
+ }
1266
+ const parent = n.parent;
1267
+ if (parent === null || !isRegularNode(parent)) {
1268
+ return undefined;
1269
+ }
1270
+ return parent.required !== null && parent.required.includes(name);
1235
1271
  }
1236
1272
 
1237
1273
  const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
@@ -1261,31 +1297,53 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
1261
1297
  };
1262
1298
 
1263
1299
  const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
1264
- const schema = specification.schema;
1265
- const parameters = schema === null || schema === void 0 ? void 0 : schema.properties;
1266
- const required = schema === null || schema === void 0 ? void 0 : schema.required;
1267
- React.useEffect(() => {
1268
- if (parameters === undefined) {
1269
- console.warn(`Invalid schema in form data spec: ${safeStringify(schema)}`);
1270
- }
1271
- }, [parameters, schema]);
1272
- if (parameters === undefined) {
1273
- return null;
1274
- }
1300
+ const schema = React.useMemo(() => {
1301
+ var _a;
1302
+ const schema = (_a = specification.schema) !== null && _a !== void 0 ? _a : {};
1303
+ const tree = new SchemaTree(schema, { mergeAllOf: true, refResolver: null });
1304
+ tree.populate();
1305
+ return tree.root.children[0];
1306
+ }, [specification]);
1307
+ const { selectedChoice, choices, setSelectedChoice } = useChoices(schema);
1308
+ const formFieldRows = visibleChildren(selectedChoice.type);
1309
+ const onSchemaChange = (choice) => {
1310
+ onChangeValues({});
1311
+ setSelectedChoice(choice);
1312
+ };
1275
1313
  return (React.createElement(Panel, { defaultIsOpen: true },
1276
- React.createElement(Panel.Titlebar, null, "Body"),
1277
- React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, mapSchemaPropertiesToParameters(parameters, required).map(parameter => {
1278
- var _a;
1314
+ React.createElement(Panel.Titlebar, { rightComponent: React.createElement(OneOfMenu, { choices: choices, choice: selectedChoice, onChange: onSchemaChange }) }, "Body"),
1315
+ React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, formFieldRows
1316
+ .filter(isRegularNode)
1317
+ .map(toParameterSpec)
1318
+ .map(parameter => {
1319
+ var _a, _b;
1279
1320
  const supportsFileUpload = parameterSupportsFileUpload(parameter);
1280
- const value = values[parameter.name];
1321
+ const value = values[(_a = parameter.name) !== null && _a !== void 0 ? _a : ''];
1281
1322
  if (supportsFileUpload) {
1282
1323
  return (React.createElement(FileUploadParameterEditor, { key: parameter.name, parameter: parameter, value: value instanceof File ? value : undefined, onChange: newValue => newValue
1283
1324
  ? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
1284
1325
  : onChangeValues(omit(values, parameter.name)) }));
1285
1326
  }
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: (_a = isAllowedEmptyValues[parameter.name]) !== null && _a !== void 0 ? _a : false }));
1327
+ 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
1328
  }))));
1288
- };
1329
+ };
1330
+ function OneOfMenu({ choices: subSchemas, choice, onChange }) {
1331
+ var _a;
1332
+ const onSubSchemaSelect = React.useCallback(onChange, [onChange]);
1333
+ const menuItems = React.useMemo(() => subSchemas.map(subSchema => {
1334
+ const label = subSchema.title;
1335
+ return {
1336
+ id: `request-subschema-${label}`,
1337
+ title: label,
1338
+ onPress: () => onSubSchemaSelect(subSchema),
1339
+ };
1340
+ }), [subSchemas, onSubSchemaSelect]);
1341
+ if (!subSchemas || subSchemas.length < 2) {
1342
+ return null;
1343
+ }
1344
+ const title = (_a = choice === null || choice === void 0 ? void 0 : choice.title) !== null && _a !== void 0 ? _a : 'Variants';
1345
+ 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)) }));
1346
+ }
1289
1347
 
1290
1348
  const fileToBase64 = (file) => new Promise((resolve, reject) => {
1291
1349
  const reader = new FileReader();
@@ -2391,7 +2449,7 @@ const isBodyEmpty = (body) => {
2391
2449
  };
2392
2450
  const Body = ({ body, onChange }) => {
2393
2451
  var _a;
2394
- const refResolver = useSchemaInlineRefResolver();
2452
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2395
2453
  const [chosenContent, setChosenContent] = React.useState(0);
2396
2454
  const { nodeHasChanged } = useOptionsCtx();
2397
2455
  React.useEffect(() => {
@@ -2408,7 +2466,7 @@ const Body = ({ body, onChange }) => {
2408
2466
  description && (React.createElement(Box, { pos: "relative" },
2409
2467
  React.createElement(MarkdownViewer, { markdown: description }),
2410
2468
  React.createElement(NodeAnnotation, { change: descriptionChanged }))),
2411
- isJSONSchema(schema) && (React.createElement(JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))));
2469
+ isJSONSchema(schema) && (React.createElement(JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema), viewMode: "write", renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))));
2412
2470
  };
2413
2471
  Body.displayName = 'HttpOperation.Body';
2414
2472
 
@@ -2433,11 +2491,11 @@ const defaultStyle = {
2433
2491
  };
2434
2492
  const Parameters = ({ parameters, parameterType }) => {
2435
2493
  const { nodeHasChanged } = useOptionsCtx();
2436
- const refResolver = useSchemaInlineRefResolver();
2494
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2437
2495
  const schema = React.useMemo(() => httpOperationParamsToSchema({ parameters, parameterType }), [parameters, parameterType]);
2438
2496
  if (!schema)
2439
2497
  return null;
2440
- return React.createElement(JsonSchemaViewer, { resolveRef: refResolver, schema: schema, disableCrumbs: true, nodeHasChanged: nodeHasChanged });
2498
+ return (React.createElement(JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: schema, disableCrumbs: true, nodeHasChanged: nodeHasChanged }));
2441
2499
  };
2442
2500
  Parameters.displayName = 'HttpOperation.Parameters';
2443
2501
  const httpOperationParamsToSchema = ({ parameters, parameterType }) => {
@@ -2571,7 +2629,7 @@ Responses.displayName = 'HttpOperation.Responses';
2571
2629
  const Response = ({ response, onMediaTypeChange }) => {
2572
2630
  const { contents = [], headers = [], description } = response;
2573
2631
  const [chosenContent, setChosenContent] = React.useState(0);
2574
- const refResolver = useSchemaInlineRefResolver();
2632
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2575
2633
  const { nodeHasChanged } = useOptionsCtx();
2576
2634
  const responseContent = contents[chosenContent];
2577
2635
  const schema = responseContent === null || responseContent === void 0 ? void 0 : responseContent.schema;
@@ -2590,7 +2648,7 @@ const Response = ({ response, onMediaTypeChange }) => {
2590
2648
  React.createElement(SectionSubtitle, { title: "Body", id: "response-body" },
2591
2649
  React.createElement(Flex, { flex: 1, justify: "end" },
2592
2650
  React.createElement(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" }))),
2593
- schema && (React.createElement(JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", parentCrumbs: ['responses', response.code], renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))))));
2651
+ schema && (React.createElement(JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, maxRefDepth: maxRefDepth, viewMode: "read", parentCrumbs: ['responses', response.code], renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))))));
2594
2652
  };
2595
2653
  Response.displayName = 'HttpOperation.Response';
2596
2654
  const codeToIntentVal = (code) => {
@@ -2874,7 +2932,7 @@ const HttpService = withErrorBoundary(HttpServiceComponent, { recoverableProps:
2874
2932
 
2875
2933
  const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOptions, exportProps, }) => {
2876
2934
  var _a, _b;
2877
- const resolveRef = useSchemaInlineRefResolver();
2935
+ const [resolveRef, maxRefDepth] = useSchemaInlineRefResolver();
2878
2936
  const data = useResolvedObject(unresolvedData);
2879
2937
  const { nodeHasChanged } = useOptionsCtx();
2880
2938
  const { ref: layoutRef, isCompact } = useIsCompact(layoutOptions);
@@ -2900,7 +2958,7 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
2900
2958
  React.createElement(MarkdownViewer, { role: "textbox", markdown: data.description }),
2901
2959
  React.createElement(NodeAnnotation, { change: descriptionChanged }))),
2902
2960
  isCompact && modelExamples,
2903
- React.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(data), nodeHasChanged: nodeHasChanged, skipTopLevelDescription: true })));
2961
+ React.createElement(JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(data), nodeHasChanged: nodeHasChanged, skipTopLevelDescription: true })));
2904
2962
  return (React.createElement(TwoColumnLayout, { ref: layoutRef, className: cn('Model', className), header: header, left: description, right: !isCompact && modelExamples }));
2905
2963
  };
2906
2964
  const ModelExamples = React.memo(({ data, isCollapsible = false }) => {
@@ -2923,7 +2981,7 @@ const Model = withErrorBoundary(ModelComponent, { recoverableProps: ['data'] });
2923
2981
 
2924
2982
  const Docs = React.memo((_a) => {
2925
2983
  var _b;
2926
- var { nodeType, nodeData, useNodeForRefResolving = false, refResolver, nodeHasChanged } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver", "nodeHasChanged"]);
2984
+ var { nodeType, nodeData, useNodeForRefResolving = false, refResolver, maxRefDepth, nodeHasChanged } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver", "maxRefDepth", "nodeHasChanged"]);
2927
2985
  const parsedNode = useParsedData(nodeType, nodeData);
2928
2986
  if (!parsedNode) {
2929
2987
  (_b = commonProps.nodeUnsupported) === null || _b === void 0 ? void 0 : _b.call(commonProps, 'dataEmpty');
@@ -2931,7 +2989,7 @@ const Docs = React.memo((_a) => {
2931
2989
  }
2932
2990
  let elem = React.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
2933
2991
  if (useNodeForRefResolving) {
2934
- elem = (React.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, elem));
2992
+ elem = (React.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver, maxRefDepth: maxRefDepth }, elem));
2935
2993
  }
2936
2994
  return React.createElement(ElementsOptionsProvider, { nodeHasChanged: nodeHasChanged }, elem);
2937
2995
  });
@@ -3043,13 +3101,13 @@ function isPartialHttpRequest(maybeHttpRequest) {
3043
3101
  typeof maybeHttpRequest['url'] === 'string');
3044
3102
  }
3045
3103
  const SchemaAndDescription = ({ title: titleProp, schema }) => {
3046
- const resolveRef = useSchemaInlineRefResolver();
3104
+ const [resolveRef, maxRefDepth] = useSchemaInlineRefResolver();
3047
3105
  const title = titleProp !== null && titleProp !== void 0 ? titleProp : schema.title;
3048
3106
  return (React__default.createElement(Box, { py: 2 },
3049
3107
  title && (React__default.createElement(Flex, { alignItems: "center", p: 2 },
3050
3108
  React__default.createElement(Icon, { icon: NodeTypeIconDefs[NodeType.Model], color: NodeTypeColors[NodeType.Model] }),
3051
3109
  React__default.createElement(Box, { color: "muted", px: 2 }, title))),
3052
- React__default.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
3110
+ React__default.createElement(JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema) })));
3053
3111
  };
3054
3112
  const CodeComponent = props => {
3055
3113
  const { title, jsonSchema, http, resolved, children } = props;
@@ -3060,7 +3118,7 @@ const CodeComponent = props => {
3060
3118
  if (!isJSONSchema(parsedValue)) {
3061
3119
  return null;
3062
3120
  }
3063
- return (React__default.createElement(InlineRefResolverProvider, { document: parsedValue, resolver: resolver },
3121
+ return (React__default.createElement(InlineRefResolverProvider, { document: parsedValue, resolver: resolver === null || resolver === void 0 ? void 0 : resolver.resolver, maxRefDepth: resolver === null || resolver === void 0 ? void 0 : resolver.maxRefDepth },
3064
3122
  React__default.createElement(SchemaAndDescription, { title: title, schema: parsedValue })));
3065
3123
  }
3066
3124
  if (http) {
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);
@@ -173,23 +176,25 @@ const InlineRefResolverContext = React__namespace.createContext(undefined);
173
176
  InlineRefResolverContext.displayName = 'InlineRefResolverContext';
174
177
  const DocumentContext = React__namespace.createContext(undefined);
175
178
  DocumentContext.displayName = 'DocumentContext';
176
- const InlineRefResolverProvider = ({ children, document: maybeDocument, resolver, }) => {
179
+ const InlineRefResolverProvider = ({ children, document: maybeDocument, resolver, maxRefDepth, }) => {
177
180
  const document = json.isPlainObject(maybeDocument) ? maybeDocument : undefined;
178
181
  const computedResolver = React__namespace.useMemo(() => resolver || (document !== undefined ? defaultResolver(document) : undefined), [document, resolver]);
179
- return (React__namespace.createElement(InlineRefResolverContext.Provider, { value: computedResolver },
182
+ return (React__namespace.createElement(InlineRefResolverContext.Provider, { value: { resolver: computedResolver, maxRefDepth } },
180
183
  React__namespace.createElement(DocumentContext.Provider, { value: document }, children)));
181
184
  };
182
185
  const useInlineRefResolver = () => React.useContext(InlineRefResolverContext);
183
186
  const useDocument = () => React.useContext(DocumentContext);
184
187
  const useResolvedObject = (currentObject) => {
188
+ var _a;
185
189
  const document = useDocument();
186
- const resolver = useInlineRefResolver();
190
+ const { resolver } = (_a = useInlineRefResolver()) !== null && _a !== void 0 ? _a : {};
187
191
  return React__namespace.useMemo(() => createResolvedObject(currentObject, { contextObject: document, resolver }), [currentObject, document, resolver]);
188
192
  };
189
193
  const useSchemaInlineRefResolver = () => {
194
+ var _a;
190
195
  const document = useDocument();
191
- const resolver = useInlineRefResolver();
192
- return React__namespace.useCallback((...args) => {
196
+ const { resolver, maxRefDepth } = (_a = useInlineRefResolver()) !== null && _a !== void 0 ? _a : {};
197
+ const referenceResolver = React__namespace.useCallback((...args) => {
193
198
  const resolved = resolver === null || resolver === void 0 ? void 0 : resolver(...args);
194
199
  if (!json.isPlainObject(resolved)) {
195
200
  return resolved;
@@ -205,6 +210,7 @@ const useSchemaInlineRefResolver = () => {
205
210
  delete converted.$schema;
206
211
  return converted;
207
212
  }, [document, resolver]);
213
+ return [referenceResolver, maxRefDepth];
208
214
  };
209
215
 
210
216
  const DEFAULT_CONTEXT = {};
@@ -1232,7 +1238,9 @@ function exampleOptions(parameter) {
1232
1238
  }
1233
1239
  function parameterSupportsFileUpload(parameter) {
1234
1240
  var _a, _b, _c;
1235
- return (((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
1241
+ return (parameter &&
1242
+ parameter.schema &&
1243
+ ((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
1236
1244
  (((_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.contentEncoding) === 'base64' ||
1237
1245
  ((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
1238
1246
  }
@@ -1288,6 +1296,35 @@ function mapSchemaPropertiesToParameters(properties, required) {
1288
1296
  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
1297
  ? [{ key: 'example', value: schema.examples[0] }]
1290
1298
  : undefined }, ((required === null || required === void 0 ? void 0 : required.includes(name)) && { required: true }))));
1299
+ }
1300
+ function toParameterSpec(jsonTreeNode) {
1301
+ var _a;
1302
+ const isBoolean = jsonTreeNode.primaryType === 'boolean';
1303
+ const schema = !isBoolean ? jsonTreeNode.fragment : undefined;
1304
+ const examples = !isBoolean && jsonTreeNode.fragment.examples && jsonTreeNode.fragment.examples[0]
1305
+ ? [{ key: 'example', value: jsonTreeNode.fragment.examples[0] }]
1306
+ : undefined;
1307
+ const lastJsonPathSegment = (_a = last__default["default"](jsonTreeNode.path)) !== null && _a !== void 0 ? _a : '<<UNKNOWN>>';
1308
+ return {
1309
+ name: lastJsonPathSegment,
1310
+ schema,
1311
+ examples,
1312
+ required: isRequired(jsonTreeNode),
1313
+ };
1314
+ }
1315
+ function isRequired(n) {
1316
+ if (!jsonSchemaTree.isRegularNode(n)) {
1317
+ return undefined;
1318
+ }
1319
+ const name = last__default["default"](n.path);
1320
+ if (name === undefined) {
1321
+ return undefined;
1322
+ }
1323
+ const parent = n.parent;
1324
+ if (parent === null || !jsonSchemaTree.isRegularNode(parent)) {
1325
+ return undefined;
1326
+ }
1327
+ return parent.required !== null && parent.required.includes(name);
1291
1328
  }
1292
1329
 
1293
1330
  const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
@@ -1317,31 +1354,53 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
1317
1354
  };
1318
1355
 
1319
1356
  const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
1320
- const schema = specification.schema;
1321
- const parameters = schema === null || schema === void 0 ? void 0 : schema.properties;
1322
- const required = schema === null || schema === void 0 ? void 0 : schema.required;
1323
- React__namespace.useEffect(() => {
1324
- if (parameters === undefined) {
1325
- console.warn(`Invalid schema in form data spec: ${json.safeStringify(schema)}`);
1326
- }
1327
- }, [parameters, schema]);
1328
- if (parameters === undefined) {
1329
- return null;
1330
- }
1357
+ const schema = React__namespace.useMemo(() => {
1358
+ var _a;
1359
+ const schema = (_a = specification.schema) !== null && _a !== void 0 ? _a : {};
1360
+ const tree = new jsonSchemaTree.SchemaTree(schema, { mergeAllOf: true, refResolver: null });
1361
+ tree.populate();
1362
+ return tree.root.children[0];
1363
+ }, [specification]);
1364
+ const { selectedChoice, choices, setSelectedChoice } = jsonSchemaViewer.useChoices(schema);
1365
+ const formFieldRows = jsonSchemaViewer.visibleChildren(selectedChoice.type);
1366
+ const onSchemaChange = (choice) => {
1367
+ onChangeValues({});
1368
+ setSelectedChoice(choice);
1369
+ };
1331
1370
  return (React__namespace.createElement(mosaic.Panel, { defaultIsOpen: true },
1332
- React__namespace.createElement(mosaic.Panel.Titlebar, null, "Body"),
1333
- React__namespace.createElement(mosaic.Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, mapSchemaPropertiesToParameters(parameters, required).map(parameter => {
1334
- var _a;
1371
+ React__namespace.createElement(mosaic.Panel.Titlebar, { rightComponent: React__namespace.createElement(OneOfMenu, { choices: choices, choice: selectedChoice, onChange: onSchemaChange }) }, "Body"),
1372
+ React__namespace.createElement(mosaic.Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, formFieldRows
1373
+ .filter(jsonSchemaTree.isRegularNode)
1374
+ .map(toParameterSpec)
1375
+ .map(parameter => {
1376
+ var _a, _b;
1335
1377
  const supportsFileUpload = parameterSupportsFileUpload(parameter);
1336
- const value = values[parameter.name];
1378
+ const value = values[(_a = parameter.name) !== null && _a !== void 0 ? _a : ''];
1337
1379
  if (supportsFileUpload) {
1338
1380
  return (React__namespace.createElement(FileUploadParameterEditor, { key: parameter.name, parameter: parameter, value: value instanceof File ? value : undefined, onChange: newValue => newValue
1339
1381
  ? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
1340
1382
  : onChangeValues(omit__default["default"](values, parameter.name)) }));
1341
1383
  }
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: (_a = isAllowedEmptyValues[parameter.name]) !== null && _a !== void 0 ? _a : false }));
1384
+ 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
1385
  }))));
1344
- };
1386
+ };
1387
+ function OneOfMenu({ choices: subSchemas, choice, onChange }) {
1388
+ var _a;
1389
+ const onSubSchemaSelect = React__namespace.useCallback(onChange, [onChange]);
1390
+ const menuItems = React__namespace.useMemo(() => subSchemas.map(subSchema => {
1391
+ const label = subSchema.title;
1392
+ return {
1393
+ id: `request-subschema-${label}`,
1394
+ title: label,
1395
+ onPress: () => onSubSchemaSelect(subSchema),
1396
+ };
1397
+ }), [subSchemas, onSubSchemaSelect]);
1398
+ if (!subSchemas || subSchemas.length < 2) {
1399
+ return null;
1400
+ }
1401
+ const title = (_a = choice === null || choice === void 0 ? void 0 : choice.title) !== null && _a !== void 0 ? _a : 'Variants';
1402
+ 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)) }));
1403
+ }
1345
1404
 
1346
1405
  const fileToBase64 = (file) => new Promise((resolve, reject) => {
1347
1406
  const reader = new FileReader();
@@ -2447,7 +2506,7 @@ const isBodyEmpty = (body) => {
2447
2506
  };
2448
2507
  const Body = ({ body, onChange }) => {
2449
2508
  var _a;
2450
- const refResolver = useSchemaInlineRefResolver();
2509
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2451
2510
  const [chosenContent, setChosenContent] = React__namespace.useState(0);
2452
2511
  const { nodeHasChanged } = useOptionsCtx();
2453
2512
  React__namespace.useEffect(() => {
@@ -2464,7 +2523,7 @@ const Body = ({ body, onChange }) => {
2464
2523
  description && (React__namespace.createElement(mosaic.Box, { pos: "relative" },
2465
2524
  React__namespace.createElement(MarkdownViewer, { markdown: description }),
2466
2525
  React__namespace.createElement(mosaic.NodeAnnotation, { change: descriptionChanged }))),
2467
- isJSONSchema(schema) && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))));
2526
+ isJSONSchema(schema) && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema), viewMode: "write", renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))));
2468
2527
  };
2469
2528
  Body.displayName = 'HttpOperation.Body';
2470
2529
 
@@ -2489,11 +2548,11 @@ const defaultStyle = {
2489
2548
  };
2490
2549
  const Parameters = ({ parameters, parameterType }) => {
2491
2550
  const { nodeHasChanged } = useOptionsCtx();
2492
- const refResolver = useSchemaInlineRefResolver();
2551
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2493
2552
  const schema = React__namespace.useMemo(() => httpOperationParamsToSchema({ parameters, parameterType }), [parameters, parameterType]);
2494
2553
  if (!schema)
2495
2554
  return null;
2496
- return React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, schema: schema, disableCrumbs: true, nodeHasChanged: nodeHasChanged });
2555
+ return (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: schema, disableCrumbs: true, nodeHasChanged: nodeHasChanged }));
2497
2556
  };
2498
2557
  Parameters.displayName = 'HttpOperation.Parameters';
2499
2558
  const httpOperationParamsToSchema = ({ parameters, parameterType }) => {
@@ -2627,7 +2686,7 @@ Responses.displayName = 'HttpOperation.Responses';
2627
2686
  const Response = ({ response, onMediaTypeChange }) => {
2628
2687
  const { contents = [], headers = [], description } = response;
2629
2688
  const [chosenContent, setChosenContent] = React__namespace.useState(0);
2630
- const refResolver = useSchemaInlineRefResolver();
2689
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2631
2690
  const { nodeHasChanged } = useOptionsCtx();
2632
2691
  const responseContent = contents[chosenContent];
2633
2692
  const schema = responseContent === null || responseContent === void 0 ? void 0 : responseContent.schema;
@@ -2646,7 +2705,7 @@ const Response = ({ response, onMediaTypeChange }) => {
2646
2705
  React__namespace.createElement(SectionSubtitle, { title: "Body", id: "response-body" },
2647
2706
  React__namespace.createElement(mosaic.Flex, { flex: 1, justify: "end" },
2648
2707
  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" }))),
2649
- schema && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", parentCrumbs: ['responses', response.code], renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))))));
2708
+ schema && (React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, maxRefDepth: maxRefDepth, viewMode: "read", parentCrumbs: ['responses', response.code], renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))))));
2650
2709
  };
2651
2710
  Response.displayName = 'HttpOperation.Response';
2652
2711
  const codeToIntentVal = (code) => {
@@ -2930,7 +2989,7 @@ const HttpService = reactErrorBoundary.withErrorBoundary(HttpServiceComponent, {
2930
2989
 
2931
2990
  const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOptions, exportProps, }) => {
2932
2991
  var _a, _b;
2933
- const resolveRef = useSchemaInlineRefResolver();
2992
+ const [resolveRef, maxRefDepth] = useSchemaInlineRefResolver();
2934
2993
  const data = useResolvedObject(unresolvedData);
2935
2994
  const { nodeHasChanged } = useOptionsCtx();
2936
2995
  const { ref: layoutRef, isCompact } = useIsCompact(layoutOptions);
@@ -2956,7 +3015,7 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
2956
3015
  React__namespace.createElement(MarkdownViewer, { role: "textbox", markdown: data.description }),
2957
3016
  React__namespace.createElement(mosaic.NodeAnnotation, { change: descriptionChanged }))),
2958
3017
  isCompact && modelExamples,
2959
- React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(data), nodeHasChanged: nodeHasChanged, skipTopLevelDescription: true })));
3018
+ React__namespace.createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(data), nodeHasChanged: nodeHasChanged, skipTopLevelDescription: true })));
2960
3019
  return (React__namespace.createElement(TwoColumnLayout, { ref: layoutRef, className: cn__default["default"]('Model', className), header: header, left: description, right: !isCompact && modelExamples }));
2961
3020
  };
2962
3021
  const ModelExamples = React__namespace.memo(({ data, isCollapsible = false }) => {
@@ -2979,7 +3038,7 @@ const Model = reactErrorBoundary.withErrorBoundary(ModelComponent, { recoverable
2979
3038
 
2980
3039
  const Docs = React__namespace.memo((_a) => {
2981
3040
  var _b;
2982
- var { nodeType, nodeData, useNodeForRefResolving = false, refResolver, nodeHasChanged } = _a, commonProps = tslib.__rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver", "nodeHasChanged"]);
3041
+ var { nodeType, nodeData, useNodeForRefResolving = false, refResolver, maxRefDepth, nodeHasChanged } = _a, commonProps = tslib.__rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver", "maxRefDepth", "nodeHasChanged"]);
2983
3042
  const parsedNode = useParsedData(nodeType, nodeData);
2984
3043
  if (!parsedNode) {
2985
3044
  (_b = commonProps.nodeUnsupported) === null || _b === void 0 ? void 0 : _b.call(commonProps, 'dataEmpty');
@@ -2987,7 +3046,7 @@ const Docs = React__namespace.memo((_a) => {
2987
3046
  }
2988
3047
  let elem = React__namespace.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
2989
3048
  if (useNodeForRefResolving) {
2990
- elem = (React__namespace.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, elem));
3049
+ elem = (React__namespace.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver, maxRefDepth: maxRefDepth }, elem));
2991
3050
  }
2992
3051
  return React__namespace.createElement(ElementsOptionsProvider, { nodeHasChanged: nodeHasChanged }, elem);
2993
3052
  });
@@ -3099,13 +3158,13 @@ function isPartialHttpRequest(maybeHttpRequest) {
3099
3158
  typeof maybeHttpRequest['url'] === 'string');
3100
3159
  }
3101
3160
  const SchemaAndDescription = ({ title: titleProp, schema }) => {
3102
- const resolveRef = useSchemaInlineRefResolver();
3161
+ const [resolveRef, maxRefDepth] = useSchemaInlineRefResolver();
3103
3162
  const title = titleProp !== null && titleProp !== void 0 ? titleProp : schema.title;
3104
3163
  return (React__default["default"].createElement(mosaic.Box, { py: 2 },
3105
3164
  title && (React__default["default"].createElement(mosaic.Flex, { alignItems: "center", p: 2 },
3106
3165
  React__default["default"].createElement(mosaic.Icon, { icon: NodeTypeIconDefs[types.NodeType.Model], color: NodeTypeColors[types.NodeType.Model] }),
3107
3166
  React__default["default"].createElement(mosaic.Box, { color: "muted", px: 2 }, title))),
3108
- React__default["default"].createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
3167
+ React__default["default"].createElement(jsonSchemaViewer.JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema) })));
3109
3168
  };
3110
3169
  const CodeComponent = props => {
3111
3170
  const { title, jsonSchema, http, resolved, children } = props;
@@ -3116,7 +3175,7 @@ const CodeComponent = props => {
3116
3175
  if (!isJSONSchema(parsedValue)) {
3117
3176
  return null;
3118
3177
  }
3119
- return (React__default["default"].createElement(InlineRefResolverProvider, { document: parsedValue, resolver: resolver },
3178
+ return (React__default["default"].createElement(InlineRefResolverProvider, { document: parsedValue, resolver: resolver === null || resolver === void 0 ? void 0 : resolver.resolver, maxRefDepth: resolver === null || resolver === void 0 ? void 0 : resolver.maxRefDepth },
3120
3179
  React__default["default"].createElement(SchemaAndDescription, { title: title, schema: parsedValue })));
3121
3180
  }
3122
3181
  if (http) {
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';
@@ -117,23 +119,25 @@ const InlineRefResolverContext = React.createContext(undefined);
117
119
  InlineRefResolverContext.displayName = 'InlineRefResolverContext';
118
120
  const DocumentContext = React.createContext(undefined);
119
121
  DocumentContext.displayName = 'DocumentContext';
120
- const InlineRefResolverProvider = ({ children, document: maybeDocument, resolver, }) => {
122
+ const InlineRefResolverProvider = ({ children, document: maybeDocument, resolver, maxRefDepth, }) => {
121
123
  const document = isPlainObject$1(maybeDocument) ? maybeDocument : undefined;
122
124
  const computedResolver = React.useMemo(() => resolver || (document !== undefined ? defaultResolver(document) : undefined), [document, resolver]);
123
- return (React.createElement(InlineRefResolverContext.Provider, { value: computedResolver },
125
+ return (React.createElement(InlineRefResolverContext.Provider, { value: { resolver: computedResolver, maxRefDepth } },
124
126
  React.createElement(DocumentContext.Provider, { value: document }, children)));
125
127
  };
126
128
  const useInlineRefResolver = () => useContext(InlineRefResolverContext);
127
129
  const useDocument = () => useContext(DocumentContext);
128
130
  const useResolvedObject = (currentObject) => {
131
+ var _a;
129
132
  const document = useDocument();
130
- const resolver = useInlineRefResolver();
133
+ const { resolver } = (_a = useInlineRefResolver()) !== null && _a !== void 0 ? _a : {};
131
134
  return React.useMemo(() => createResolvedObject(currentObject, { contextObject: document, resolver }), [currentObject, document, resolver]);
132
135
  };
133
136
  const useSchemaInlineRefResolver = () => {
137
+ var _a;
134
138
  const document = useDocument();
135
- const resolver = useInlineRefResolver();
136
- return React.useCallback((...args) => {
139
+ const { resolver, maxRefDepth } = (_a = useInlineRefResolver()) !== null && _a !== void 0 ? _a : {};
140
+ const referenceResolver = React.useCallback((...args) => {
137
141
  const resolved = resolver === null || resolver === void 0 ? void 0 : resolver(...args);
138
142
  if (!isPlainObject$1(resolved)) {
139
143
  return resolved;
@@ -149,6 +153,7 @@ const useSchemaInlineRefResolver = () => {
149
153
  delete converted.$schema;
150
154
  return converted;
151
155
  }, [document, resolver]);
156
+ return [referenceResolver, maxRefDepth];
152
157
  };
153
158
 
154
159
  const DEFAULT_CONTEXT = {};
@@ -1176,7 +1181,9 @@ function exampleOptions(parameter) {
1176
1181
  }
1177
1182
  function parameterSupportsFileUpload(parameter) {
1178
1183
  var _a, _b, _c;
1179
- return (((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
1184
+ return (parameter &&
1185
+ parameter.schema &&
1186
+ ((_a = parameter.schema) === null || _a === void 0 ? void 0 : _a.type) === 'string' &&
1180
1187
  (((_b = parameter.schema) === null || _b === void 0 ? void 0 : _b.contentEncoding) === 'base64' ||
1181
1188
  ((_c = parameter.schema) === null || _c === void 0 ? void 0 : _c.contentMediaType) === 'application/octet-stream'));
1182
1189
  }
@@ -1232,6 +1239,35 @@ function mapSchemaPropertiesToParameters(properties, required) {
1232
1239
  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
1240
  ? [{ key: 'example', value: schema.examples[0] }]
1234
1241
  : undefined }, ((required === null || required === void 0 ? void 0 : required.includes(name)) && { required: true }))));
1242
+ }
1243
+ function toParameterSpec(jsonTreeNode) {
1244
+ var _a;
1245
+ const isBoolean = jsonTreeNode.primaryType === 'boolean';
1246
+ const schema = !isBoolean ? jsonTreeNode.fragment : undefined;
1247
+ const examples = !isBoolean && jsonTreeNode.fragment.examples && jsonTreeNode.fragment.examples[0]
1248
+ ? [{ key: 'example', value: jsonTreeNode.fragment.examples[0] }]
1249
+ : undefined;
1250
+ const lastJsonPathSegment = (_a = last(jsonTreeNode.path)) !== null && _a !== void 0 ? _a : '<<UNKNOWN>>';
1251
+ return {
1252
+ name: lastJsonPathSegment,
1253
+ schema,
1254
+ examples,
1255
+ required: isRequired(jsonTreeNode),
1256
+ };
1257
+ }
1258
+ function isRequired(n) {
1259
+ if (!isRegularNode(n)) {
1260
+ return undefined;
1261
+ }
1262
+ const name = last(n.path);
1263
+ if (name === undefined) {
1264
+ return undefined;
1265
+ }
1266
+ const parent = n.parent;
1267
+ if (parent === null || !isRegularNode(parent)) {
1268
+ return undefined;
1269
+ }
1270
+ return parent.required !== null && parent.required.includes(name);
1235
1271
  }
1236
1272
 
1237
1273
  const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptional, canChangeOptional, validate, }) => {
@@ -1261,31 +1297,53 @@ const ParameterEditor = ({ parameter, value, onChange, isOptional, onChangeOptio
1261
1297
  };
1262
1298
 
1263
1299
  const FormDataBody = ({ specification, values, onChangeValues, onChangeParameterAllow, isAllowedEmptyValues, }) => {
1264
- const schema = specification.schema;
1265
- const parameters = schema === null || schema === void 0 ? void 0 : schema.properties;
1266
- const required = schema === null || schema === void 0 ? void 0 : schema.required;
1267
- React.useEffect(() => {
1268
- if (parameters === undefined) {
1269
- console.warn(`Invalid schema in form data spec: ${safeStringify(schema)}`);
1270
- }
1271
- }, [parameters, schema]);
1272
- if (parameters === undefined) {
1273
- return null;
1274
- }
1300
+ const schema = React.useMemo(() => {
1301
+ var _a;
1302
+ const schema = (_a = specification.schema) !== null && _a !== void 0 ? _a : {};
1303
+ const tree = new SchemaTree(schema, { mergeAllOf: true, refResolver: null });
1304
+ tree.populate();
1305
+ return tree.root.children[0];
1306
+ }, [specification]);
1307
+ const { selectedChoice, choices, setSelectedChoice } = useChoices(schema);
1308
+ const formFieldRows = visibleChildren(selectedChoice.type);
1309
+ const onSchemaChange = (choice) => {
1310
+ onChangeValues({});
1311
+ setSelectedChoice(choice);
1312
+ };
1275
1313
  return (React.createElement(Panel, { defaultIsOpen: true },
1276
- React.createElement(Panel.Titlebar, null, "Body"),
1277
- React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, mapSchemaPropertiesToParameters(parameters, required).map(parameter => {
1278
- var _a;
1314
+ React.createElement(Panel.Titlebar, { rightComponent: React.createElement(OneOfMenu, { choices: choices, choice: selectedChoice, onChange: onSchemaChange }) }, "Body"),
1315
+ React.createElement(Panel.Content, { className: "sl-overflow-y-auto ParameterGrid OperationParametersContent" }, formFieldRows
1316
+ .filter(isRegularNode)
1317
+ .map(toParameterSpec)
1318
+ .map(parameter => {
1319
+ var _a, _b;
1279
1320
  const supportsFileUpload = parameterSupportsFileUpload(parameter);
1280
- const value = values[parameter.name];
1321
+ const value = values[(_a = parameter.name) !== null && _a !== void 0 ? _a : ''];
1281
1322
  if (supportsFileUpload) {
1282
1323
  return (React.createElement(FileUploadParameterEditor, { key: parameter.name, parameter: parameter, value: value instanceof File ? value : undefined, onChange: newValue => newValue
1283
1324
  ? onChangeValues(Object.assign(Object.assign({}, values), { [parameter.name]: newValue }))
1284
1325
  : onChangeValues(omit(values, parameter.name)) }));
1285
1326
  }
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: (_a = isAllowedEmptyValues[parameter.name]) !== null && _a !== void 0 ? _a : false }));
1327
+ 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
1328
  }))));
1288
- };
1329
+ };
1330
+ function OneOfMenu({ choices: subSchemas, choice, onChange }) {
1331
+ var _a;
1332
+ const onSubSchemaSelect = React.useCallback(onChange, [onChange]);
1333
+ const menuItems = React.useMemo(() => subSchemas.map(subSchema => {
1334
+ const label = subSchema.title;
1335
+ return {
1336
+ id: `request-subschema-${label}`,
1337
+ title: label,
1338
+ onPress: () => onSubSchemaSelect(subSchema),
1339
+ };
1340
+ }), [subSchemas, onSubSchemaSelect]);
1341
+ if (!subSchemas || subSchemas.length < 2) {
1342
+ return null;
1343
+ }
1344
+ const title = (_a = choice === null || choice === void 0 ? void 0 : choice.title) !== null && _a !== void 0 ? _a : 'Variants';
1345
+ 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)) }));
1346
+ }
1289
1347
 
1290
1348
  const fileToBase64 = (file) => new Promise((resolve, reject) => {
1291
1349
  const reader = new FileReader();
@@ -2391,7 +2449,7 @@ const isBodyEmpty = (body) => {
2391
2449
  };
2392
2450
  const Body = ({ body, onChange }) => {
2393
2451
  var _a;
2394
- const refResolver = useSchemaInlineRefResolver();
2452
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2395
2453
  const [chosenContent, setChosenContent] = React.useState(0);
2396
2454
  const { nodeHasChanged } = useOptionsCtx();
2397
2455
  React.useEffect(() => {
@@ -2408,7 +2466,7 @@ const Body = ({ body, onChange }) => {
2408
2466
  description && (React.createElement(Box, { pos: "relative" },
2409
2467
  React.createElement(MarkdownViewer, { markdown: description }),
2410
2468
  React.createElement(NodeAnnotation, { change: descriptionChanged }))),
2411
- isJSONSchema(schema) && (React.createElement(JsonSchemaViewer, { resolveRef: refResolver, schema: getOriginalObject(schema), viewMode: "write", renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))));
2469
+ isJSONSchema(schema) && (React.createElement(JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema), viewMode: "write", renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))));
2412
2470
  };
2413
2471
  Body.displayName = 'HttpOperation.Body';
2414
2472
 
@@ -2433,11 +2491,11 @@ const defaultStyle = {
2433
2491
  };
2434
2492
  const Parameters = ({ parameters, parameterType }) => {
2435
2493
  const { nodeHasChanged } = useOptionsCtx();
2436
- const refResolver = useSchemaInlineRefResolver();
2494
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2437
2495
  const schema = React.useMemo(() => httpOperationParamsToSchema({ parameters, parameterType }), [parameters, parameterType]);
2438
2496
  if (!schema)
2439
2497
  return null;
2440
- return React.createElement(JsonSchemaViewer, { resolveRef: refResolver, schema: schema, disableCrumbs: true, nodeHasChanged: nodeHasChanged });
2498
+ return (React.createElement(JsonSchemaViewer, { resolveRef: refResolver, maxRefDepth: maxRefDepth, schema: schema, disableCrumbs: true, nodeHasChanged: nodeHasChanged }));
2441
2499
  };
2442
2500
  Parameters.displayName = 'HttpOperation.Parameters';
2443
2501
  const httpOperationParamsToSchema = ({ parameters, parameterType }) => {
@@ -2571,7 +2629,7 @@ Responses.displayName = 'HttpOperation.Responses';
2571
2629
  const Response = ({ response, onMediaTypeChange }) => {
2572
2630
  const { contents = [], headers = [], description } = response;
2573
2631
  const [chosenContent, setChosenContent] = React.useState(0);
2574
- const refResolver = useSchemaInlineRefResolver();
2632
+ const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2575
2633
  const { nodeHasChanged } = useOptionsCtx();
2576
2634
  const responseContent = contents[chosenContent];
2577
2635
  const schema = responseContent === null || responseContent === void 0 ? void 0 : responseContent.schema;
@@ -2590,7 +2648,7 @@ const Response = ({ response, onMediaTypeChange }) => {
2590
2648
  React.createElement(SectionSubtitle, { title: "Body", id: "response-body" },
2591
2649
  React.createElement(Flex, { flex: 1, justify: "end" },
2592
2650
  React.createElement(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" }))),
2593
- schema && (React.createElement(JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, viewMode: "read", parentCrumbs: ['responses', response.code], renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))))));
2651
+ schema && (React.createElement(JsonSchemaViewer, { schema: getOriginalObject(schema), resolveRef: refResolver, maxRefDepth: maxRefDepth, viewMode: "read", parentCrumbs: ['responses', response.code], renderRootTreeLines: true, nodeHasChanged: nodeHasChanged }))))));
2594
2652
  };
2595
2653
  Response.displayName = 'HttpOperation.Response';
2596
2654
  const codeToIntentVal = (code) => {
@@ -2874,7 +2932,7 @@ const HttpService = withErrorBoundary(HttpServiceComponent, { recoverableProps:
2874
2932
 
2875
2933
  const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOptions, exportProps, }) => {
2876
2934
  var _a, _b;
2877
- const resolveRef = useSchemaInlineRefResolver();
2935
+ const [resolveRef, maxRefDepth] = useSchemaInlineRefResolver();
2878
2936
  const data = useResolvedObject(unresolvedData);
2879
2937
  const { nodeHasChanged } = useOptionsCtx();
2880
2938
  const { ref: layoutRef, isCompact } = useIsCompact(layoutOptions);
@@ -2900,7 +2958,7 @@ const ModelComponent = ({ data: unresolvedData, className, nodeTitle, layoutOpti
2900
2958
  React.createElement(MarkdownViewer, { role: "textbox", markdown: data.description }),
2901
2959
  React.createElement(NodeAnnotation, { change: descriptionChanged }))),
2902
2960
  isCompact && modelExamples,
2903
- React.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(data), nodeHasChanged: nodeHasChanged, skipTopLevelDescription: true })));
2961
+ React.createElement(JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(data), nodeHasChanged: nodeHasChanged, skipTopLevelDescription: true })));
2904
2962
  return (React.createElement(TwoColumnLayout, { ref: layoutRef, className: cn('Model', className), header: header, left: description, right: !isCompact && modelExamples }));
2905
2963
  };
2906
2964
  const ModelExamples = React.memo(({ data, isCollapsible = false }) => {
@@ -2923,7 +2981,7 @@ const Model = withErrorBoundary(ModelComponent, { recoverableProps: ['data'] });
2923
2981
 
2924
2982
  const Docs = React.memo((_a) => {
2925
2983
  var _b;
2926
- var { nodeType, nodeData, useNodeForRefResolving = false, refResolver, nodeHasChanged } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver", "nodeHasChanged"]);
2984
+ var { nodeType, nodeData, useNodeForRefResolving = false, refResolver, maxRefDepth, nodeHasChanged } = _a, commonProps = __rest(_a, ["nodeType", "nodeData", "useNodeForRefResolving", "refResolver", "maxRefDepth", "nodeHasChanged"]);
2927
2985
  const parsedNode = useParsedData(nodeType, nodeData);
2928
2986
  if (!parsedNode) {
2929
2987
  (_b = commonProps.nodeUnsupported) === null || _b === void 0 ? void 0 : _b.call(commonProps, 'dataEmpty');
@@ -2931,7 +2989,7 @@ const Docs = React.memo((_a) => {
2931
2989
  }
2932
2990
  let elem = React.createElement(ParsedDocs, Object.assign({ node: parsedNode }, commonProps));
2933
2991
  if (useNodeForRefResolving) {
2934
- elem = (React.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver }, elem));
2992
+ elem = (React.createElement(InlineRefResolverProvider, { document: parsedNode.data, resolver: refResolver, maxRefDepth: maxRefDepth }, elem));
2935
2993
  }
2936
2994
  return React.createElement(ElementsOptionsProvider, { nodeHasChanged: nodeHasChanged }, elem);
2937
2995
  });
@@ -3043,13 +3101,13 @@ function isPartialHttpRequest(maybeHttpRequest) {
3043
3101
  typeof maybeHttpRequest['url'] === 'string');
3044
3102
  }
3045
3103
  const SchemaAndDescription = ({ title: titleProp, schema }) => {
3046
- const resolveRef = useSchemaInlineRefResolver();
3104
+ const [resolveRef, maxRefDepth] = useSchemaInlineRefResolver();
3047
3105
  const title = titleProp !== null && titleProp !== void 0 ? titleProp : schema.title;
3048
3106
  return (React__default.createElement(Box, { py: 2 },
3049
3107
  title && (React__default.createElement(Flex, { alignItems: "center", p: 2 },
3050
3108
  React__default.createElement(Icon, { icon: NodeTypeIconDefs[NodeType.Model], color: NodeTypeColors[NodeType.Model] }),
3051
3109
  React__default.createElement(Box, { color: "muted", px: 2 }, title))),
3052
- React__default.createElement(JsonSchemaViewer, { resolveRef: resolveRef, schema: getOriginalObject(schema) })));
3110
+ React__default.createElement(JsonSchemaViewer, { resolveRef: resolveRef, maxRefDepth: maxRefDepth, schema: getOriginalObject(schema) })));
3053
3111
  };
3054
3112
  const CodeComponent = props => {
3055
3113
  const { title, jsonSchema, http, resolved, children } = props;
@@ -3060,7 +3118,7 @@ const CodeComponent = props => {
3060
3118
  if (!isJSONSchema(parsedValue)) {
3061
3119
  return null;
3062
3120
  }
3063
- return (React__default.createElement(InlineRefResolverProvider, { document: parsedValue, resolver: resolver },
3121
+ return (React__default.createElement(InlineRefResolverProvider, { document: parsedValue, resolver: resolver === null || resolver === void 0 ? void 0 : resolver.resolver, maxRefDepth: resolver === null || resolver === void 0 ? void 0 : resolver.maxRefDepth },
3064
3122
  React__default.createElement(SchemaAndDescription, { title: title, schema: parsedValue })));
3065
3123
  }
3066
3124
  if (http) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stoplight/elements-core",
3
- "version": "7.13.9",
3
+ "version": "7.15.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-viewer": "^4.12.1",
31
+ "@stoplight/json-schema-tree": "^2.3.0",
32
+ "@stoplight/json-schema-viewer": "^4.14.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",