Skip to content

Instantly share code, notes, and snippets.

@ucw
Created June 19, 2024 08:12
Show Gist options
  • Save ucw/6f351b8567fa0e7df8090a978cf0cbbc to your computer and use it in GitHub Desktop.
Save ucw/6f351b8567fa0e7df8090a978cf0cbbc to your computer and use it in GitHub Desktop.
import type { Plugin } from 'rollup'
import traverse from '@babel/traverse'
import * as t from '@babel/types'
import { parse } from '@babel/parser'
import generate from '@babel/generator'
import { buildSchema, parse as parseGql } from 'graphql'
import { ClientSideBaseVisitor } from '@graphql-codegen/visitor-plugin-common'
import * as queries from '../gql/graphql'
const gqlTagName = 'graphql'
const noopSchema = buildSchema('type Query { _: Int }')
export default function (): Plugin {
const visitor = new ClientSideBaseVisitor(noopSchema, [], {}, {})
return {
name: 'codegen-plugin',
transform (code, id) {
if (!(id.endsWith('.ts') || id.endsWith('.vue'))) {
return
}
const module = parse(code, {
sourceType: 'module'
})
traverse(module, {
ImportDeclaration (path) {
const isGql = path.node.specifiers.find(it => it.type === 'ImportSpecifier' && it.imported.type === 'Identifier' && it.imported.name === 'graphql') !== undefined
if (isGql) {
path.remove()
}
},
CallExpression (path) {
if (path.node.callee.type !== 'Identifier' || path.node.callee.name !== gqlTagName) {
return
}
const [argument] = path.node.arguments
if (argument == null) {
return
}
if (argument.type !== 'TemplateLiteral') {
return
}
const [content] = argument.quasis
const ast = parseGql(content.value.raw)
const [firstDefinition] = ast.definitions
if (firstDefinition.kind !== 'FragmentDefinition' && firstDefinition.kind !== 'OperationDefinition') {
return
}
if (firstDefinition.name == null) {
return
}
const operationOrFragmentName =
firstDefinition.kind === 'OperationDefinition'
? visitor.getOperationVariableName(firstDefinition)
: visitor.getFragmentVariableName(firstDefinition)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
path.replaceWith(t.stringLiteral((queries as unknown as Record<string, queries.TypedDocumentString<any, any>>)[operationOrFragmentName].toString()))
}
})
return generate(module, {}, code)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment