Skip to content

Commit

Permalink
chore(docs): generator section
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt committed Sep 8, 2024
1 parent f282913 commit 9bf3896
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 4 deletions.
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,26 @@
"exports": {
".": {
"import": {
"types": "./build/entrypoints/main.d.ts",
"default": "./build/entrypoints/main.js"
}
},
"./generator": {
"import": {
"default": "./build/entrypoints/generator.js"
}
},
"./client": {
"import": {
"types": "./build/entrypoints/client.d.ts",
"default": "./build/entrypoints/client.js"
}
},
"./schema": {
"import": {
"types": "./build/entrypoints/schema.d.ts",
"default": "./build/entrypoints/schema.js"
}
},
"./schema/scalars": {
"import": {
"types": "./build/entrypoints/scalars.d.ts",
"default": "./build/entrypoints/scalars.js"
}
}
Expand Down
1 change: 1 addition & 0 deletions src/entrypoints/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { generateFiles as generate } from '../layers/2_generator/files.js'
117 changes: 117 additions & 0 deletions website/content/guides/overview/generation.md
Original file line number Diff line number Diff line change
@@ -1 +1,118 @@
# Generation

## Overview

Graffle allows you to extend your client with generated code. This is achieved through a generator CLI that Graffle ships with. Using the CLI, you pass it either a file path to a GraphQL SDL file or a URL to a GraphQL API supporting introspection, and then the CLI outputs TypeScript modules into a local directory that can be used by your project. The benefits of generation are:

1. A TypeScript first interface for sending requests to the GraphQL schema.
2. Type-safe request inputs (selection set, directives, etc.).
3. Type-safe request outputs (results) inferred from the the request input.
4. Automatic encoding and decoding of custom scalars.
5. Type utilities to create TypeScript types based on types in the GraphQL schema.
6. Runtime utilities to create reusable selection sets.

## Example

The following takes you through a simple example to demonstrate how generation works and what it gives you.

1. `pnpm init`
1. `pnpm add graffle`
1. `pnpm graffle --schema https://countries.trevorblades.com/graphql`
1. A local directory will have been generated `./graffle`. You will import Graffle from here now instead of the static library `graffle`. Note that you still need `graffle` installed as the generated code is just a thin layer of code that still imports from `graffle`.
1. You can start sending requests. The constructor's schema parameter is made optional because the CLI used the URL to introspect the schema so it already knows where to send requests to.

```ts twoslash
import { Graffle } from './graffle/__.js'

const graffle = Graffle.create()
const result = await graffle.rawString({
document: `query { continents { name } }`,
})
console.log(result.data)
```

<!-- dprint-ignore -->
```js
{
continents: [
{ name: 'Africa' },
{ name: 'Antarctica' },
{ name: 'Asia' },
{ name: 'Europe' },
{ name: 'North America' },
{ name: 'Oceania' },
{ name: 'South America' },
]
}
```
1. So far this is not much different than using the static Graffle client. Let's try the TypeScript interface that is exclusive to the generated client. We'll rewrite our query:

```ts twoslash
import { Graffle } from './graffle/__.js'
const graffle = Graffle.create()
// ---cut---
const data = await graffle
.document({
demoQuery: { // Operation name
query: { // Operation
continents: { // Query field selection
name: true, // Continent field selection
},
},
},
})
.run()
```
Note:
1. The input is type safe.
2. The results are type safe.

1. The `.document` method allows sending whole GraphQL documents but we can use more targeted interface if we just want `continents` like so:
```ts twoslash
import { Graffle } from './graffle/__.js'

const graffle = Graffle.create()
// ---cut---
const data = await graffle.query.continents({ name: true })
```
Simple!

1. There are many more features covered by the rest of these guides. One more thing we'll demonstrate here are the utilities. You can build up reusable selection sets if desired:

```ts twoslash
import { Select } from './graffle/modules/Select.js'
const ContinentSelection = Select.Continent({ name: true })
```

1. You can also do the same thing at the type level:

```ts twoslash
import { type Select } from './graffle/modules/Select.js'
type Continent = Select.Continent<{ name: true }>
```

## CLI

Typically you will use the CLI to generate a client. After installing `graffle` you will have access to a CLI also named `graffle`.

```bash
pnpm add graffle
pnpm graffle --schema '...'
```

The CLI has built in help that you can use to learn about all its inputs.

```bash
pnpm graffle --help
```

## API

If you need to script graffle client generation then you can drop to the underlying Graffle generator API. It is largely one-to-one with the CLI. Use its JSDoc to learn about all its inputs.

```ts
import { generate } from 'graffle/generator'
```

0 comments on commit 9bf3896

Please sign in to comment.