TypeScript Oclif
Package name | Weekly Downloads | Version | License | Updated |
---|---|---|---|---|
@graphql-codegen/typescript-oclif (opens in a new tab) | Jul 22nd, 2023 |
Installation
pnpm add -D @graphql-codegen/typescript-oclif
Usage Requirements
In order to use this GraphQL Codegen plugin, please make sure that you have GraphQL operations (query
/ mutation
/ subscription
and fragment
) set as documents: …
in your codegen.yml
.
Without loading your GraphQL operations (query
, mutation
, subscription
and fragment
), you won't see any change in the generated output.
This plugin generates oclif
(opens in a new tab) CLI commands.
Then, make sure you have typescript
plugin as well in your configuration:
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: 'http://localhost:4000',
documents: 'src/commands/**/*.graphql',
generates: {
'src/types.ts': { plugins: ['typescript'] },
'src/commands/': {
preset: 'near-operation-file',
presetConfig: {
extension: '.ts',
baseTypesPath: '../types.ts'
},
plugins: [
{
'typescript-oclif': {
handlerPath: '../../handler'
}
}
]
}
}
}
export default config
Usage
With GraphQL Codegen, building a CLI tool for your GraphQL API couldn't be easier. In four steps, you can have a user-friendly command-line interface:
- Generate a boilerplate CLI using
oclif
- Add GraphQL Documents (Queries & Mutations)
- Add and export a graphql client of your choice (
graphql-request
,apollo-client
, etc.) - Add, configure, and run the code generator
Step 1: Generate the CLI scaffold
You'll be starting from your projects directory. From there, generate the CLI skeleton using oclif
by following the steps in their guide (opens in a new tab). You can choose either
the single
or multi
type, and can switch later if you change your mind.
Step 2: Add GraphQL Documents
These documents are how oclif
will interact with your API. For each document, there will be
exactly one command.
Within the directory created by the oclif
tool, you'll have a subdirectory src/commands
. That's
where you'll put your GraphQL documents. Ie, to create a <cli-name> hello
command, you'd write a
src/commands/hello.graphql
document, which will be used to generate a src/commands/hello.ts
file. Important: each document should have exactly one GraphQL operation.
Step 3: Add & Export a GraphQL Query Handler
Which client you use, and how you configure it, is entirely up to you! It just has to conform to
this QueryHandler
signature:
import { Command } from '@oclif/command'
interface QueryHandlerProps {
command: Command
query: string
variables?: Record<string, any>
}
type QueryHandler = (props: QueryHandlerProps) => any
This allows you to pre-process, send, and post-process requests however you'd like, as well as format the results returned. The arguments are:
command
: the command object being executed, described here (opens in a new tab) in theoclif
documentation.query
: the string version of the GraphQL query being executed.variables
: the variables as configured in your GraphQL operation and parsed byoclif
.
You can add a src/handler.ts
(or any other path), configure your handler function there, and then
export your handler as the default export. It's in this module that you can handle auth logic,
read config files, etc., and that will apply to all CLI operations. This file will not be modified
by the codegen.
To get started quickly and easily, consider using the simple graphql-request
as your handler:
import { GraphQLClient } from 'graphql-request'
import { Command } from '@oclif/command'
interface QueryHandlerProps {
command: Command
query: string
variables?: Record<string, any>
}
// Change the URL to the endpoint your CLI will use
const client = new GraphQLClient('http://localhost:4000')
const handler = ({ command, query, variables }: QueryHandlerProps) => {
return client.request(query, variables).then(command.log).catch(command.error)
}
export default handler
Step 4: Add & Configure GraphQL Codegen
First, follow the GraphQL-Code-Generator guide to install it, and make sure to also install
@graphql-codegen/typescript-oclif
. Then, change your codegen.yml
file to look like this:
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: '<path-to-your-schema>',
documents: 'src/commands/**/*.graphql',
generates: {
'src/types.ts': { plugins: ['typescript'] },
'src/commands/': {
preset: 'near-operation-file',
presetConfig: {
extension: '.ts',
baseTypesPath: '../types.ts'
},
plugins: [
{
'typescript-oclif': {
client: '../../client'
}
}
]
}
}
}
export default config
Breaking that down:
- Reading your schema allows the codegen tool to understand what types it's working with
- The 'documents' section will collect all of your
*.graphql
files src/types.ts
creates the typescript types that the rest of the tool can referencenear-operation-file
is agraphql-codegen
preset which allows one output file per input file (ie, one.ts
module per.graphql
document) rather than one output file for the whole package. This is required foroclif
to work, since it uses the file structure to generate the command structure.- Note:
typescript-operations
plugin isn't required, since this library isn't meant to be consumed programmatically (and so nothing reads the types thattypescript-operations
would produce) - The
client
path is to the file which has a default export of yourgraphql-request
client, relative to the generated files (ie here,src/commands/something/file.graphql
). Note that it has no extension.
With that configured, just run yarn graphql-codegen
or npx graphql-code-generator
to generate all the
necessary oclif
command files. With that complete, follow the directions in the
oclif guide (opens in a new tab) to run your new CLI tool.
Advanced Features
Descriptions & Examples
You can add descriptions and examples for your commands via typescript-oclif
with the @oclif
client-side directive, like so:
mutation CreateAuthor($name: String!)
@oclif(
description: "Create a new author"
example: "cli author:create --name Alice"
example: "cli author:create --name Bob"
) {
createAuthor(input: { name: $name }) {
name
}
}
This @oclif
directive will not be sent to the server. Note that, for multiple examples, you must
use multiple example
keys rather than an examples
array. This is a quirk feature of
graphql
.
Custom/Manually-maintained Commands
If you want a command that doesn't just execute a GraphQL Query or Mutation, then you can still
create one manually in the same way as any other oclif
application. If you wanted to add a fix
command, for example, you can just create a file at src/commands/fix.ts
, follow the oclif
API
(ie, export a class with a run()
method), and graphql-codegen
won't disturb that file - so long
as you don't also create a fix.graphql
file next to it (in which case, it would override
fix.ts
on the next run of graphql-codegen
).