mercurius-codegen
Get full type-safety and autocompletion for Mercurius using TypeScript and GraphQL Code Generator seamlessly while you code.
pnpm add mercurius-codegen
yarn add mercurius-codegen
npm install mercurius-codegen
Usage
For convenience, this package also exports a fake gql
tag that gives tooling support for "prettier formatting" and "IDE syntax highlighting". It's completely optional.
import Fastify from 'fastify'
import mercurius from 'mercurius'
import mercuriusCodegen, { gql } from 'mercurius-codegen'
const app = Fastify()
app.register(mercurius, {
schema: gql`
type Query {
hello(greetings: String!): String!
}
`,
resolvers: {
Query: {
hello(_root, { greetings }) {
return 'Hello World'
},
},
},
})
mercuriusCodegen(app, {
targetPath: './src/graphql/generated.ts',
}).catch(console.error)
app.listen(8000)
import { IResolvers } from 'mercurius'
export const resolvers: IResolvers = {
Query: {
hello(_root, { greetings }) {
return 'Hello World'
},
},
}
It also gives type-safety for Mercurius Loaders:
import { MercuriusLoaders } from 'mercurius'
export const loaders: MercuriusLoaders = {
Dog: {
async owner(queries, ctx) {
return queries.map(({ obj, params }) => {
return owners[obj.name]
})
},
},
}
By default it disables itself if NODE_ENV
is 'production'
It automatically uses prettier resolving the most nearby config for you.
Operations
mercurius-codegen also supports giving it GraphQL Operation files, basically client queries
, mutations
or subscriptions
, and it creates Typed Document Nodes, that later can be used by other libraries, like for example mercurius-integration-testing (that has native support for typed document nodes), and then be able to have end-to-end type-safety and auto-completion.
You might need to install @graphql-typed-document-node/core
manually in your project.
import mercuriusCodegen from 'mercurius-codegen'
mercuriusCodegen(app, {
targetPath: './src/graphql/generated.ts',
operationsGlob: './src/graphql/operations/*.gql',
}).catch(console.error)
/your-project/src/graphql/operations/example.gql
query hello {
HelloWorld
}
Then, for example, in your tests:
import { createMercuriusTestClient } from 'mercurius-integration-testing'
import { helloDocument } from '../src/graphql/generated'
import { app } from '../src/server'
const client = createMercuriusTestClient(app)
const response = await client.query(helloDocument)
Keep in mind that you can always call mercuriusCodegen
multiple times for different environments and different paths if you prefer to keep the production code as light as possible (which is generally a good practice).
Options
There are some extra options that can be specified:
interface CodegenMercuriusOptions {
targetPath: string
disable?: boolean
silent?: boolean
codegenConfig?: CodegenPluginsConfig
preImportCode?: string
operationsGlob?: string[] | string
watchOptions?: {
enabled?: boolean
chokidarOptions?: ChokidarOptions
uniqueWatch?: boolean
}
}
mercuriusCodegen(app, {
targetPath: './src/graphql/generated.ts',
operationsGlob: ['./src/graphql/operations/*.gql'],
disable: false,
silent: true,
codegenConfig: {
scalars: {
DateTime: 'Date',
},
},
preImportCode: `
// Here you can put any code and it will be added at very beginning of the file
`,
watchOptions: {
enabled: true,
},
}).catch(console.error)
GraphQL Schema from files
As shown in the examples/codegen-gql-files, you can load all your schema type definitions directly from GraphQL .gql files, and this library gives you a function that eases that process, allowing you to get the schema from files, watch for changes and preloading the schema for production environments.
export interface LoadSchemaOptions {
watchOptions?: {
enabled?: boolean
onChange?: (schema: string[]) => void
chokidarOptions?: ChokidarOptions
uniqueWatch?: boolean
}
prebuild?: {
enabled?: boolean
}
silent?: boolean
}
import Fastify from 'fastify'
import mercurius from 'mercurius'
import { buildSchema } from 'graphql'
import mercuriusCodegen, { loadSchemaFiles } from 'mercurius-codegen'
const app = Fastify()
const { schema } = loadSchemaFiles('src/graphql/schema/**/*.gql', {
watchOptions: {
enabled: process.env.NODE_ENV === 'development',
onChange(schema) {
app.graphql.replaceSchema(buildSchema(schema.join('\n')))
app.graphql.defineResolvers(resolvers)
mercuriusCodegen(app, {
targetPath: './src/graphql/generated.ts',
operationsGlob: './src/graphql/operations/*.gql',
}).catch(console.error)
},
},
})
app.register(mercurius, {
schema,
})
License
MIT