Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@
"react-dom": ">=16.8"
},
"dependencies": {
"@types/json-schema": "^7.0.7",
"@stoplight/json": "^3.5.1",
"@stoplight/json-schema-merge-allof": "^0.7.2",
"@stoplight/react-error-boundary": "^1.0.0",
"@stoplight/tree-list": "^5.0.3",
"@stoplight/types": "^12.0.0",
"classnames": "^2.2.6",
"lodash": "^4.17.15",
"lodash": "^4.17.21",
"mobx-react-lite": "^1.4.1",
"pluralize": "^8.0.0"
},
Expand All @@ -60,12 +62,10 @@
"@stoplight/markdown-viewer": "^3.5.5",
"@stoplight/scripts": "^8.2.0",
"@stoplight/storybook-config": "^2.0.5",
"@stoplight/types": "11.0.0",
"@stoplight/ui-kit": "3.0.0-beta.2",
"@types/classnames": "^2.2.9",
"@types/enzyme": "3.10.3",
"@types/jest": "^24.0.18",
"@types/json-schema": "^7.0.3",
"@types/lodash": "^4.14.149",
"@types/node": "^12.7.2",
"@types/pluralize": "^0.0.29",
Expand Down
5 changes: 2 additions & 3 deletions src/components/JsonSchemaViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import cn from 'classnames';
import { action } from 'mobx';
import * as React from 'react';

import { JSONSchema4 } from 'json-schema';
import { SchemaTree, SchemaTreeOptions, SchemaTreePopulateHandler, SchemaTreeRefDereferenceFn } from '../tree/tree';
import { GoToRefHandler, RowRenderer, ViewMode } from '../types';
import { GoToRefHandler, JSONSchema, RowRenderer, ViewMode } from '../types';
import { isSchemaViewerEmpty } from '../utils/isSchemaViewerEmpty';
import { SchemaTree as SchemaTreeComponent } from './SchemaTree';

