import { BREAK , parse , visit } from 'graphql' ; import type { Visitor } from '@babel/traverse' ; import type BabelTypes from '@babel/types' ; const GQL_TAGS = new Set ( [ 'gql' ] ) ; interface Babel { types : typeof BabelTypes ; } interface BabelPlugin { visitor : Visitor ; } const getOperationName = ( query ) => { let operationName = 'unknown' ; visit ( parse ( query ) , { OperationDefinition : ( node ) => { const operation = node . name ?. value ; if ( typeof operation === 'string' ) { operationName = operation ; } return BREAK ; } , } ) ; return operationName ; } ; export default function babelGQLPlugin ( babel ) { const { types } = babel ; return { visitor : { Program : ( program ) => { program . traverse ( { TaggedTemplateExpression : ( path ) => { if ( ! path . node . loc ) { return ; } const { tag } = path . node ; if ( ! types . isIdentifier ( tag ) || ! GQL_TAGS . has ( tag . name ) ) { return ; } try { const query = path . node . quasi . quasis . map ( ( q ) => q . value . cooked ) . join ( '' ) . trim ( ) ; const operationName = getOperationName ( query ) ; path . replaceWithSourceString ( `"${ operationName }"` ) ; } catch ( error ) { throw path . buildCodeFrameError ( `GraphQL: ${ error . message }` ?? 'Unknown graphql parsing error' ) ; } } , } ) ; } , } , } ; }