// @flow strict import type { DirectiveLocationEnum } from '../language/directiveLocation'; export type IntrospectionOptions = {| // Whether to include descriptions in the introspection result. // Default: true descriptions?: boolean, // Whether to include `specifiedByUrl` in the introspection result. // Default: false specifiedByUrl?: boolean, // Whether to include `isRepeatable` field on directives. // Default: false directiveIsRepeatable?: boolean, // Whether to include `description` field on schema. // Default: false schemaDescription?: boolean, // Whether target GraphQL server support deprecation of input values. // Default: false inputValueDeprecation?: boolean, |}; export function getIntrospectionQuery(options?: IntrospectionOptions): string { const optionsWithDefault = { descriptions: true, specifiedByUrl: false, directiveIsRepeatable: false, schemaDescription: false, inputValueDeprecation: false, ...options, }; const descriptions = optionsWithDefault.descriptions ? 'description' : ''; const specifiedByUrl = optionsWithDefault.specifiedByUrl ? 'specifiedByUrl' : ''; const directiveIsRepeatable = optionsWithDefault.directiveIsRepeatable ? 'isRepeatable' : ''; const schemaDescription = optionsWithDefault.schemaDescription ? descriptions : ''; function inputDeprecation(str) { return optionsWithDefault.inputValueDeprecation ? str : ''; } return ` query IntrospectionQuery { __schema { ${schemaDescription} queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name ${descriptions} ${directiveIsRepeatable} locations args${inputDeprecation('(includeDeprecated: true)')} { ...InputValue } } } } fragment FullType on __Type { kind name ${descriptions} ${specifiedByUrl} fields(includeDeprecated: true) { name ${descriptions} args${inputDeprecation('(includeDeprecated: true)')} { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields${inputDeprecation('(includeDeprecated: true)')} { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name ${descriptions} isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name ${descriptions} type { ...TypeRef } defaultValue ${inputDeprecation('isDeprecated')} ${inputDeprecation('deprecationReason')} } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } } } } `; } export type IntrospectionQuery = {| +__schema: IntrospectionSchema, |}; export type IntrospectionSchema = {| +description?: ?string, +queryType: IntrospectionNamedTypeRef, +mutationType: ?IntrospectionNamedTypeRef, +subscriptionType: ?IntrospectionNamedTypeRef, +types: $ReadOnlyArray, +directives: $ReadOnlyArray, |}; export type IntrospectionType = | IntrospectionScalarType | IntrospectionObjectType | IntrospectionInterfaceType | IntrospectionUnionType | IntrospectionEnumType | IntrospectionInputObjectType; export type IntrospectionOutputType = | IntrospectionScalarType | IntrospectionObjectType | IntrospectionInterfaceType | IntrospectionUnionType | IntrospectionEnumType; export type IntrospectionInputType = | IntrospectionScalarType | IntrospectionEnumType | IntrospectionInputObjectType; export type IntrospectionScalarType = {| +kind: 'SCALAR', +name: string, +description?: ?string, +specifiedByUrl?: ?string, |}; export type IntrospectionObjectType = {| +kind: 'OBJECT', +name: string, +description?: ?string, +fields: $ReadOnlyArray, +interfaces: $ReadOnlyArray< IntrospectionNamedTypeRef, >, |}; export type IntrospectionInterfaceType = {| +kind: 'INTERFACE', +name: string, +description?: ?string, +fields: $ReadOnlyArray, +interfaces: $ReadOnlyArray< IntrospectionNamedTypeRef, >, +possibleTypes: $ReadOnlyArray< IntrospectionNamedTypeRef, >, |}; export type IntrospectionUnionType = {| +kind: 'UNION', +name: string, +description?: ?string, +possibleTypes: $ReadOnlyArray< IntrospectionNamedTypeRef, >, |}; export type IntrospectionEnumType = {| +kind: 'ENUM', +name: string, +description?: ?string, +enumValues: $ReadOnlyArray, |}; export type IntrospectionInputObjectType = {| +kind: 'INPUT_OBJECT', +name: string, +description?: ?string, +inputFields: $ReadOnlyArray, |}; export type IntrospectionListTypeRef< T: IntrospectionTypeRef = IntrospectionTypeRef, > = {| +kind: 'LIST', +ofType: T, |}; export type IntrospectionNonNullTypeRef< T: IntrospectionTypeRef = IntrospectionTypeRef, > = {| +kind: 'NON_NULL', +ofType: T, |}; export type IntrospectionTypeRef = | IntrospectionNamedTypeRef<> | IntrospectionListTypeRef<> | IntrospectionNonNullTypeRef< IntrospectionNamedTypeRef<> | IntrospectionListTypeRef<>, >; export type IntrospectionOutputTypeRef = | IntrospectionNamedTypeRef | IntrospectionListTypeRef | IntrospectionNonNullTypeRef< | IntrospectionNamedTypeRef | IntrospectionListTypeRef, >; export type IntrospectionInputTypeRef = | IntrospectionNamedTypeRef | IntrospectionListTypeRef | IntrospectionNonNullTypeRef< | IntrospectionNamedTypeRef | IntrospectionListTypeRef, >; export type IntrospectionNamedTypeRef< T: IntrospectionType = IntrospectionType, > = {| +kind: $PropertyType, +name: string, |}; export type IntrospectionField = {| +name: string, +description?: ?string, +args: $ReadOnlyArray, +type: IntrospectionOutputTypeRef, +isDeprecated: boolean, +deprecationReason: ?string, |}; export type IntrospectionInputValue = {| +name: string, +description?: ?string, +type: IntrospectionInputTypeRef, +defaultValue: ?string, +isDeprecated?: boolean, +deprecationReason?: ?string, |}; export type IntrospectionEnumValue = {| +name: string, +description?: ?string, +isDeprecated: boolean, +deprecationReason: ?string, |}; export type IntrospectionDirective = {| +name: string, +description?: ?string, +isRepeatable?: boolean, +locations: $ReadOnlyArray, +args: $ReadOnlyArray, |};