Skip to content

Commit 5b4e0a7

Browse files
feat: add Resolvers interface to types for improved type safety
1 parent 37ef8ed commit 5b4e0a7

23 files changed

+882
-358
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ node_modules
22
dist
33
.output
44
.nitro
5-
*.log
5+
*.log
6+
nitro

diff.txt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
diff --git a/playground/nitro.config.ts b/playground/nitro.config.ts
2+
index 824d7a8..69b15ea 100644
3+
--- a/playground/nitro.config.ts
4+
+++ b/playground/nitro.config.ts
5+
@@ -4,27 +4,6 @@ export default defineNitroConfig({
6+
srcDir: 'server',
7+
modules: ['nitro-graphql-yoga'],
8+
compatibilityDate: '2025-07-01',
9+
- hooks: {
10+
- 'nitro:build:before': (nitro) => {
11+
- // Ensure rollupConfig exists
12+
- nitro.options.rollupConfig = nitro.options.rollupConfig || {}
13+
- nitro.options.rollupConfig.output = nitro.options.rollupConfig.output || {}
14+
-
15+
- // Configure manual chunks for GraphQL files
16+
- nitro.options.rollupConfig.output.manualChunks = (id) => {
17+
- if (id.includes('/graphql/') || id.includes('resolver') || id.includes('createUser') || id.includes('hello') || id.includes('posts') || id.includes('todos') || id.includes('users') || id.includes('comment-resolver')) {
18+
- return 'graphql'
19+
- }
20+
- return undefined
21+
- }
22+
-
23+
- // Configure chunk file names to use chunk name as directory
24+
- nitro.options.rollupConfig.output.chunkFileNames = (chunkInfo) => {
25+
- const chunkName = chunkInfo.name || 'chunks'
26+
- return `${chunkName}/[name].mjs`
27+
- }
28+
- },
29+
- },
30+
runtimeConfig: {
31+
graphqlYoga: {
32+
endpoint: '/api/graphql',
33+
diff --git a/src/index.ts b/src/index.ts
34+
index 01dcf25..27f1125 100644
35+
--- a/src/index.ts
36+
+++ b/src/index.ts
37+
@@ -14,14 +14,6 @@ import { setupGraphQLWatcher } from './watcher'
38+
export default defineNitroModule({
39+
name: 'nitro:graphql-yoga',
40+
async setup(nitro: Nitro) {
41+
- // Configure chunk directory naming
42+
- nitro.options.rollupConfig = nitro.options.rollupConfig || {}
43+
- nitro.options.rollupConfig.output = nitro.options.rollupConfig.output || {}
44+
-
45+
- // Configure chunk file names to use 'graphql' directory instead of '_'
46+
- nitro.options.rollupConfig.output.chunkFileNames = (chunkInfo) => {
47+
- return `graphql/[name].mjs`
48+
- }
49+
50+
// Add virtual imports
51+
nitro.options.virtual ??= {}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"chokidar": "^4.0.3",
4242
"consola": "^3.4.2",
4343
"defu": "^6.1.4",
44+
"globby": "^14.0.2",
4445
"graphql": "^16.11.0",
4546
"graphql-scalars": "^1.24.2",
4647
"graphql-yoga": "^5.14.0",

playground/nitro.config.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@ export default defineNitroConfig({
44
srcDir: 'server',
55
modules: ['nitro-graphql-yoga'],
66
compatibilityDate: '2025-07-01',
7+
hooks: {
8+
'nitro:build:before': (nitro) => {
9+
// Ensure rollupConfig exists
10+
nitro.options.rollupConfig = nitro.options.rollupConfig || {}
11+
nitro.options.rollupConfig.output = nitro.options.rollupConfig.output || {}
12+
13+
// Configure manual chunks for GraphQL files
14+
nitro.options.rollupConfig.output.manualChunks = (id) => {
15+
if (id.includes('/graphql/') || id.includes('resolver') || id.includes('createUser') || id.includes('hello') || id.includes('posts') || id.includes('todos') || id.includes('users') || id.includes('comment-resolver')) {
16+
return 'graphql'
17+
}
18+
return undefined
19+
}
20+
21+
// Configure chunk file names to use chunk name as directory
22+
nitro.options.rollupConfig.output.chunkFileNames = (chunkInfo) => {
23+
const chunkName = chunkInfo.name || 'chunks'
24+
return `${chunkName}/[name].mjs`
25+
}
26+
},
27+
},
728
runtimeConfig: {
829
graphqlYoga: {
930
endpoint: '/api/graphql',
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export default createResolver({
2+
Query: {
3+
comments: async (parent, { postId }, context) => {
4+
return [
5+
{ id: '1', content: 'Great post!', postId, authorId: '1' },
6+
{ id: '2', content: 'Nice work!', postId, authorId: '2' },
7+
]
8+
},
9+
},
10+
11+
Mutation: {
12+
addComment: async (parent, { input }, context) => {
13+
return {
14+
id: Date.now().toString(),
15+
content: input.content,
16+
postId: input.postId,
17+
authorId: input.authorId,
18+
}
19+
},
20+
},
21+
})

playground/server/graphql/posts.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
export default createResolver({
2+
Query: {
3+
post: async (parent, { id }, context) => {
4+
return {
5+
id,
6+
title: `Post ${id}`,
7+
content: `This is the content of post ${id}`,
8+
authorId: '1',
9+
}
10+
},
11+
12+
posts: async (parent, args, context) => {
13+
return [
14+
{ id: '1', title: 'First Post', content: 'Content 1', authorId: '1' },
15+
{ id: '2', title: 'Second Post', content: 'Content 2', authorId: '2' },
16+
]
17+
},
18+
},
19+
20+
Mutation: {
21+
createPost: async (parent, { input }, context) => {
22+
return {
23+
id: Date.now().toString(),
24+
title: input.title,
25+
content: input.content,
26+
authorId: input.authorId,
27+
}
28+
},
29+
},
30+
})

playground/server/graphql/resolvers/mutations/createUser.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import type { MutationResolvers } from '../../types.generated'
2-
3-
export default {
1+
export default createResolver({
42
Mutation: {
53
createUser: async (_parent, { input }, context) => {
64
// In a real app, you would save to database
@@ -15,5 +13,5 @@ export default {
1513

1614
return newUser
1715
},
18-
} as MutationResolvers,
19-
}
16+
},
17+
})

playground/server/graphql/resolvers/mutations/todos.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { MutationResolvers, Todo } from '../../types.generated'
1+
import type { Todo } from '#build/graphql-types.generated'
22

3-
export default {
3+
export default createResolver({
44
Mutation: {
55
addTodo: async (_parent, { title }, { storage }) => {
66
const todos = await storage.getItem('todos') || []
@@ -36,5 +36,5 @@ export default {
3636
await storage.setItem('todos', todos)
3737
return true
3838
},
39-
} as MutationResolvers,
40-
}
39+
},
40+
})
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import type { QueryResolvers } from '../../types.generated'
2-
3-
export default {
1+
export default createResolver({
42
Query: {
53
hello: () => 'Hello from auto-discovered resolver!',
64
greeting: (_parent, { name }) => `Hello, ${name}!`,
7-
} as QueryResolvers,
8-
}
5+
},
6+
})
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import type { QueryResolvers } from '../../types.generated'
2-
3-
export default {
1+
export default createResolver({
42
Query: {
53
todos: async (_parent, _args, { storage }) => {
64
const todos = await storage.getItem('todos') || []
@@ -11,5 +9,5 @@ export default {
119
const todos = await storage.getItem('todos') || []
1210
return todos.find((todo: any) => todo.id === id) || null
1311
},
14-
} as QueryResolvers,
15-
}
12+
},
13+
})

0 commit comments

Comments
 (0)