/* eslint-disable */ import { Color } from '@yaakapp-internal/plugins'; import classNames from 'classnames'; import type { GraphQLField, GraphQLInputField, GraphQLType } from 'graphql'; import { getNamedType, isEnumType, isInputObjectType, isInterfaceType, isListType, isNonNullType, isObjectType, isScalarType, isUnionType, } from 'graphql'; import { useAtomValue } from 'jotai'; import { ReactNode, useState } from 'react'; import { graphqlDocStateAtom, graphqlSchemaAtom } from '../atoms/graphqlSchemaAtom'; import { jotaiStore } from '../lib/jotai'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; import { Markdown } from './Markdown'; type ExplorerItem = | { kind: 'type'; type: GraphQLType; from: ExplorerItem } | { kind: 'field'; type: GraphQLField; from: ExplorerItem } | { kind: 'input_field'; type: GraphQLInputField; from: ExplorerItem } | null; export function GraphQLDocsExplorer() { const graphqlSchema = useAtomValue(graphqlSchemaAtom); const [activeItem, setActiveItem] = useState(null); if (!graphqlSchema) { return
No GraphQL schema available
; } const qryType = graphqlSchema.getQueryType(); const mutType = graphqlSchema.getMutationType(); const subType = graphqlSchema.getSubscriptionType(); const qryItem: ExplorerItem = qryType ? { kind: 'type', type: qryType, from: null } : null; const mutItem: ExplorerItem = mutType ? { kind: 'type', type: mutType, from: null } : null; const subItem: ExplorerItem = subType ? { kind: 'type', type: subType, from: null } : null; const allTypes = graphqlSchema.getTypeMap(); return (
{ jotaiStore.set(graphqlDocStateAtom, false); }} /> {activeItem == null ? (
Root Types All Schema Types {graphqlSchema.description ?? null}
{Object.keys(allTypes).map((typeName) => { const t = allTypes[typeName]!; return ( ); })}
) : (
)}
); } function GraphQLExplorerHeader({ item, setItem, }: { item: ExplorerItem; setItem: (t: ExplorerItem) => void; }) { if (item == null) return null; return ( ); } function GqlTypeInfo({ item, setItem, }: { item: ExplorerItem | null; setItem: (t: ExplorerItem) => void; }) { const graphqlSchema = useAtomValue(graphqlSchemaAtom); if (item == null) return null; const name = item.kind === 'type' ? getNamedType(item.type).name : item.type.name; const description = item.kind === 'type' ? getNamedType(item.type).description : item.type.description; const heading = (

{name}

{description || 'No description'}
); if (isScalarType(item.type)) { return heading; } else if (isInterfaceType(item.type)) { const fields = item.type.getFields(); const possibleTypes = graphqlSchema?.getPossibleTypes(item.type) ?? []; return (
{heading} Fields {Object.keys(fields).map((fieldName) => { const field = fields[fieldName]!; const fieldItem: ExplorerItem = { kind: 'field', type: field, from: item }; return (
); })} {possibleTypes.length > 0 && ( <> Implemented By {possibleTypes.map((t) => ( ))} )}
); } else if (isUnionType(item.type)) { const types = item.type.getTypes(); return (
{heading} Possible Types {types.map((t) => ( ))}
); } else if (isEnumType(item.type)) { const values = item.type.getValues(); return (
{heading}
Type
Values {values.map((v) => (
{v.value} {v.description ?? null}
))}
); } else if (item.kind === 'field') { return (
{heading}
Type
{item.type.args.length > 0 && (
Arguments {item.type.args.map((a) => (
))}
)}
); } else if (item.kind === 'input_field' && isInputObjectType(item.type)) { const fields = item.type.getFields(); return (
{heading} Fields {Object.keys(fields).map((fieldName) => { const field = fields[fieldName]; if (field == null) return null; const fieldItem: ExplorerItem = { kind: 'input_field', type: field, from: item, }; return (
); })}
); } else if (item.kind === 'type' && isInputObjectType(item.type)) { const fields = item.type.getFields(); return (
{heading} Fields {Object.keys(fields).map((fieldName) => { const field = fields[fieldName]; if (field == null) return null; const fieldItem: ExplorerItem = { kind: 'input_field', type: field, from: item, }; return (
); })}
); } else if (item.kind === 'type' && isObjectType(item.type)) { const fields = item.type.getFields(); return (
{heading} Fields {Object.keys(fields).map((fieldName) => { const field = fields[fieldName]; if (field == null) return null; const fieldItem: ExplorerItem = { kind: 'field', type: field, from: item }; return (
); })}
); } console.log('Unknown GraphQL Type', item); return
Unknown GraphQL type
; } function GqlTypeRow({ item, setItem, name, description, className, hideDescription, }: { item: ExplorerItem; name?: { value: string; color: Color }; description?: string | null; setItem: (t: ExplorerItem) => void; className?: string; hideDescription?: boolean; }) { if (item == null) return null; let child: ReactNode = <>Unknown Type; if (item.kind === 'type') { child = ( <>
{name && ( {name.value}: )}{' '}
{!hideDescription && ( {(description === undefined ? getNamedType(item.type).description : description) ?? null} )} ); } else if (item.kind === 'field') { const returnItem: ExplorerItem = { kind: 'type', type: item.type.type, from: item.from, }; child = (
{name?.value} {item.type.args.length > 0 && ( <> ( {item.type.args.map((arg) => (
{arg.name}:{' '}
))} ){' '} )} :{' '}
{item.type.description ?? null}
); } else if (item.kind === 'input_field') { child = ( <>
{name && {name.value}:}{' '}
{item.type.description ?? null} ); } return
{child}
; } function GqlTypeLink({ item, setItem, color, children, }: { item: ExplorerItem; color?: Color; setItem: (item: ExplorerItem) => void; children?: string; }) { if (item?.kind === 'type' && isListType(item.type)) { return ( <> [ {children} ] ); } else if (item?.kind === 'type' && isNonNullType(item.type)) { return ( <> {children} ! ); } return ( ); } function GqlTypeLabel({ item, children }: { item: ExplorerItem; children?: string }) { let inner; if (children) { inner = children; } else if (item == null) { inner = 'Root'; } else if (item.kind === 'type') { inner = getNamedType(item.type).name; } else { inner = getNamedType(item.type.type).name; } return <>{inner}; } function Subheading({ children }: { children: ReactNode }) { return

{children}

; } function Heading({ children }: { children: ReactNode }) { return

{children}

; }