Skip to content

Commit f4a9f10

Browse files
feat: add schema and define schemas for GraphQL integration
1 parent a8bd534 commit f4a9f10

File tree

6 files changed

+76
-34
lines changed

6 files changed

+76
-34
lines changed

playground/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"preview": "node .output/server/index.mjs"
88
},
99
"dependencies": {
10-
"nitro-graphql": "link:../"
10+
"nitro-graphql": "link:../",
11+
"zod": "^4.0.5"
1112
},
1213
"devDependencies": {
1314
"nitropack": "^2.11.13"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { SchemaType } from '#graphql/server'
2+
import { z } from 'zod/v4'
3+
4+
export const schemas: SchemaType = {
5+
Todo: z.object({
6+
id: z.string(),
7+
}),
8+
}

playground/server/graphql/todos/todo-queries.resolver.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ export default defineResolver({
44
// const todos = await storage.getItem('todos') || []
55
return [{
66
id: '1',
7-
title: 'Sample Todo',
8-
completed: false,
9-
createdAt: new Date().toISOString(),
107
}]
118
},
129

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/codegen.ts

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,14 @@ export async function generateTypes(
6060
contextType: 'h3#H3Event',
6161
maybeValue: 'T | null | undefined',
6262
inputMaybeValue: 'T | undefined',
63-
enumsAsTypes: true,
64-
useTypeImports: true,
63+
declarationKind: 'interface',
64+
allowParentTypeOverride: false,
65+
// Type safety maximization
6566
strictScalars: true,
66-
emitLegacyCommonJSImports: false,
67+
// Modern TypeScript support
68+
useTypeImports: true,
69+
enumsAsTypes: true,
70+
immutableTypes: true,
6771
}
6872

6973
const mergedConfig = defu(config, defaultConfig)
@@ -84,38 +88,58 @@ export async function generateTypes(
8488
plugin: pluginContent,
8589
},
8690
imports: {
87-
plugin: () => ({
88-
prepend: [
89-
`type Primitive =
90-
| null
91-
| undefined
92-
| string
93-
| number
94-
| boolean
95-
| symbol
96-
| bigint;
91+
plugin: () => {
92+
return {
93+
prepend: [
94+
`import { schemas } from '#graphql/schemas'`,
95+
`import type { StandardSchemaV1 } from 'nitro-graphql'`,
96+
97+
`
98+
export type SchemaType = Partial<Record<Partial<keyof ResolversTypes>, StandardSchemaV1>>
99+
type SchemaKeys = keyof typeof schemas;
100+
101+
type InferInput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferInput<T> : unknown;
102+
type InferOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : unknown;
103+
104+
type InferInputFromSchema<T extends SchemaKeys> = InferInput<(typeof schemas)[T]>;
105+
type InferOutputFromSchema<T extends SchemaKeys> = InferOutput<(typeof schemas)[T]>;
106+
107+
type Primitive =
108+
| null
109+
| undefined
110+
| string
111+
| number
112+
| boolean
113+
| symbol
114+
| bigint;
97115
98116
type BuiltIns = Primitive | void | Date | RegExp;
99117
118+
100119
type ResolverReturnType<T> = T extends BuiltIns
101-
? T
102-
: T extends (...args: any[]) => unknown
103-
? T | undefined
104-
: T extends object
105-
? T extends Array<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
106-
? ItemType[] extends T // Test for arrays (non-tuples) specifically
107-
? Array<ResolverReturnType<ItemType>>
108-
: ResolverReturnTypeObject<T> // Tuples behave properly
109-
: ResolverReturnTypeObject<T>
110-
: unknown;
120+
? T
121+
: T extends (...args: any[]) => unknown
122+
? T | undefined
123+
: T extends object
124+
? T extends Array<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
125+
? ItemType[] extends T // Test for arrays (non-tuples) specifically
126+
? Array<ResolverReturnType<ItemType>>
127+
: ResolverReturnTypeObject<T> // Tuples behave properly
128+
: ResolverReturnTypeObject<T>
129+
: unknown;
111130
112-
type ResolverReturnTypeObject<T extends object> = {
113-
[K in keyof T]: ResolverReturnType<T[K]>
114-
};`,
115-
'',
116-
],
117-
content: '',
118-
}),
131+
type ResolverReturnTypeObject<T extends object> =
132+
T extends { __typename?: infer TTypename }
133+
? TTypename extends SchemaKeys
134+
? InferOutputFromSchema<TTypename>
135+
: { [K in keyof T]: ResolverReturnType<T[K]> }
136+
: { [K in keyof T]: ResolverReturnType<T[K]> };
137+
`,
138+
'',
139+
],
140+
content: '',
141+
}
142+
},
119143
},
120144
typescript: typescriptPlugin,
121145
typescriptResolvers: typescriptResolversPlugin,

src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ declare module 'nitro-graphql' {
181181
`
182182

183183
writeFileSync(join(typesDir, 'graphql.d.ts'), graphqlDtsContent)
184+
nitro.options.typescript.strict = true
184185

185186
nitro.hooks.hook('types:extend', (types) => {
186187
// Add TypeScript path alias for IDE support
@@ -193,6 +194,9 @@ declare module 'nitro-graphql' {
193194
types.tsConfig.compilerOptions.paths['#graphql/client'] = [
194195
relativeWithDot(tsconfigDir, join(typesDir, 'nitro-graphql-client.d.ts')),
195196
]
197+
types.tsConfig.compilerOptions.paths['#graphql/schemas'] = [
198+
relativeWithDot(tsconfigDir, join(nitro.graphql.serverDir, 'schemas.ts')),
199+
]
196200
types.tsConfig.include = types.tsConfig.include || []
197201
types.tsConfig.include.push(
198202
relativeWithDot(tsconfigDir, join(typesDir, 'nitro-graphql-server.d.ts')),

0 commit comments

Comments
 (0)