Skip to content

Commit 64ecbfe

Browse files
committed
feat: resolveRef hook
1 parent ebcad8b commit 64ecbfe

File tree

4 files changed

+16
-6
lines changed

4 files changed

+16
-6
lines changed

src/components/JsonSchemaViewer.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { action } from 'mobx';
55
import * as React from 'react';
66

77
import { JSONSchema4 } from 'json-schema';
8-
import { SchemaTree } from '../tree/tree';
8+
import { SchemaTree, SchemaTreeRefDereferenceFn } from '../tree/tree';
99
import { GoToRefHandler, RowRenderer } from '../types';
1010
import { isSchemaViewerEmpty } from '../utils/isSchemaViewerEmpty';
1111
import { SchemaTree as SchemaTreeComponent } from './SchemaTree';
@@ -24,6 +24,7 @@ export interface IJsonSchemaViewer {
2424
mergeAllOf?: boolean;
2525
FallbackComponent?: typeof FallbackComponent;
2626
rowRenderer?: RowRenderer;
27+
resolveRef?: SchemaTreeRefDereferenceFn;
2728
}
2829

2930
export class JsonSchemaViewerComponent extends React.PureComponent<IJsonSchemaViewer & ErrorBoundaryForwardedProps> {
@@ -38,6 +39,7 @@ export class JsonSchemaViewerComponent extends React.PureComponent<IJsonSchemaVi
3839
this.tree = new SchemaTree(props.schema, this.treeState, {
3940
expandedDepth: this.expandedDepth,
4041
mergeAllOf: this.mergeAllOf,
42+
resolveRef: this.props.resolveRef,
4143
});
4244
this.treeStore = new TreeStore(this.tree, this.treeState, {
4345
defaultExpandedDepth: this.expandedDepth,

src/components/SchemaTree.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export interface ISchemaTree {
1010
treeStore: TreeStore;
1111
schema: JSONSchema4;
1212
name?: string;
13-
dereferencedSchema?: JSONSchema4;
1413
hideTopBar?: boolean;
1514
expanded?: boolean;
1615
maxRows?: number;

src/tree/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export { getNodeMetadata } from './metadata';
2-
export { SchemaTree, SchemaTreeState } from './tree';
2+
export { SchemaTree, SchemaTreeState, SchemaTreeRefDereferenceFn } from './tree';

src/tree/tree.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,33 @@
11
import { isLocalRef, pointerToPath } from '@stoplight/json';
22
import { Tree, TreeListParentNode, TreeState } from '@stoplight/tree-list';
3-
import { JsonPath } from '@stoplight/types';
3+
import { JsonPath, Optional } from '@stoplight/types';
44
import { JSONSchema4 } from 'json-schema';
5-
import { get as _get, isEqual as _isEqual } from 'lodash';
5+
import { get as _get, isEqual as _isEqual, isObject as _isObject } from 'lodash';
66
import { isRefNode } from '../utils/guards';
77
import { getNodeMetadata, metadataStore } from './metadata';
88
import { populateTree } from './populateTree';
99

10+
export type SchemaTreeRefDereferenceFn = (path: JsonPath, schema: JSONSchema4) => Optional<JSONSchema4>;
11+
1012
export type SchemaTreeOptions = {
1113
expandedDepth: number;
1214
mergeAllOf: boolean;
15+
resolveRef: Optional<SchemaTreeRefDereferenceFn>;
1316
};
1417

1518
export { TreeState as SchemaTreeState };
1619

1720
export class SchemaTree extends Tree {
1821
public expandedDepth: number;
1922
public mergeAllOf: boolean;
23+
protected resolveRef: Optional<SchemaTreeRefDereferenceFn>;
2024

2125
constructor(public schema: JSONSchema4, public state: TreeState, opts: SchemaTreeOptions) {
2226
super();
2327

2428
this.expandedDepth = opts.expandedDepth;
2529
this.mergeAllOf = opts.mergeAllOf;
30+
this.resolveRef = opts.resolveRef;
2631
}
2732

2833
protected readonly visited = new WeakSet();
@@ -78,7 +83,11 @@ export class SchemaTree extends Tree {
7883
const { path, schemaNode, schema } = metadata;
7984
if (isRefNode(schemaNode)) {
8085
const refPath = pointerToPath(schemaNode.$ref);
81-
const schemaFragment = _get(this.schema, refPath);
86+
const schemaFragment = this.resolveRef ? this.resolveRef(refPath, this.schema) : _get(this.schema, refPath);
87+
if (!_isObject(schemaFragment)) {
88+
throw new ReferenceError(`Could not dereference ${refPath.join('.')}`);
89+
}
90+
8291
this.populateTreeFragment(node, schemaFragment, path);
8392
metadata.schema = schemaFragment;
8493
} else {

0 commit comments

Comments
 (0)