Skip to content

Commit e88bf85

Browse files
committed
feat: graphql-codegen plugin
1 parent a0250c9 commit e88bf85

File tree

13 files changed

+913
-3
lines changed

13 files changed

+913
-3
lines changed

README.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# GraphQL CodeGen Persisted Query List
2+
3+
A GraphQL CodeGen plugin for generating persisted query manifests.
4+
5+
## Installation
6+
7+
```bash
8+
pnpm add -D graphql-codegen-persisted-query-list
9+
```
10+
11+
## Usage
12+
13+
Add the plugin to your GraphQL CodeGen configuration:
14+
15+
### Using YAML Config
16+
17+
```yml
18+
# codegen.yml
19+
generates:
20+
./generated-gql/persisted-query-manifest/client.json:
21+
plugins:
22+
- graphql-codegen-persisted-query-list
23+
config:
24+
output: client
25+
26+
./generated-gql/persisted-query-manifest/server.json:
27+
plugins:
28+
- graphql-codegen-persisted-query-list
29+
config:
30+
output: server
31+
includeAlgorithmPrefix: true # Enable prefixed document identifiers for compliance with GraphQL over HTTP spec
32+
```
33+
34+
### Using JavaScript/TypeScript Config
35+
36+
```typescript
37+
// codegen.ts
38+
import type { CodegenConfig } from '@graphql-codegen/cli';
39+
40+
const config: CodegenConfig = {
41+
// ... other config
42+
generates: {
43+
'./generated-gql/persisted-query-manifest/client.json': {
44+
documents: ['./client/**/*.{graphql,gql}', './pages/**/*.{graphql,gql}'],
45+
plugins: ['graphql-codegen-persisted-query-list'],
46+
config: {
47+
output: 'client',
48+
},
49+
},
50+
'./generated-gql/persisted-query-manifest/server.json': {
51+
documents: ['./client/**/*.{graphql,gql}', './pages/**/*.{graphql,gql}'],
52+
plugins: ['graphql-codegen-persisted-query-list'],
53+
config: {
54+
output: 'server',
55+
includeAlgorithmPrefix: true, // Enable prefixed document identifiers for compliance with GraphQL over HTTP spec
56+
},
57+
}
58+
}
59+
};
60+
61+
export default config;
62+
```
63+
64+
## Configuration Options
65+
66+
| Option | Type | Default | Description |
67+
|-------------------------|------------------------|------------|------------------------------------------------------------------------|
68+
| `output` | `'client' \| 'server'` | (required) | Format of the generated manifest |
69+
| `algorithm` | `string` | `'sha256'` | Hash algorithm to use for generating operation IDs |
70+
| `includeAlgorithmPrefix`| `boolean` | `false` | Whether to prefix hashes with algorithm name (e.g., `sha256:abc123...`) |
71+
72+
## Output Formats
73+
74+
### Client Format
75+
76+
The client format provides a simple mapping between operation names and their hashes, making it easy for clients to reference operations by name:
77+
78+
```json
79+
{
80+
"GetUser": "abcdef123456...",
81+
"UpdateUser": "fedcba654321..."
82+
}
83+
```
84+
85+
With `includeAlgorithmPrefix: true`:
86+
87+
```json
88+
{
89+
"GetUser": "sha256:abcdef123456...",
90+
"UpdateUser": "sha256:fedcba654321..."
91+
}
92+
```
93+
94+
### Server Format
95+
96+
The server format is more comprehensive, mapping operation hashes to their complete details (type, name, and body). This is ideal for server-side lookup and validation:
97+
98+
```json
99+
{
100+
"format": "apollo-persisted-query-manifest",
101+
"version": 1,
102+
"operations": {
103+
"abcdef123456...": {
104+
"type": "query",
105+
"name": "GetUser",
106+
"body": "query GetUser { user { id name } }"
107+
},
108+
"fedcba654321...": {
109+
"type": "mutation",
110+
"name": "UpdateUser",
111+
"body": "mutation UpdateUser($id: ID!, $name: String!) { updateUser(id: $id, name: $name) { id name } }"
112+
}
113+
}
114+
}
115+
```
116+
117+
With `includeAlgorithmPrefix: true`:
118+
119+
```json
120+
{
121+
"format": "apollo-persisted-query-manifest",
122+
"version": 1,
123+
"operations": {
124+
"sha256:abcdef123456...": {
125+
"type": "query",
126+
"name": "GetUser",
127+
"body": "query GetUser { user { id name } }"
128+
},
129+
"sha256:fedcba654321...": {
130+
"type": "mutation",
131+
"name": "UpdateUser",
132+
"body": "mutation UpdateUser($id: ID!, $name: String!) { updateUser(id: $id, name: $name) { id name } }"
133+
}
134+
}
135+
}
136+
```
137+
138+
## How It Works
139+
140+
The plugin's workflow is straightforward but powerful:
141+
142+
1. It collects all GraphQL operations from your codebase
143+
2. It extracts and resolves all fragments used in each operation
144+
3. It outputs a manifest file in your chosen format (client or server)
145+
146+
All generated hashes use the algorithm you specify (default: `sha256`). You can enable the "Prefixed Document Identifier" format (e.g., `sha256:abc123...`) for compliance with the [GraphQL over HTTP specification](https://github.com/graphql/graphql-over-http/blob/52d56fb36d51c17e08a920510a23bdc2f6a720be/spec/Appendix%20A%20--%20Persisted%20Documents.md#sha256-hex-document-identifier) by setting `includeAlgorithmPrefix: true`.
147+
148+
## License
149+
150+
MIT

package.json

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
{
22
"name": "@replit/graphql-codegen-persisted-queries",
33
"version": "0.0.1",
4-
"description": "GraphQL codegen plugin to generate persisted query list manifests",
5-
"main": "index.ts",
4+
"description": "GraphQL plugin to generate persisted query manifests",
5+
"main": "dist/index.mjs",
6+
"module": "dist/index.mjs",
7+
"types": "dist/index.d.mts",
8+
"files": [
9+
"dist",
10+
"README.md"
11+
],
612
"scripts": {
7-
"build": "tsup"
13+
"build": "tsup",
14+
"dev": "tsup --watch",
15+
"typecheck": "tsc --noEmit",
16+
"lint": "eslint . --ext .ts",
17+
"clean": "rm -rf dist",
18+
"prepare": "npm run build"
819
},
920
"repository": {
1021
"type": "git",
@@ -24,14 +35,21 @@
2435
},
2536
"homepage": "https://github.com/replit/graphql-codegen-persisted-queries#readme",
2637
"packageManager": "pnpm@8.15.5",
38+
"peerDependencies": {
39+
"@graphql-codegen/plugin-helpers": "^5.0.0",
40+
"graphql": "^16.0.0"
41+
},
2742
"devDependencies": {
43+
"@graphql-codegen/plugin-helpers": "^5.0.0",
2844
"@stylistic/eslint-plugin-js": "^4.2.0",
2945
"@stylistic/eslint-plugin-ts": "^4.2.0",
46+
"@types/node": "^22.13.10",
3047
"@typescript-eslint/eslint-plugin": "^8.26.1",
3148
"@typescript-eslint/parser": "^8.26.1",
3249
"eslint": "^9.22.0",
3350
"eslint-config-prettier": "^10.1.1",
3451
"eslint-plugin-prettier": "^5.2.3",
52+
"graphql": "^16.8.1",
3553
"prettier": "^3.5.3",
3654
"tsup": "^8.4.0"
3755
}

0 commit comments

Comments
 (0)