/** * Copyright (c) 2021 GraphQL Contributors. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { ExplorerFieldDef, useExplorerContext, useSchemaContext, } from '@graphiql/react'; import { GraphQLEnumValue, GraphQLInterfaceType, GraphQLNamedType, GraphQLObjectType, isEnumType, isInterfaceType, isNamedType, isObjectType, isUnionType, } from 'graphql'; import React, { ReactNode, useState } from 'react'; import Argument from './Argument'; import DefaultValue from './DefaultValue'; import FieldLink from './FieldLink'; import MarkdownContent from './MarkdownContent'; import TypeLink from './TypeLink'; export default function TypeDoc() { const { schema } = useSchemaContext({ nonNull: true }); const { explorerNavStack } = useExplorerContext({ nonNull: true }); const [showDeprecated, setShowDeprecated] = useState(false); const navItem = explorerNavStack[explorerNavStack.length - 1]; const type = navItem.def; if (!schema || !isNamedType(type)) { return null; } let typesTitle: string | null = null; let types: readonly (GraphQLObjectType | GraphQLInterfaceType)[] = []; if (isUnionType(type)) { typesTitle = 'possible types'; types = schema.getPossibleTypes(type); } else if (isInterfaceType(type)) { typesTitle = 'implementations'; types = schema.getPossibleTypes(type); } else if (isObjectType(type)) { typesTitle = 'implements'; types = type.getInterfaces(); } let typesDef; if (types && types.length > 0) { typesDef = (
{typesTitle}
{types.map(subtype => (
))}
); } // InputObject and Object let fieldsDef; let deprecatedFieldsDef; if (type && 'getFields' in type) { const fieldMap = type.getFields(); const fields = Object.keys(fieldMap).map(name => fieldMap[name]); fieldsDef = (
fields
{fields .filter(field => !field.deprecationReason) .map(field => ( ))}
); const deprecatedFields = fields.filter(field => Boolean(field.deprecationReason), ); if (deprecatedFields.length > 0) { deprecatedFieldsDef = (
deprecated fields
{!showDeprecated ? ( ) : ( deprecatedFields.map(field => ( )) )}
); } } let valuesDef: ReactNode; let deprecatedValuesDef: ReactNode; if (isEnumType(type)) { const values = type.getValues(); valuesDef = (
values
{values .filter(value => Boolean(!value.deprecationReason)) .map(value => ( ))}
); const deprecatedValues = values.filter(value => Boolean(value.deprecationReason), ); if (deprecatedValues.length > 0) { deprecatedValuesDef = (
deprecated values
{!showDeprecated ? ( ) : ( deprecatedValues.map(value => ( )) )}
); } } return (
{isObjectType(type) && typesDef} {fieldsDef} {deprecatedFieldsDef} {valuesDef} {deprecatedValuesDef} {!isObjectType(type) && typesDef}
); } type FieldProps = { type: GraphQLNamedType; field: ExplorerFieldDef; }; function Field({ field }: FieldProps) { return (
{'args' in field && field.args && field.args.length > 0 && [ '(', {field.args .filter(arg => !arg.deprecationReason) .map(arg => ( ))} , ')', ]} {': '} {field.description && ( )} {'deprecationReason' in field && field.deprecationReason && ( )}
); } type EnumValueProps = { value: GraphQLEnumValue; }; function EnumValue({ value }: EnumValueProps) { return (
{value.name}
{value.deprecationReason && ( )}
); }