Skip to content

Commit 6d262d9

Browse files
authored
feat: accept JSON Schema Draft 6 & Draft 7 (#138)
1 parent 5304cb4 commit 6d262d9

28 files changed

+146
-127
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@
4242
"react-dom": ">=16.8"
4343
},
4444
"dependencies": {
45+
"@types/json-schema": "^7.0.7",
4546
"@stoplight/json": "^3.5.1",
4647
"@stoplight/json-schema-merge-allof": "^0.7.2",
4748
"@stoplight/react-error-boundary": "^1.0.0",
4849
"@stoplight/tree-list": "^5.0.3",
50+
"@stoplight/types": "^12.0.0",
4951
"classnames": "^2.2.6",
50-
"lodash": "^4.17.15",
52+
"lodash": "^4.17.21",
5153
"mobx-react-lite": "^1.4.1",
5254
"pluralize": "^8.0.0"
5355
},
@@ -60,12 +62,10 @@
6062
"@stoplight/markdown-viewer": "^3.5.5",
6163
"@stoplight/scripts": "^8.2.0",
6264
"@stoplight/storybook-config": "^2.0.5",
63-
"@stoplight/types": "11.0.0",
6465
"@stoplight/ui-kit": "3.0.0-beta.2",
6566
"@types/classnames": "^2.2.9",
6667
"@types/enzyme": "3.10.3",
6768
"@types/jest": "^24.0.18",
68-
"@types/json-schema": "^7.0.3",
6969
"@types/lodash": "^4.14.149",
7070
"@types/node": "^12.7.2",
7171
"@types/pluralize": "^0.0.29",

src/components/JsonSchemaViewer.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ import cn from 'classnames';
44
import { action } from 'mobx';
55
import * as React from 'react';
66

7-
import { JSONSchema4 } from 'json-schema';
87
import { SchemaTree, SchemaTreeOptions, SchemaTreePopulateHandler, SchemaTreeRefDereferenceFn } from '../tree/tree';
9-
import { GoToRefHandler, RowRenderer, ViewMode } from '../types';
8+
import { GoToRefHandler, JSONSchema, RowRenderer, ViewMode } from '../types';
109
import { isSchemaViewerEmpty } from '../utils/isSchemaViewerEmpty';
1110
import { SchemaTree as SchemaTreeComponent } from './SchemaTree';
1211