export interface IJsonSchemaViewer {
schema: JSONSchema4;
schema: JSONSchema;
style?: object;
emptyText?: string;
defaultExpandedDepth?: number;
Expand Down
5 changes: 2 additions & 3 deletions src/components/SchemaRow.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { IRowRendererOptions, isParentNode, Tree } from '@stoplight/tree-list';
import cn from 'classnames';
import { JSONSchema4 } from 'json-schema';
import * as React from 'react';

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

function getRelevantSchemaForRequireCheck(treeNode: SchemaTreeListNode): JSONSchema4 | JSONSchema4[] | null {
function getRelevantSchemaForRequireCheck(treeNode: SchemaTreeListNode): JSONSchema | JSONSchema[] | null {
const metadata = getNodeMetadata(treeNode);
if (!('schemaNode' in metadata)) return null;
if (isArrayNodeWithItems(metadata.schemaNode)) {
Expand Down
5 changes: 2 additions & 3 deletions src/components/SchemaTree.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { TreeList, TreeListEvents, TreeStore } from '@stoplight/tree-list';
import { JSONSchema4 } from 'json-schema';
import { observer } from 'mobx-react-lite';
import * as React from 'react';

import { GoToRefHandler, RowRenderer } from '../types';
import { GoToRefHandler, JSONSchema, RowRenderer } from '../types';
import { SchemaRow } from './SchemaRow';

export interface ISchemaTree {
treeStore: TreeStore;
schema: JSONSchema4;
schema: JSONSchema;
name?: string;
hideTopBar?: boolean;
expanded?: boolean;
Expand Down
6 changes: 3 additions & 3 deletions src/components/shared/Divider.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Dictionary } from '@stoplight/types';
import * as React from 'react';
import { JSONSchema4CombinerName } from '../../types';
import { JSONSchemaCombinerName } from '../../types';

const DIVIDERS: Dictionary<string, JSONSchema4CombinerName> = {
const DIVIDERS: Dictionary<string, JSONSchemaCombinerName> = {
allOf: 'and',
anyOf: 'and/or',
oneOf: 'or',
};

export const Divider: React.FunctionComponent<{ kind: JSONSchema4CombinerName }> = ({ kind }) => (
export const Divider: React.FunctionComponent<{ kind: JSONSchemaCombinerName }> = ({ kind }) => (
<div className="flex items-center w-full absolute" style={{ top: -9, height: 1 }}>
<div className="text-darken-7 dark:text-lighten-8 uppercase text-xs pr-2 -ml-4">{DIVIDERS[kind]}</div>
<div className="flex-1 bg-darken-5 dark:bg-lighten-5" style={{ height: 1 }} />
Expand Down
11 changes: 5 additions & 6 deletions src/components/shared/Types.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Dictionary, Optional } from '@stoplight/types';
import cn from 'classnames';
import { JSONSchema4TypeName } from 'json-schema';
import * as React from 'react';

import { JSONSchema4CombinerName, SchemaKind } from '../../types';
import { JSONSchema, JSONSchemaCombinerName, JSONSchemaTypeName, SchemaKind } from '../../types';

/**
* TYPE
*/
export interface IType {
type: JSONSchema4TypeName | JSONSchema4CombinerName | 'binary' | '$ref';
subtype: Optional<JSONSchema4TypeName | JSONSchema4TypeName[]> | '$ref';
type: JSONSchemaTypeName | JSONSchemaCombinerName | 'binary' | '$ref';
subtype: JSONSchema['type'] | '$ref';
className?: string;
title: Optional<string>;
}
Expand Down Expand Up @@ -61,8 +60,8 @@ Type.displayName = 'JsonSchemaViewer.Type';
*/
interface ITypes {
className?: string;
type: Optional<JSONSchema4TypeName | JSONSchema4TypeName[] | JSONSchema4CombinerName | '$ref'>;
subtype: Optional<JSONSchema4TypeName | JSONSchema4TypeName[] | '$ref'>;
type: Optional<JSONSchemaTypeName | JSONSchemaTypeName[] | JSONSchemaCombinerName | '$ref'>;
subtype: Optional<JSONSchema['type'] | '$ref'>;
title: Optional<string>;
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/shared/Validations.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { safeStringify } from '@stoplight/json';
import { Dictionary } from '@stoplight/types';
import { Popover } from '@stoplight/ui-kit';
import { JSONSchema4 } from 'json-schema';
import * as React from 'react';
import { JSONSchema } from '../../types';
import { ViewModeContext } from '../JsonSchemaViewer';
import { PropertyTypeColors } from './Types';

Expand Down Expand Up @@ -93,7 +93,7 @@ export const Validations: React.FunctionComponent<IValidations> = ({
);
};

export const Format: React.FunctionComponent<{ schema: JSONSchema4 }> = ({ schema }) => {
export const Format: React.FunctionComponent<{ schema: JSONSchema }> = ({ schema }) => {
return (
<div
{...(typeof schema.type === 'string' && schema.type in PropertyTypeColors
Expand Down
4 changes: 2 additions & 2 deletions src/tree/__tests__/utils/printTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { pathToPointer } from '@stoplight/json';
import * as treeify from 'treeify';

import { TreeListNode } from '@stoplight/tree-list';
import { JSONSchema4CombinerName } from '../../../types';
import { JSONSchemaCombinerName } from '../../../types';
import { hasRefItems, isArrayNodeWithItems } from '../../../utils/guards';
import { inferType } from '../../../utils/inferType';
import { getNodeMetadata } from '../../metadata';
Expand All @@ -18,7 +18,7 @@ export function printTree(tree: SchemaTree) {
type PrintableNode = {
[key in string]: {
type?: unknown;
combiner?: JSONSchema4CombinerName;
combiner?: JSONSchemaCombinerName;
enum?: unknown;
required?: unknown;
subtype?: unknown;
Expand Down
5 changes: 2 additions & 3 deletions src/tree/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { TreeListNode } from '@stoplight/tree-list';
import { JsonPath } from '@stoplight/types';
import { JSONSchema4 } from 'json-schema';
import { SchemaNode, SchemaTreeListNode } from '../types';
import { JSONSchema, SchemaNode, SchemaTreeListNode } from '../types';

export interface ITreeNodeMetaSchema {
path: JsonPath;
schemaNode: SchemaNode;
schema: JSONSchema4;
schema: JSONSchema;
}

export interface ITreeNodeMetaError {
Expand Down
17 changes: 10 additions & 7 deletions src/tree/tree.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { extractPointerFromRef, extractSourceFromRef, pointerToPath } from '@stoplight/json';
import { Tree, TreeListParentNode, TreeState } from '@stoplight/tree-list';
import { JsonPath, Optional } from '@stoplight/types';
import { JSONSchema4 } from 'json-schema';
import { get as _get, isEqual as _isEqual, isObject as _isObject } from 'lodash';
import { ResolvingError } from '../errors';
import { IArrayNode, IObjectNode, SchemaKind, SchemaNode, ViewMode } from '../types';
import { IArrayNode, IObjectNode, JSONSchema, SchemaKind, SchemaNode, ViewMode } from '../types';
import { hasRefItems, isArrayNodeWithItems, isCombinerNode, isRefNode } from '../utils/guards';
import { inferType } from '../utils/inferType';
import { getSchemaNodeMetadata } from './metadata';
Expand All @@ -20,8 +19,8 @@ export type SchemaTreeRefInfo = {
export type SchemaTreeRefDereferenceFn = (
ref: SchemaTreeRefInfo,
propertyPath: JsonPath | null,
schema: JSONSchema4,
) => Optional<JSONSchema4>;
schema: JSONSchema,
) => Optional<JSONSchema>;

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

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

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

protected readonly visited = new WeakSet();

protected isViewModeRespected = (fragment: JSONSchema4) => {
protected isViewModeRespected = (fragment: JSONSchema) => {
if (!('writeOnly' in fragment) && !('readOnly' in fragment)) {
return true;
}

return !(
!!fragment.writeOnly !== !!fragment.readOnly &&
((this.treeOptions.viewMode === 'read' && fragment.writeOnly) ||
Expand Down Expand Up @@ -112,7 +115,7 @@ export class SchemaTree extends Tree {
this.treeOptions.onPopulate?.(this, this.root);
}

public populateTreeFragment(parent: TreeListParentNode, schema: JSONSchema4, path: JsonPath, stepIn: boolean) {
public populateTreeFragment(parent: TreeListParentNode, schema: JSONSchema, path: JsonPath, stepIn: boolean) {
const initialLevel = Tree.getLevel(parent);
const artificialRoot = Tree.createArtificialRoot();
populateTree(schema, artificialRoot, initialLevel, path, {
Expand Down
4 changes: 2 additions & 2 deletions src/tree/utils/__tests__/walk.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { JSONSchema4 } from 'json-schema';
import { JSONSchema4CombinerName, SchemaKind } from '../../../types';
import { JSONSchemaCombinerName, SchemaKind } from '../../../types';
import { walk } from '../walk';

describe('Schema Walker', () => {
Expand Down Expand Up @@ -100,7 +100,7 @@ describe('Schema Walker', () => {
});

describe('title', () => {
describe.each<JSONSchema4CombinerName>(['allOf', 'oneOf', 'anyOf'])('when combiner equals %s', combiner => {
describe.each<JSONSchemaCombinerName>(['allOf', 'oneOf', 'anyOf'])('when combiner equals %s', combiner => {
test.each([null, 2, void 0, false, true, 0, {}, []])('should ignore %s invalid title', title => {
const schema = {
[combiner]: [],
Expand Down
5 changes: 2 additions & 3 deletions src/tree/utils/canStepIn.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { JSONSchema4 } from 'json-schema';
import { SchemaKind } from '../../types';
import { JSONSchema, SchemaKind } from '../../types';
import { getCombiners } from '../../utils/getCombiners';
import { getPrimaryType } from '../../utils/getPrimaryType';

export const canStepIn = (fragment: JSONSchema4) => {
export const canStepIn = (fragment: JSONSchema) => {
if (getCombiners(fragment) !== void 0) {
return true;
}
Expand Down
10 changes: 5 additions & 5 deletions src/tree/utils/mergeAllOf.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { pathToPointer, safeStringify } from '@stoplight/json';
import { JsonPath } from '@stoplight/types';
import { JSONSchema4 } from 'json-schema';
import { ResolvingError } from '../../errors';
import { JSONSchema } from '../../types';
import { WalkingOptions } from './populateTree';

const resolveAllOf = require('@stoplight/json-schema-merge-allof');

const store = new WeakMap<WalkingOptions, WeakMap<JSONSchema4, string[]>>();
const store = new WeakMap<WalkingOptions, WeakMap<JSONSchema, string[]>>();

function _mergeAllOf(schema: JSONSchema4, path: JsonPath, opts: WalkingOptions) {
function _mergeAllOf(schema: JSONSchema, path: JsonPath, opts: WalkingOptions) {
return resolveAllOf(schema, {
deep: false,
resolvers: resolveAllOf.stoplightResolvers,
Expand Down Expand Up @@ -38,7 +38,7 @@ function _mergeAllOf(schema: JSONSchema4, path: JsonPath, opts: WalkingOptions)

if (Array.isArray(resolved.allOf)) {
for (const member of resolved.allOf) {
if (typeof member.$ref === 'string' && schemaRefs.includes(member.$ref)) {
if (typeof member !== 'boolean' && typeof member.$ref === 'string' && schemaRefs.includes(member.$ref)) {
throw new ResolvingError('Circular reference detected');
}
}
Expand All @@ -49,7 +49,7 @@ function _mergeAllOf(schema: JSONSchema4, path: JsonPath, opts: WalkingOptions)
});
}

export const mergeAllOf = (schema: JSONSchema4, path: JsonPath, opts: WalkingOptions) => {
export const mergeAllOf = (schema: JSONSchema, path: JsonPath, opts: WalkingOptions) => {
try {
if (!store.has(opts)) {
store.set(opts, new WeakMap());
Expand Down
13 changes: 7 additions & 6 deletions src/tree/utils/mergeOneOrAnyOf.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { JsonPath } from '@stoplight/types';
import { JSONSchema4 } from 'json-schema';
import { isObject } from 'lodash';
import { JSONSchema } from '../../types';
import { mergeAllOf } from './mergeAllOf';
import { WalkingOptions } from './populateTree';

export function mergeOneOrAnyOf(
schema: JSONSchema4,
schema: JSONSchema,
combiner: 'oneOf' | 'anyOf',
path: JsonPath,
options: WalkingOptions,
): JSONSchema4[] {
): JSONSchema[] {
const items = schema[combiner];

if (!Array.isArray(items)) return []; // just in case

const merged: JSONSchema4[] = [];
const merged: JSONSchema[] = [];

if (Array.isArray(schema.allOf) && Array.isArray(items)) {
for (const item of items) {
merged.push({
allOf: [...schema.allOf, item],
allOf: [...schema.allOf, item].filter<object>(isObject),
});
}

Expand All @@ -31,7 +32,7 @@ export function mergeOneOrAnyOf(
merged.push(
mergeAllOf(
{
allOf: [prunedSchema, item],
allOf: [prunedSchema, item].filter<object>(isObject),
},
path,
options,
Expand Down
Loading