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 { getPrimaryType } from '../utils/getPrimaryType';
import { hasRefItems, isArrayNodeWithItems, isRefNode } from '../utils/guards';
import { Caret, Description, Divider, Format, Property, Validations } from './shared';
export interface ISchemaRow {
className?: string;
node: SchemaTreeListNode;
rowOptions: IRowRendererOptions;
onGoToRef?: GoToRefHandler;
}
const ICON_SIZE = 12;
const ICON_DIMENSION = 20;
const ROW_OFFSET = 7;
function getRelevantSchemaForRequireCheck(treeNode: SchemaTreeListNode): JSONSchema4 | JSONSchema4[] | null {
const metadata = getNodeMetadata(treeNode);
if (!('schemaNode' in metadata)) return null;
if (isArrayNodeWithItems(metadata.schemaNode)) {
return metadata.schemaNode.items;
}
return metadata.schema;
}
function isRequired(treeNode: SchemaTreeListNode) {
if (treeNode.parent === null) return false;
try {
const { path } = getSchemaNodeMetadata(treeNode);
if (path.length === 0) {
return false;
}
const schema = getRelevantSchemaForRequireCheck(treeNode.parent);
return (
schema !== null &&
!Array.isArray(schema) &&
getPrimaryType(schema) === SchemaKind.Object &&
Array.isArray(schema.required) &&
schema.required.includes(String(path[path.length - 1]))
);
} catch {
return false;
}
}
export const SchemaPropertyRow: typeof SchemaRow = ({ node, onGoToRef, rowOptions }) => {
const metadata = getSchemaNodeMetadata(node);
const { schemaNode } = metadata;
const parentSchemaNode =
(node.parent !== null && Tree.getLevel(node.parent) >= 0 && getSchemaNodeMetadata(node.parent)?.schemaNode) || null;
const description = 'annotations' in schemaNode ? schemaNode.annotations.description : null;
const has$Ref = isRefNode(schemaNode) || (getPrimaryType(schemaNode) === SchemaKind.Array && hasRefItems(schemaNode));
return (
<>
{has$Ref || (isParentNode(node) && Tree.getLevel(node) > 0) ? (