Skip to content

Commit 5ccdb39

Browse files
feat: refactor resolvers to use defineQuery, defineMutation, and defineSubscription for improved structure and type safety
1 parent cda3293 commit 5ccdb39

File tree

6 files changed

+107
-30
lines changed

6 files changed

+107
-30
lines changed
Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
export const define1 = defineResolver({
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-
},
1+
export const define1 = defineQuery({
2+
comments: async (parent, { postId }, context) => {
3+
return [
4+
{ id: '1', content: 'Great post!', postId, authorId: '1' },
5+
{ id: '2', content: 'Nice work!', postId, authorId: '2' },
6+
]
7+
},
8+
})
9+
10+
export const define2 = defineMutation({
11+
addComment: async (parent, { input }, context) => {
12+
const newComment = { id: '3', ...input, authorId: '1' }
13+
// Here you would typically save the new comment to the database
14+
return newComment
915
},
1016
})

src/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ import { clientTypeGeneration, serverTypeGeneration } from './utils/server-type-
1313

1414
export type * from './types'
1515

16+
export { defineGraphQLSchema, defineMutation, defineQuery, defineResolver, defineSubscription, defineType } from './utils'
17+
1618
// This is the main entry point for the nitro-graphql module.
1719
// It sets up the module, configures the GraphQL endpoints, and handles type generation.
18-
export interface Resolvers {}
20+
export interface Resolvers extends Record<string, any> {
21+
22+
}
1923

2024
export default defineNitroModule({
2125
name: 'nitro-graphql',
@@ -152,6 +156,11 @@ export default defineNitroModule({
152156
imports: [
153157
'defineResolver',
154158
'defineYogaConfig',
159+
'defineGraphQLSchema',
160+
'defineMutation',
161+
'defineQuery',
162+
'defineSubscription',
163+
'defineType',
155164
],
156165
})
157166
}

src/rollup.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,12 @@ export function virtualResolvers(app: Nitro) {
133133
}),
134134
]
135135

136-
const data = imports.map(({ imports }) => {
137-
for (const i of imports) {
138-
if (i.type === 'resolver') {
139-
// return `${i.as}`
140-
return `{ resolver: ${i.as} }`
141-
}
142-
}
143-
return undefined
144-
}).filter(Boolean).join(',\n')
136+
const data = imports
137+
.map(({ imports }) =>
138+
imports.map(i => `{ resolver: ${i.as} }`).join(',\n'),
139+
)
140+
.filter(Boolean)
141+
.join(',\n')
145142

