import { DirectiveLocation , GraphQLError } from "graphql" ; import { FeatureDefinition , FeatureDefinitions , FeatureUrl , FeatureVersion } from "./coreSpec" ; import { DirectiveDefinition , NonNullType , Schema } from "./definitions" ; import { ERRORS } from "./error" ; import { sameType } from "./types" ; import { assert } from "./utils" ; export const tagIdentity = 'https://specs.apollo.dev/tag' ; export const tagLocations = [ DirectiveLocation . FIELD_DEFINITION , DirectiveLocation . OBJECT , DirectiveLocation . INTERFACE , DirectiveLocation . UNION , ] ; const printedTagDefinition = 'directive @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION' ; export class TagSpecDefinition extends FeatureDefinition { constructor ( version ) { super ( new FeatureUrl ( tagIdentity , 'tag' , version ) ) ; } addElementsToSchema ( schema ) { const directive = this . addDirective ( schema , 'tag' ) . addLocations ( ... tagLocations ) ; directive . addArgument ( "name" , new NonNullType ( schema . stringType ( ) ) ) ; } tagDirective ( schema ) { return this . directive ( schema , 'tag' ) ! ; } checkCompatibleDirective ( definition ) { assert ( definition . name === 'tag' , ( ) => `This method should not have been called on directive named ${ definition . name }` ) ; const hasUnknownArguments = Object . keys ( definition . arguments ( ) ) . length > 1 ; const nameArg = definition . argument ( 'name' ) ; const hasValidNameArg = nameArg && sameType ( nameArg . type ! , new NonNullType ( definition . schema ( ) . stringType ( ) ) ) ; const hasValidLocations = definition . locations . every ( loc => tagLocations . includes ( loc ) ) ; if ( hasUnknownArguments || ! hasValidNameArg || ! hasValidLocations ) { return ERRORS . TAG_DEFINITION_INVALID . err ( { message : `Found invalid @tag directive definition. Please ensure the directive definition in your schema's definitions matches the following:\n\t${ printedTagDefinition }` , } ) ; } return undefined ; } } export const TAG_VERSIONS = new FeatureDefinitions < TagSpecDefinition > ( tagIdentity ) . add ( new TagSpecDefinition ( new FeatureVersion ( 0 , 1 ) ) ) ;