GraphQL Megaera
Example
| From GraphQL | To TypeScript |
|---|---|
query IssuesQuery { issues(first: 100) { totalCount nodes { createdAt closedAt closed author { login } number title labels(first: 10) { totalCount nodes { name } } body comments(first: 10) { totalCount nodes { body } } repository { owner { login } name } } pageInfo { hasNextPage endCursor } } rateLimit { limit cost remaining resetAt } } |
type IssuesQuery = () => { issues: { totalCount: number nodes: Array<{ createdAt: string closedAt: string | null closed: boolean author: { login: string } number: number title: string labels: { totalCount: number nodes: Array<{ name: string }> } body: string comments: { totalCount: number nodes: Array<{ body: string }> } repository: { owner: { login: string } name: string } }> pageInfo: { hasNextPage: boolean endCursor: string | null } } rateLimit: { limit: number cost: number remaining: number resetAt: string } } |
Installation
Usage
megaera --schema=schema.graphql ./src/**/*.graphql
Megaera will generate TypeScript code for all queries in the specified files.
FAQ
How to use Megaera?
Put your queries in .graphql files, and run megaera to generate TypeScript code from them.
Megaera will copy the query string to the generated TypeScript file, so you can import it in your TypeScript code.
import { IssuesQuery } from './query.graphql.ts'
The IssuesQuery variable is a string with the GraphQL query. You can use it
directly in your code, or pass it to a function that accepts a query.
Also, IssuesQuery carries the type of the query, so you can use it to infer
the return type of the query, and the types of the input variables.
type Result = ReturnType<IssuesQuery>
The type IssuesQuery can also be used independently:
import type { IssuesQuery } from './query.graphql.ts'
How to get the return type of a query?
Megaera generates TypeScript types for queries as functions.
type UserQuery = (vars: { login?: string }) => { user: { login: string avatarUrl: string name: string } }
To get the return type of a query, use the ReturnType utility type:
type Result = ReturnType<UserQuery>
How to get the types of the variables of a query?
The first parameter of the query function is the variables.
You can use TypeScript's Parameters utility type to get the types of the variables:
type Variables = Parameters<UserQuery>[0]
Or you can use the Variables utility type to get the types of the variables:
import { Variables } from 'megaera' type Variables = Variables<UserQuery>
Why query string is copied to TypeScript file as well?
To make it easier to import queries in TypeScript projects. As well to connect generated output types with query source code.
This allows for library authors to create a function that accepts a query, and infers the return type from the query, as well as the types of the variables.
For example, wrap Octokit in a function that accepts a query and returns the result:
import { Query, Variables } from 'megaera' import { IssuesQuery } from './query.graphql.ts' function query<T extends Query>(query: T, variables?: Variables<T>) { return octokit.graphql<ReturnType<T>>(query, variables) } // Return type, and types of variables are inferred from the query. const { issues } = await query(IssuesQuery, { login: 'webpod' })
Does Megaera support fragments?
Yes, Megaera fully supports fragments. Fragments are generated as separate types, and can be used independently.
query IssuesQuery($login: String) { issues(login: $login) { totalCount nodes { ...Issue } } } fragment Issue on Issue { number author { login } createdAt closedAt }
The generated TypeScript code will have a type Issue that can be used independently:
import { Issue, IssuesQuery } from './query.graphql.ts' const firstIssue: Issue = query(IssuesQuery).issues.nodes[0]
Can Megaera extract queries from `.ts` files?
No. To simplify development of Megaera, it is only possible to extract queries
from .graphql files.
But it should be possible to create plugins for webpack, rollup, or other
bundlers that can extract queries from .ts files. If you are interested in
this, please open an issue.