146143
const content = [
147144
'export const resolvers = [',

src/types/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export type CodegenServerConfig = TypeScriptPluginConfig & TypeScriptResolversPl
1313
interface IESMImport {
1414
name: string
1515
as?: string
16-
type: 'resolver' | 'query' | 'mutation' | 'type'
16+
type: 'resolver' | 'query' | 'mutation' | 'type' | 'subscription'
1717
}
1818

1919
export interface GenImport {

src/utils/client-codegen.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { LoadSchemaOptions, UnnormalizedTypeDefPointer } from '@graphql-tools/load'
22
import type { Source } from '@graphql-tools/utils'
33
import type { GraphQLSchema } from 'graphql'
4-
import type { CodegenClientConfig } from './types'
4+
import type { CodegenClientConfig } from '../types'
55
import { codegen } from '@graphql-codegen/core'
66
import { preset } from '@graphql-codegen/import-types-preset'
77
import { plugin as typescriptPlugin } from '@graphql-codegen/typescript'

src/utils/index.ts

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,47 @@ export function defineResolver(
2626
return resolvers
2727
}
2828

29+
// Kullanım için utility type
30+
export type ResolverQuery = Resolvers extends { Query: infer Q }
31+
? Q
32+
: never
33+
34+
export function defineQuery(
35+
resolvers: Resolvers['Query'] = {},
36+
): Resolvers {
37+
return {
38+
Query: {
39+
...resolvers,
40+
},
41+
}
42+
}
43+
44+
export function defineMutation(
45+
resolvers: Resolvers['Mutation'] = {},
46+
): Resolvers {
47+
return {
48+
Mutation: {
49+
...resolvers,
50+
},
51+
}
52+
}
53+
54+
export function defineSubscription(
55+
resolvers: Resolvers['Subscription'] = {},
56+
): Resolvers {
57+
return {
58+
Subscription: {
59+
...resolvers,
60+
},
61+
}
62+
}
63+
64+
export function defineType(
65+
resolvers: Resolvers,
66+
): Resolvers {
67+
return resolvers
68+
}
69+
2970
/**
3071
* Helper function to define GraphQL Yoga configuration with type safety
3172
*/
@@ -64,6 +105,10 @@ export async function scanResolvers(nitro: Nitro) {
64105
const fileContent = await readFile(file.fullPath, 'utf-8')
65106
const parsed = await parseAsync(file.fullPath, fileContent)
66107

108+
const exports: GenImport = {
109+
imports: [],
110+
specifier: file.fullPath,
111+
}
67112
for (const node of parsed.program.body) {
68113
if (
69114
node.type === 'ExportNamedDeclaration'
@@ -74,32 +119,52 @@ export async function scanResolvers(nitro: Nitro) {
74119
if (decl.type === 'VariableDeclarator' && decl.init && decl.id.type === 'Identifier') {
75120
if (decl.init && decl.init.type === 'CallExpression') {
76121
if (decl.init.callee.type === 'Identifier' && decl.init.callee.name === 'defineResolver') {
77-
exportName.push({
78-
specifier: file.fullPath,
79-
imports: [{
80-
name: decl.id.name,
81-
type: 'resolver',
82-
as: `_${hash(decl.id.name + file.path).replace(/-/g, '').slice(0, 10)}`,
83-
}],
122+
exports.imports.push({
123+
name: decl.id.name,
124+
type: 'resolver',
125+
as: `_${hash(decl.id.name + file.path).replace(/-/g, '').slice(0, 6)}`,
84126
})
85127
}
86128

87129
if (decl.init.callee.type === 'Identifier' && decl.init.callee.name === 'defineQuery') {
88-
console.log('Found schema:', decl.id.name)
130+
exports.imports.push({
131+
name: decl.id.name,
132+
type: 'query',
133+
as: `_${hash(decl.id.name + file.path).replace(/-/g, '').slice(0, 6)}`,
134+
})
89135
}
90136

91137
if (decl.init.callee.type === 'Identifier' && decl.init.callee.name === 'defineMutation') {
92-
console.log('Found mutation:', decl.id.name)
138+
exports.imports.push({
139+
name: decl.id.name,
140+
type: 'mutation',
141+
as: `_${hash(decl.id.name + file.path).replace(/-/g, '').slice(0, 6)}`,
142+
})
93143
}
94144

95145
if (decl.init.callee.type === 'Identifier' && decl.init.callee.name === 'defineType') {
96-
console.log('Found type:', decl.id.name)
146+
exports.imports.push({
147+
name: decl.id.name,
148+
type: 'type',
149+
as: `_${hash(decl.id.name + file.path).replace(/-/g, '').slice(0, 6)}`,
150+
})
151+
}
152+
153+
if (decl.init.callee.type === 'Identifier' && decl.init.callee.name === 'defineSubscription') {
154+
exports.imports.push({
155+
name: decl.id.name,
156+
type: 'subscription',
157+
as: `_${hash(decl.id.name + file.path).replace(/-/g, '').slice(0, 6)}`,
158+
})
97159
}
98160
}
99161
}
100162
}
101163
}
102164
}
165+
if (exports.imports.length > 0) {
166+
exportName.push(exports)
167+
}
103168
}
104169

105170
return exportName

0 commit comments

Comments
 (0)