1312
export interface IJsonSchemaViewer {
14-
schema: JSONSchema4;
13+
schema: JSONSchema;
1514
style?: object;
1615
emptyText?: string;
1716
defaultExpandedDepth?: number;

src/components/SchemaRow.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { IRowRendererOptions, isParentNode, Tree } from '@stoplight/tree-list';
22
import cn from 'classnames';
3-
import { JSONSchema4 } from 'json-schema';
43
import * as React from 'react';
54

65
import { getNodeMetadata, getSchemaNodeMetadata } from '../tree/metadata';
7-
import { GoToRefHandler, SchemaKind, SchemaTreeListNode } from '../types';
6+
import { GoToRefHandler, JSONSchema, SchemaKind, SchemaTreeListNode } from '../types';
87
import { getPrimaryType } from '../utils/getPrimaryType';
98
import { hasRefItems, isArrayNodeWithItems, isRefNode } from '../utils/guards';
109
import { Caret, Description, Divider, Format, Property, Validations } from './shared';
@@ -20,7 +19,7 @@ const ICON_SIZE = 12;
2019
const ICON_DIMENSION = 20;
2120
const ROW_OFFSET = 7;
2221

23-
function getRelevantSchemaForRequireCheck(treeNode: SchemaTreeListNode): JSONSchema4 | JSONSchema4[] | null {
22+
function getRelevantSchemaForRequireCheck(treeNode: SchemaTreeListNode): JSONSchema | JSONSchema[] | null {
2423
const metadata = getNodeMetadata(treeNode);
2524
if (!('schemaNode' in metadata)) return null;
2625
if (isArrayNodeWithItems(metadata.schemaNode)) {

src/components/SchemaTree.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { TreeList, TreeListEvents, TreeStore } from '@stoplight/tree-list';
2-
import { JSONSchema4 } from 'json-schema';
32
import { observer } from 'mobx-react-lite';
43
import * as React from 'react';
54

6-
import { GoToRefHandler, RowRenderer } from '../types';
5+
import { GoToRefHandler, JSONSchema, RowRenderer } from '../types';
76
import { SchemaRow } from './SchemaRow';
87

98
export interface ISchemaTree {
109
treeStore: TreeStore;
11-
schema: JSONSchema4;
10+
schema: JSONSchema;
1211
name?: string;
1312
hideTopBar?: boolean;
1413
expanded?: boolean;

src/components/shared/Divider.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Dictionary } from '@stoplight/types';
22
import * as React from 'react';
3-
import { JSONSchema4CombinerName } from '../../types';
3+
import { JSONSchemaCombinerName } from '../../types';
44

5-
const DIVIDERS: Dictionary<string, JSONSchema4CombinerName> = {
5+
const DIVIDERS: Dictionary<string, JSONSchemaCombinerName> = {
66
allOf: 'and',
77
anyOf: 'and/or',
88
oneOf: 'or',
99
};
1010

11-
export const Divider: React.FunctionComponent<{ kind: JSONSchema4CombinerName }> = ({ kind }) => (
11+
export const Divider: React.FunctionComponent<{ kind: JSONSchemaCombinerName }> = ({ kind }) => (
1212
<div className="flex items-center w-full absolute" style={{ top: -9, height: 1 }}>
1313
<div className="text-darken-7 dark:text-lighten-8 uppercase text-xs pr-2 -ml-4">{DIVIDERS[kind]}</div>
1414
<div className="flex-1 bg-darken-5 dark:bg-lighten-5" style={{ height: 1 }} />

src/components/shared/Types.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import { Dictionary, Optional } from '@stoplight/types';
22
import cn from 'classnames';
3-
import { JSONSchema4TypeName } from 'json-schema';
43
import * as React from 'react';
54

6-
import { JSONSchema4CombinerName, SchemaKind } from '../../types';
5+
import { JSONSchema, JSONSchemaCombinerName, JSONSchemaTypeName, SchemaKind } from '../../types';
76

87
/**
98
* TYPE
109
*/
1110
export interface IType {
12-
type: JSONSchema4TypeName | JSONSchema4CombinerName | 'binary' | '$ref';
13-
subtype: Optional<JSONSchema4TypeName | JSONSchema4TypeName[]> | '$ref';
11+
type: JSONSchemaTypeName | JSONSchemaCombinerName | 'binary' | '$ref';
12+
subtype: JSONSchema['type'] | '$ref';
1413
className?: string;
1514
title: Optional<string>;
1615
}
@@ -61,8 +60,8 @@ Type.displayName = 'JsonSchemaViewer.Type';
6160
*/
6261
interface ITypes {
6362
className?: string;
64-
type: Optional<JSONSchema4TypeName | JSONSchema4TypeName[] | JSONSchema4CombinerName | '$ref'>;
65-
subtype: Optional<JSONSchema4TypeName | JSONSchema4TypeName[] | '$ref'>;
63+
type: Optional<JSONSchemaTypeName | JSONSchemaTypeName[] | JSONSchemaCombinerName | '$ref'>;
64+
subtype: Optional<JSONSchema['type'] | '$ref'>;
6665
title: Optional<string>;
6766
}
6867

src/components/shared/Validations.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { safeStringify } from '@stoplight/json';
22
import { Dictionary } from '@stoplight/types';
33
import { Popover } from '@stoplight/ui-kit';
4-
import { JSONSchema4 } from 'json-schema';
54
import * as React from 'react';
5+
import { JSONSchema } from '../../types';
66
import { ViewModeContext } from '../JsonSchemaViewer';
77
import { PropertyTypeColors } from './Types';
88

@@ -93,7 +93,7 @@ export const Validations: React.FunctionComponent<IValidations> = ({
9393
);
9494
};
9595

96-
export const Format: React.FunctionComponent<{ schema: JSONSchema4 }> = ({ schema }) => {
96+
export const Format: React.FunctionComponent<{ schema: JSONSchema }> = ({ schema }) => {
9797
return (
9898
<div
9999
{...(typeof schema.type === 'string' && schema.type in PropertyTypeColors

src/tree/__tests__/utils/printTree.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { pathToPointer } from '@stoplight/json';
22
import * as treeify from 'treeify';
33

44
import { TreeListNode } from '@stoplight/tree-list';
5-
import { JSONSchema4CombinerName } from '../../../types';
5+
import { JSONSchemaCombinerName } from '../../../types';
66
import { hasRefItems, isArrayNodeWithItems } from '../../../utils/guards';
77
import { inferType } from '../../../utils/inferType';
88
import { getNodeMetadata } from '../../metadata';
@@ -18,7 +18,7 @@ export function printTree(tree: SchemaTree) {
1818
type PrintableNode = {
1919
[key in string]: {
2020
type?: unknown;
21-
combiner?: JSONSchema4CombinerName;
21+
combiner?: JSONSchemaCombinerName;
2222
enum?: unknown;
2323
required?: unknown;
2424
subtype?: unknown;

src/tree/metadata.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { TreeListNode } from '@stoplight/tree-list';
22
import { JsonPath } from '@stoplight/types';
3-
import { JSONSchema4 } from 'json-schema';
4-
import { SchemaNode, SchemaTreeListNode } from '../types';
3+
import { JSONSchema, SchemaNode, SchemaTreeListNode } from '../types';
54

65
export interface ITreeNodeMetaSchema {
76
path: JsonPath;
87
schemaNode: SchemaNode;
9-
schema: JSONSchema4;
8+
schema: JSONSchema;
109
}
1110

1211
export interface ITreeNodeMetaError {

src/tree/tree.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { extractPointerFromRef, extractSourceFromRef, pointerToPath } from '@stoplight/json';
22
import { Tree, TreeListParentNode, TreeState } from '@stoplight/tree-list';
33
import { JsonPath, Optional } from '@stoplight/types';
4-
import { JSONSchema4 } from 'json-schema';
54
import { get as _get, isEqual as _isEqual, isObject as _isObject } from 'lodash';
65
import { ResolvingError } from '../errors';
7-
import { IArrayNode, IObjectNode, SchemaKind, SchemaNode, ViewMode } from '../types';
6+
import { IArrayNode, IObjectNode, JSONSchema, SchemaKind, SchemaNode, ViewMode } from '../types';
87
import { hasRefItems, isArrayNodeWithItems, isCombinerNode, isRefNode } from '../utils/guards';
98
import { inferType } from '../utils/inferType';
109
import { getSchemaNodeMetadata } from './metadata';
@@ -20,8 +19,8 @@ export type SchemaTreeRefInfo = {
2019
export type SchemaTreeRefDereferenceFn = (
2120
ref: SchemaTreeRefInfo,
2221
propertyPath: JsonPath | null,
23-
schema: JSONSchema4,
24-
) => Optional<JSONSchema4>;
22+
schema: JSONSchema,
23+
) => Optional<JSONSchema>;
2524

2625
export type SchemaTreePopulateHandler = (tree: SchemaTree, node: TreeListParentNode) => void;
2726

@@ -39,7 +38,7 @@ export { TreeState as SchemaTreeState };
3938
export class SchemaTree extends Tree {
4039
public treeOptions: SchemaTreeOptions;
4140

42-
constructor(public schema: JSONSchema4, public state: TreeState, opts: SchemaTreeOptions) {
41+
constructor(public schema: JSONSchema, public state: TreeState, opts: SchemaTreeOptions) {
4342
super({
4443
expanded: node =>
4544
(!(node.id in state.expanded) && SchemaTree.getLevel(node) <= opts.expandedDepth) ||
@@ -51,7 +50,11 @@ export class SchemaTree extends Tree {
5150

5251
protected readonly visited = new WeakSet();
5352

54-
protected isViewModeRespected = (fragment: JSONSchema4) => {
53+
protected isViewModeRespected = (fragment: JSONSchema) => {
54+
if (!('writeOnly' in fragment) && !('readOnly' in fragment)) {
55+
return true;
56+
}
57+
5558
return !(
5659
!!fragment.writeOnly !== !!fragment.readOnly &&
5760
((this.treeOptions.viewMode === 'read' && fragment.writeOnly) ||
@@ -112,7 +115,7 @@ export class SchemaTree extends Tree {
112115
this.treeOptions.onPopulate?.(this, this.root);
113116
}
114117

115-
public populateTreeFragment(parent: TreeListParentNode, schema: JSONSchema4, path: JsonPath, stepIn: boolean) {
118+
public populateTreeFragment(parent: TreeListParentNode, schema: JSONSchema, path: JsonPath, stepIn: boolean) {
116119
const initialLevel = Tree.getLevel(parent);
117120
const artificialRoot = Tree.createArtificialRoot();
118121
populateTree(schema, artificialRoot, initialLevel, path, {

0 commit comments

Comments
 (0)