nitro-graphql 2.0.0-beta.24 โ†’ 2.0.0-beta.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,12 +56,12 @@
56
56
 
57
57
  **GraphQL Yoga (recommended):**
58
58
  ```bash
59
- pnpm add nitro-graphql graphql-yoga graphql
59
+ pnpm add nitro-graphql graphql-yoga graphql graphql-config
60
60
  ```
61
61
 
62
62
  **Apollo Server:**
63
63
  ```bash
64
- pnpm add nitro-graphql @apollo/server @apollo/utils.withrequired graphql
64
+ pnpm add nitro-graphql @apollo/server @apollo/utils.withrequired graphql graphql-config
65
65
  ```
66
66
 
67
67
  ### 2. Configure
@@ -145,6 +145,8 @@ type Mutation {
145
145
 
146
146
  ```ts
147
147
  // server/graphql/hello.resolver.ts
148
+ import { defineResolver } from 'nitro-graphql/define'
149
+
148
150
  export const helloResolver = defineResolver({
149
151
  Query: {
150
152
  hello: () => 'Hello from GraphQL!',
@@ -175,6 +177,7 @@ Try these working examples:
175
177
  | [**Vite + Nitro**](./playgrounds/vite/) | Vite with Nitro GraphQL integration | `cd playgrounds/vite && pnpm dev` |
176
178
  | [**Nuxt Integration**](./playgrounds/nuxt/) | Full Nuxt app with client types | `pnpm playground:nuxt` |
177
179
  | [**Apollo Federation**](./playgrounds/federation/) | Federated GraphQL services | `pnpm playground:federation` |
180
+ | [**Drizzle ORM**](./examples/drizzle-orm/) | Drizzle ORM + Zod validation integration | `cd examples/drizzle-orm && pnpm dev` |
178
181
 
179
182
  ### ๐Ÿงช Test Projects
180
183
 
@@ -215,6 +218,8 @@ extend type Mutation {
215
218
  ### 2. Create Resolvers
216
219
  ```ts
217
220
  // server/graphql/users/user.resolver.ts
221
+ import { defineQuery, defineMutation } from 'nitro-graphql/define'
222
+
218
223
  export const userQueries = defineQuery({
219
224
  users: async (_, __, { storage }) => {
220
225
  return await storage.getItem('users') || []
@@ -512,6 +517,8 @@ Create reusable GraphQL directives:
512
517
 
513
518
  ```ts
514
519
  // server/graphql/directives/auth.directive.ts
520
+ import { defineDirective } from 'nitro-graphql/define'
521
+
515
522
  export const authDirective = defineDirective({
516
523
  name: 'auth',
517
524
  locations: ['FIELD_DEFINITION'],
@@ -586,7 +593,11 @@ export default defineNitroConfig({
586
593
 
587
594
  ### Core Utilities
588
595
 
589
- All utilities are auto-imported in resolver files:
596
+ > **โš ๏ธ Breaking Change**: Utilities are **NOT auto-imported**. You must explicitly import them from `nitro-graphql/define`:
597
+
598
+ ```typescript
599
+ import { defineResolver, defineQuery, defineMutation, defineType, defineDirective } from 'nitro-graphql/define'
600
+ ```
590
601
 
591
602
  | Function | Purpose | Example |
592
603
  |----------|---------|---------|
@@ -595,6 +606,11 @@ All utilities are auto-imported in resolver files:
595
606
  | `defineMutation` | Mutation-only resolvers | `defineMutation({ createUser: (...) => {...} })` |
596
607
  | `defineType` | Custom type resolvers | `defineType({ User: { posts: (parent) => [...] } })` |
597
608
  | `defineDirective` | Custom directives | `defineDirective({ name: 'auth', ... })` |
609
+ | `defineGraphQLConfig` | GraphQL server config | `defineGraphQLConfig({ maskedErrors: {...} })` |
610
+ | `defineSchema` | Schema with Zod integration | `defineSchema({ Book: selectBookSchema })` |
611
+
612
+ **Additional Utilities** from `nitro-graphql/utils`:
613
+ - `createDefaultMaskError()` - Error handler for ZodError and HTTPError (use in `defineGraphQLConfig`)
598
614
 
599
615
  ### Type Generation
600
616
 
@@ -648,10 +664,19 @@ server/
648
664
  - โœ… Check file naming: `*.graphql`, `*.resolver.ts`
649
665
  - โœ… Verify exports are named exports
650
666
 
651
- **Import errors**
652
- - โœ… Use correct path: `nitro-graphql/define`
667
+ **Import errors / "defineQuery is not defined"**
668
+ - โœ… **Requires explicit imports**: Add `import { defineQuery } from 'nitro-graphql/define'` to resolver files
669
+ - โœ… Use correct import path: `nitro-graphql/define` (not `nitro-graphql`)
653
670
  - โœ… Use named exports in resolvers
654
671
 
672
+ Example fix:
673
+ ```typescript
674
+ // Add this to the top of your resolver file
675
+ import { defineQuery, defineMutation } from 'nitro-graphql/define'
676
+
677
+ export const myQueries = defineQuery({ ... })
678
+ ```
679
+
655
680
  **Vite: "Parse failure: Expected ';', '}' or <eof>" on GraphQL files**
656
681
  - โœ… Add `graphql()` plugin from `nitro-graphql/vite`
657
682
  - โœ… Ensure `graphql()` is placed **before** `nitro()` in plugins array
@@ -848,6 +873,9 @@ File: server/graphql/users.resolver.ts
848
873
  Action: CREATE NEW FILE
849
874
  Content:
850
875
 
876
+ // Must explicitly import (NOT auto-imported)
877
+ import { defineQuery } from 'nitro-graphql/define'
878
+
851
879
  // โš ๏ธ CRITICAL: Use NAMED EXPORTS (not default export)
852
880
  export const userQueries = defineQuery({
853
881
  users: async (_, __, context) => {
@@ -867,7 +895,7 @@ export const userQueries = defineQuery({
867
895
  }
868
896
  })
869
897
 
870
- Validation: File ends with .resolver.ts and uses named export
898
+ Validation: File ends with .resolver.ts, has import statement, and uses named export
871
899
 
872
900
  ## STEP 7: START DEV SERVER
873
901
  Command: pnpm dev
@@ -923,7 +951,8 @@ Issue: "GraphQL endpoint returns 404"
923
951
  Fix: Ensure 'nitro-graphql/nuxt' is in modules array (not just 'nitro-graphql')
924
952
 
925
953
  Issue: "defineQuery is not defined"
926
- Fix: Restart dev server - auto-imports need to regenerate
954
+ Fix: Add import statement at top of resolver file:
955
+ import { defineQuery } from 'nitro-graphql/define'
927
956
 
928
957
  Issue: "Types not generating"
929
958
  Fix: Check .nuxt/types/nitro-graphql-server.d.ts exists, if not restart dev server
@@ -984,6 +1013,9 @@ type Mutation {
984
1013
  }
985
1014
 
986
1015
  RESOLVERS (server/graphql/products.resolver.ts):
1016
+ // Must explicitly import (NOT auto-imported)
1017
+ import { defineQuery, defineMutation } from 'nitro-graphql/define'
1018
+
987
1019
  // Use NAMED EXPORTS only
988
1020
  export const productQueries = defineQuery({
989
1021
  products: async (_, __, context) => {
@@ -1013,7 +1045,7 @@ export const productMutations = defineMutation({
1013
1045
  KEY RULES:
1014
1046
  - Files: *.graphql for schemas, *.resolver.ts for resolvers
1015
1047
  - MUST use named exports (not default export)
1016
- - defineQuery and defineMutation are auto-imported
1048
+ - MUST explicitly import: import { defineQuery } from 'nitro-graphql/define'
1017
1049
  - Context is the third parameter (access H3 event context)
1018
1050
  - Endpoint: http://localhost:3000/api/graphql
1019
1051
 
@@ -1058,6 +1090,9 @@ type Mutation {
1058
1090
  }
1059
1091
 
1060
1092
  RESOLVERS (server/graphql/books.resolver.ts):
1093
+ // Must explicitly import (NOT auto-imported)
1094
+ import { defineResolver } from 'nitro-graphql/define'
1095
+
1061
1096
  // IMPORTANT: Use NAMED EXPORTS
1062
1097
  export const bookResolver = defineResolver({
1063
1098
  Query: {
@@ -1083,6 +1118,7 @@ export const bookResolver = defineResolver({
1083
1118
 
1084
1119
  KEY RULES:
1085
1120
  - framework: 'apollo-server' in config
1121
+ - MUST explicitly import: import { defineResolver } from 'nitro-graphql/define'
1086
1122
  - defineResolver for complete resolver maps
1087
1123
  - Named exports required (export const name = ...)
1088
1124
  - Apollo Sandbox: http://localhost:3000/api/graphql
@@ -1131,6 +1167,9 @@ extend type Mutation {
1131
1167
  }
1132
1168
 
1133
1169
  RESOLVERS (server/graphql/posts/post.resolver.ts):
1170
+ // Must explicitly import (NOT auto-imported)
1171
+ import { defineQuery, defineMutation } from 'nitro-graphql/define'
1172
+
1134
1173
  // Use NAMED EXPORTS
1135
1174
  export const postQueries = defineQuery({
1136
1175
  posts: async (_, { limit, offset }, context) => {
@@ -1180,6 +1219,7 @@ Import types:
1180
1219
  import type { Post, CreatePostInput } from '#graphql/server'
1181
1220
 
1182
1221
  KEY RULES:
1222
+ - MUST explicitly import: import { defineQuery, defineMutation } from 'nitro-graphql/define'
1183
1223
  - Use "extend type" to add to existing Query/Mutation
1184
1224
  - Named exports required
1185
1225
  - Context has H3 event properties
package/dist/define.d.mts CHANGED
@@ -43,19 +43,19 @@ declare function defineSchema<T extends Partial<Record<keyof ResolversTypes, Sta
43
43
  * ```typescript
44
44
  * export const userResolvers = defineResolver({
45
45
  * Query: {
46
- * user: async (_, { id }, context) => {
46
+ * user: async (parent, { id }, context) => {
47
47
  * return await context.storage.getItem(`user:${id}`)
48
48
  * }
49
49
  * },
50
50
  * Mutation: {
51
- * createUser: async (_, { input }, context) => {
51
+ * createUser: async (parent, { input }, context) => {
52
52
  * const user = { id: generateId(), ...input }
53
53
  * await context.storage.setItem(`user:${user.id}`, user)
54
54
  * return user
55
55
  * }
56
56
  * },
57
57
  * User: {
58
- * fullName: (parent) => `${parent.firstName} ${parent.lastName}`
58
+ * fullName: (parent, args, context) => `${parent.firstName} ${parent.lastName}`
59
59
  * }
60
60
  * })
61
61
  * ```
@@ -74,10 +74,10 @@ declare function defineResolver(resolvers: Resolvers): Resolvers;
74
74
  * @example
75
75
  * ```typescript
76
76
  * export const userQueries = defineQuery({
77
- * user: async (_, { id }, context) => {
77
+ * user: async (parent, { id }, context) => {
78
78
  * return await fetchUser(id)
79
79
  * },
80
- * users: async (_, __, context) => {
80
+ * users: async (parent, args, context) => {
81
81
  * return await fetchAllUsers()
82
82
  * }
83
83
  * })
@@ -100,14 +100,14 @@ declare function defineQuery(resolvers?: Resolvers['Query']): Resolvers;
100
100
  * @example
101
101
  * ```typescript
102
102
  * export const userMutations = defineMutation({
103
- * createUser: async (_, { input }, context) => {
103
+ * createUser: async (parent, { input }, context) => {
104
104
  * const user = await context.db.users.create(input)
105
105
  * return user
106
106
  * },
107
- * updateUser: async (_, { id, input }, context) => {
107
+ * updateUser: async (parent, { id, input }, context) => {
108
108
  * return await context.db.users.update(id, input)
109
109
  * },
110
- * deleteUser: async (_, { id }, context) => {
110
+ * deleteUser: async (parent, { id }, context) => {
111
111
  * return await context.db.users.delete(id)
112
112
  * }
113
113
  * })
@@ -133,13 +133,13 @@ declare function defineMutation(resolvers?: Resolvers['Mutation']): Resolvers;
133
133
  *
134
134
  * export const messageSubscriptions = defineSubscription({
135
135
  * messageAdded: {
136
- * subscribe: async function* (_, { channelId }, context) {
136
+ * subscribe: async function* (parent, { channelId }, context) {
137
137
  * const pubsub = context.pubsub
138
138
  * yield* pubsub.subscribe(`channel:${channelId}`)
139
139
  * }
140
140
  * },
141
141
  * userStatusChanged: {
142
- * subscribe: async (_, __, context) => {
142
+ * subscribe: async (parent, args, context) => {
143
143
  * return new Repeater(async (push, stop) => {
144
144
  * // Real-time subscription logic
145
145
  * })
@@ -197,6 +197,8 @@ declare function defineType(resolvers: Resolvers): Resolvers;
197
197
  *
198
198
  * @example
199
199
  * ```typescript
200
+ * import { createDefaultMaskError } from 'nitro-graphql/utils'
201
+ *
200
202
  * // GraphQL Yoga configuration
201
203
  * export default defineGraphQLConfig({
202
204
  * schema: {
@@ -208,10 +210,10 @@ declare function defineType(resolvers: Resolvers): Resolvers;
208
210
  * db: getDatabase()
209
211
  * }
210
212
  * },
211
- * yoga: {
212
- * graphiql: true,
213
- * maskedErrors: false
214
- * }
213
+ * maskedErrors: {
214
+ * maskError: createDefaultMaskError()
215
+ * },
216
+ * graphiql: true
215
217
  * })
216
218
  * ```
217
219
  *
package/dist/define.mjs CHANGED
@@ -39,19 +39,19 @@ function defineSchema(config) {
39
39
  * ```typescript
40
40
  * export const userResolvers = defineResolver({
41
41
  * Query: {
42
- * user: async (_, { id }, context) => {
42
+ * user: async (parent, { id }, context) => {
43
43
  * return await context.storage.getItem(`user:${id}`)
44
44
  * }
45
45
  * },
46
46
  * Mutation: {
47
- * createUser: async (_, { input }, context) => {
47
+ * createUser: async (parent, { input }, context) => {
48
48
  * const user = { id: generateId(), ...input }
49
49
  * await context.storage.setItem(`user:${user.id}`, user)
50
50
  * return user
51
51
  * }
52
52
  * },
53
53
  * User: {
54
- * fullName: (parent) => `${parent.firstName} ${parent.lastName}`
54
+ * fullName: (parent, args, context) => `${parent.firstName} ${parent.lastName}`
55
55
  * }
56
56
  * })
57
57
  * ```
@@ -72,10 +72,10 @@ function defineResolver(resolvers) {
72
72
  * @example
73
73
  * ```typescript
74
74
  * export const userQueries = defineQuery({
75
- * user: async (_, { id }, context) => {
75
+ * user: async (parent, { id }, context) => {
76
76
  * return await fetchUser(id)
77
77
  * },
78
- * users: async (_, __, context) => {
78
+ * users: async (parent, args, context) => {
79
79
  * return await fetchAllUsers()
80
80
  * }
81
81
  * })
@@ -100,14 +100,14 @@ function defineQuery(resolvers = {}) {
100
100
  * @example
101
101
  * ```typescript
102
102
  * export const userMutations = defineMutation({
103
- * createUser: async (_, { input }, context) => {
103
+ * createUser: async (parent, { input }, context) => {
104
104
  * const user = await context.db.users.create(input)
105
105
  * return user
106
106
  * },
107
- * updateUser: async (_, { id, input }, context) => {
107
+ * updateUser: async (parent, { id, input }, context) => {
108
108
  * return await context.db.users.update(id, input)
109
109
  * },
110
- * deleteUser: async (_, { id }, context) => {
110
+ * deleteUser: async (parent, { id }, context) => {
111
111
  * return await context.db.users.delete(id)
112
112
  * }
113
113
  * })
@@ -135,13 +135,13 @@ function defineMutation(resolvers = {}) {
135
135
  *
136
136
  * export const messageSubscriptions = defineSubscription({
137
137
  * messageAdded: {
138
- * subscribe: async function* (_, { channelId }, context) {
138
+ * subscribe: async function* (parent, { channelId }, context) {
139
139
  * const pubsub = context.pubsub
140
140
  * yield* pubsub.subscribe(`channel:${channelId}`)
141
141
  * }
142
142
  * },
143
143
  * userStatusChanged: {
144
- * subscribe: async (_, __, context) => {
144
+ * subscribe: async (parent, args, context) => {
145
145
  * return new Repeater(async (push, stop) => {
146
146
  * // Real-time subscription logic
147
147
  * })
@@ -203,6 +203,8 @@ function defineType(resolvers) {
203
203
  *
204
204
  * @example
205
205
  * ```typescript
206
+ * import { createDefaultMaskError } from 'nitro-graphql/utils'
207
+ *
206
208
  * // GraphQL Yoga configuration
207
209
  * export default defineGraphQLConfig({
208
210
  * schema: {
@@ -214,10 +216,10 @@ function defineType(resolvers) {
214
216
  * db: getDatabase()
215
217
  * }
216
218
  * },
217
- * yoga: {
218
- * graphiql: true,
219
- * maskedErrors: false
220
- * }
219
+ * maskedErrors: {
220
+ * maskError: createDefaultMaskError()
221
+ * },
222
+ * graphiql: true
221
223
  * })
222
224
  * ```
223
225
  *
@@ -1,4 +1,4 @@
1
- import * as h31 from "h3";
1
+ import * as h35 from "h3";
2
2
 
3
3
  //#region src/routes/debug.d.ts
4
4
 
@@ -10,7 +10,7 @@ import * as h31 from "h3";
10
10
  * - /_nitro/graphql/debug - HTML dashboard
11
11
  * - /_nitro/graphql/debug?format=json - JSON API
12
12
  */
13
- declare const _default: h31.EventHandlerWithFetch<h31.EventHandlerRequest, Promise<string | {
13
+ declare const _default: h35.EventHandlerWithFetch<h35.EventHandlerRequest, Promise<string | {
14
14
  timestamp: string;
15
15
  environment: {
16
16
  dev: any;
@@ -1,6 +1,6 @@
1
- import * as h35 from "h3";
1
+ import * as h30 from "h3";
2
2
 
3
3
  //#region src/routes/graphql-yoga.d.ts
4
- declare const _default: h35.EventHandlerWithFetch<h35.EventHandlerRequest, Promise<Response>>;
4
+ declare const _default: h30.EventHandlerWithFetch<h30.EventHandlerRequest, Promise<Response>>;
5
5
  //#endregion
6
6
  export { _default as default };
@@ -84,6 +84,10 @@ var graphql_yoga_default = defineEventHandler(async (event) => {
84
84
  renderGraphiQL: () => apolloSandboxHtml
85
85
  }, importedConfig));
86
86
  const response = await yoga.handleRequest(event.req, event);
87
+ if (event.res.statusCode && event.res.statusCode !== 200) return new Response(response.body, {
88
+ ...response,
89
+ status: event.res.statusCode
90
+ });
87
91
  return new Response(response.body, response);
88
92
  });
89
93
 
@@ -1,7 +1,7 @@
1
- import * as h30 from "h3";
1
+ import * as h31 from "h3";
2
2
 
3
3
  //#region src/routes/health.d.ts
4
- declare const _default: h30.EventHandlerWithFetch<h30.EventHandlerRequest, Promise<{
4
+ declare const _default: h31.EventHandlerWithFetch<h31.EventHandlerRequest, Promise<{
5
5
  status: string;
6
6
  message: string;
7
7
  timestamp: string;
@@ -8,7 +8,18 @@ import { NPMConfig } from "#graphql/server";
8
8
  type Flatten<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;
9
9
  type DefineServerConfig<T extends NPMConfig = NPMConfig> = T['framework'] extends 'graphql-yoga' ? Partial<YogaServerOptions<H3Event, Partial<H3Event>>> : T['framework'] extends 'apollo-server' ? Partial<ApolloServerOptions<H3Event>> : Partial<YogaServerOptions<H3Event, Partial<H3Event>>> | Partial<ApolloServerOptions<H3Event>>;
10
10
  type DirectiveLocationName = 'QUERY' | 'MUTATION' | 'SUBSCRIPTION' | 'FIELD' | 'FRAGMENT_DEFINITION' | 'FRAGMENT_SPREAD' | 'INLINE_FRAGMENT' | 'VARIABLE_DEFINITION' | 'SCHEMA' | 'SCALAR' | 'OBJECT' | 'FIELD_DEFINITION' | 'ARGUMENT_DEFINITION' | 'INTERFACE' | 'UNION' | 'ENUM' | 'ENUM_VALUE' | 'INPUT_OBJECT' | 'INPUT_FIELD_DEFINITION';
11
+ type GraphQLScalarType = 'String' | 'Int' | 'Float' | 'Boolean' | 'ID' | 'JSON' | 'DateTime';
12
+ type GraphQLBaseType = GraphQLScalarType | (string & {});
11
13
  type GraphQLArgumentType = 'String' | 'Int' | 'Float' | 'Boolean' | 'ID' | 'JSON' | 'DateTime' | 'String!' | 'Int!' | 'Float!' | 'Boolean!' | 'ID!' | 'JSON!' | 'DateTime!' | '[String]' | '[String!]' | '[String]!' | '[String!]!' | '[Int]' | '[Int!]' | '[Int]!' | '[Int!]!' | '[Float]' | '[Float!]' | '[Float]!' | '[Float!]!' | '[Boolean]' | '[Boolean!]' | '[Boolean]!' | '[Boolean!]!' | '[ID]' | '[ID!]' | '[ID]!' | '[ID!]!' | '[JSON]' | '[JSON!]' | '[JSON]!' | '[JSON!]!' | '[DateTime]' | '[DateTime!]' | '[DateTime]!' | '[DateTime!]!' | (string & {});
14
+ interface DirectiveArgument<T extends GraphQLArgumentType = GraphQLArgumentType> {
15
+ /**
16
+ * GraphQL type for the argument
17
+ * @example 'String', 'Int!', '[String!]!', 'DateTime', 'JSON'
18
+ */
19
+ type: T;
20
+ defaultValue?: any;
21
+ description?: string;
22
+ }
12
23
  interface DirectiveArg {
13
24
  type: GraphQLArgumentType;
14
25
  defaultValue?: any;
@@ -35,4 +46,4 @@ interface DefineDirectiveConfig {
35
46
  transformer?: (schema: GraphQLSchema) => GraphQLSchema;
36
47
  }
37
48
  //#endregion
38
- export { DefineDirectiveConfig, DefineServerConfig, DirectiveDefinition, Flatten };
49
+ export { DefineDirectiveConfig, DefineServerConfig, DirectiveArgument, DirectiveDefinition, Flatten, GraphQLArgumentType, GraphQLBaseType, GraphQLScalarType };
@@ -0,0 +1 @@
1
+ export { };
@@ -243,4 +243,4 @@ interface NitroGraphQLOptions {
243
243
  paths?: PathsConfig;
244
244
  }
245
245
  //#endregion
246
- export { ClientUtilsConfig, CodegenClientConfig, ExternalGraphQLService, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, ScaffoldConfig, SdkConfig, TypesConfig };
246
+ export { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, StandardSchemaV1, TypesConfig };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,73 @@
1
+ //#region src/utils/errors.d.ts
2
+ interface MaskErrorOptions {
3
+ /**
4
+ * Default HTTP status code for validation errors (ZodError)
5
+ * @default 400
6
+ */
7
+ validationStatusCode?: number;
8
+ /**
9
+ * Default HTTP status code for HTTP errors when status is not provided
10
+ * @default 500
11
+ */
12
+ defaultHttpStatusCode?: number;
13
+ }
14
+ /**
15
+ * Default error masking function for GraphQL Yoga
16
+ * Handles common error types like ZodError and HTTPError
17
+ *
18
+ * @param options - Configuration options for error handling
19
+ *
20
+ * @example Basic usage
21
+ * ```ts
22
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
23
+ * import { createDefaultMaskError } from 'nitro-graphql/utils'
24
+ *
25
+ * export default defineGraphQLConfig({
26
+ * maskedErrors: {
27
+ * maskError: createDefaultMaskError()
28
+ * }
29
+ * })
30
+ * ```
31
+ *
32
+ * @example Custom status codes
33
+ * ```ts
34
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
35
+ * import { createDefaultMaskError } from 'nitro-graphql/utils'
36
+ *
37
+ * export default defineGraphQLConfig({
38
+ * maskedErrors: {
39
+ * maskError: createDefaultMaskError({
40
+ * validationStatusCode: 422, // Use 422 for validation errors
41
+ * defaultHttpStatusCode: 500 // Use 500 for unknown HTTP errors
42
+ * })
43
+ * }
44
+ * })
45
+ * ```
46
+ *
47
+ * @example Custom error handling with fallback to default
48
+ * ```ts
49
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
50
+ * import { createDefaultMaskError } from 'nitro-graphql/utils'
51
+ *
52
+ * const defaultMaskError = createDefaultMaskError()
53
+ *
54
+ * export default defineGraphQLConfig({
55
+ * maskedErrors: {
56
+ * maskError: (error: unknown) => {
57
+ * // Handle custom errors first
58
+ * if (error instanceof MyCustomError) {
59
+ * return new GraphQLError(error.message, {
60
+ * extensions: { code: 'CUSTOM_ERROR' }
61
+ * })
62
+ * }
63
+ *
64
+ * // Fall back to default handling
65
+ * return defaultMaskError(error)
66
+ * }
67
+ * }
68
+ * })
69
+ * ```
70
+ */
71
+ declare function createDefaultMaskError(options?: MaskErrorOptions): (error: unknown) => Error;
72
+ //#endregion
73
+ export { MaskErrorOptions, createDefaultMaskError };
@@ -0,0 +1,89 @@
1
+ import { GraphQLError } from "graphql";
2
+
3
+ //#region src/utils/errors.ts
4
+ /**
5
+ * Default error masking function for GraphQL Yoga
6
+ * Handles common error types like ZodError and HTTPError
7
+ *
8
+ * @param options - Configuration options for error handling
9
+ *
10
+ * @example Basic usage
11
+ * ```ts
12
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
13
+ * import { createDefaultMaskError } from 'nitro-graphql/utils'
14
+ *
15
+ * export default defineGraphQLConfig({
16
+ * maskedErrors: {
17
+ * maskError: createDefaultMaskError()
18
+ * }
19
+ * })
20
+ * ```
21
+ *
22
+ * @example Custom status codes
23
+ * ```ts
24
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
25
+ * import { createDefaultMaskError } from 'nitro-graphql/utils'
26
+ *
27
+ * export default defineGraphQLConfig({
28
+ * maskedErrors: {
29
+ * maskError: createDefaultMaskError({
30
+ * validationStatusCode: 422, // Use 422 for validation errors
31
+ * defaultHttpStatusCode: 500 // Use 500 for unknown HTTP errors
32
+ * })
33
+ * }
34
+ * })
35
+ * ```
36
+ *
37
+ * @example Custom error handling with fallback to default
38
+ * ```ts
39
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
40
+ * import { createDefaultMaskError } from 'nitro-graphql/utils'
41
+ *
42
+ * const defaultMaskError = createDefaultMaskError()
43
+ *
44
+ * export default defineGraphQLConfig({
45
+ * maskedErrors: {
46
+ * maskError: (error: unknown) => {
47
+ * // Handle custom errors first
48
+ * if (error instanceof MyCustomError) {
49
+ * return new GraphQLError(error.message, {
50
+ * extensions: { code: 'CUSTOM_ERROR' }
51
+ * })
52
+ * }
53
+ *
54
+ * // Fall back to default handling
55
+ * return defaultMaskError(error)
56
+ * }
57
+ * }
58
+ * })
59
+ * ```
60
+ */
61
+ function createDefaultMaskError(options) {
62
+ const validationStatusCode = options?.validationStatusCode ?? 400;
63
+ const defaultHttpStatusCode = options?.defaultHttpStatusCode ?? 500;
64
+ return (error) => {
65
+ if (error && typeof error === "object" && "originalError" in error) {
66
+ const graphqlError = error;
67
+ if (graphqlError.originalError && typeof graphqlError.originalError === "object" && "issues" in graphqlError.originalError && Array.isArray(graphqlError.originalError.issues)) return new GraphQLError("Validation failed", { extensions: {
68
+ code: "BAD_USER_INPUT",
69
+ validationErrors: graphqlError.originalError.issues.map((issue) => ({
70
+ field: issue.path.join("."),
71
+ message: issue.message
72
+ })),
73
+ http: { status: validationStatusCode }
74
+ } });
75
+ if (graphqlError.originalError && typeof graphqlError.originalError === "object" && "statusCode" in graphqlError.originalError && "statusMessage" in graphqlError.originalError) {
76
+ const httpError = graphqlError.originalError;
77
+ const statusCode = httpError.statusCode ?? defaultHttpStatusCode;
78
+ return new GraphQLError(httpError.statusMessage || httpError.message || "Internal Server Error", { extensions: {
79
+ code: statusCode,
80
+ http: { status: statusCode }
81
+ } });
82
+ }
83
+ }
84
+ return error instanceof Error ? error : new Error(String(error));
85
+ };
86
+ }
87
+
88
+ //#endregion
89
+ export { createDefaultMaskError };
@@ -1,5 +1,6 @@
1
1
  import { GenImport } from "../types/index.mjs";
2
2
  import { directiveParser, generateDirectiveSchema, generateDirectiveSchemas } from "./directive-parser.mjs";
3
+ import { createDefaultMaskError } from "./errors.mjs";
3
4
  import { Nitro } from "nitro/types";
4
5
 
5
6
  //#region src/utils/index.d.ts
@@ -36,4 +37,4 @@ declare function scanExternalServiceDocs(nitro: Nitro, serviceName: string, patt
36
37
  */
37
38
  declare function validateExternalServices(services: unknown[]): string[];
38
39
  //#endregion
39
- export { GLOB_SCAN_PATTERN, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, validateExternalServices };
40
+ export { GLOB_SCAN_PATTERN, createDefaultMaskError, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, validateExternalServices };
@@ -1,4 +1,5 @@
1
1
  import { directiveParser, generateDirectiveSchema, generateDirectiveSchemas } from "./directive-parser.mjs";
2
+ import { createDefaultMaskError } from "./errors.mjs";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import { join, relative } from "pathe";
4
5
  import { hash } from "ohash";
@@ -275,4 +276,4 @@ async function scanDir(nitro, dir, name, globPattern = GLOB_SCAN_PATTERN) {
275
276
  }
276
277
 
277
278
  //#endregion
278
- export { GLOB_SCAN_PATTERN, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, validateExternalServices };
279
+ export { GLOB_SCAN_PATTERN, createDefaultMaskError, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, validateExternalServices };
@@ -61,7 +61,7 @@ async function generateTypes(selectFremework, schema, config = {}, outputPath) {
61
61
  return {
62
62
  prepend: [
63
63
  `import schemas from '#graphql/schema'`,
64
- `import type { StandardSchemaV1 } from 'nitro-graphql'`,
64
+ `import type { StandardSchemaV1 } from 'nitro-graphql/types'`,
65
65
  `
66
66
  export interface NPMConfig {
67
67
  framework: '${selectFremework || "graphql-yoga"}';
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "nitro-graphql",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.24",
4
+ "version": "2.0.0-beta.25",
5
+ "packageManager": "pnpm@10.22.0",
5
6
  "description": "GraphQL integration for Nitro",
6
7
  "license": "MIT",
7
8
  "sideEffects": false,
@@ -59,6 +60,10 @@
59
60
  "./vite": {
60
61
  "types": "./dist/vite.d.mts",
61
62
  "import": "./dist/vite.mjs"
63
+ },
64
+ "./types": {
65
+ "types": "./dist/types/index.d.mts",
66
+ "import": "./dist/types/index.mjs"
62
67
  }
63
68
  },
64
69
  "module": "./dist/index.mjs",
@@ -66,6 +71,22 @@
66
71
  "files": [
67
72
  "dist"
68
73
  ],
74
+ "scripts": {
75
+ "prepack": "pnpm build",
76
+ "build": "tsdown",
77
+ "dev": "tsdown --watch",
78
+ "bumpp": "bumpp package.json",
79
+ "release": "pnpm build && pnpm bumpp && pnpm publish --no-git-checks --access public",
80
+ "playground:nitro": "cd playgrounds/nitro && pnpm install && pnpm dev",
81
+ "playground:nuxt": "cd playgrounds/nuxt && pnpm install && pnpm dev",
82
+ "playground:federation": "cd playgrounds/federation && pnpm install && pnpm dev",
83
+ "docs:dev": "cd .docs && pnpm install && pnpm update:metadata && pnpm dev",
84
+ "docs:build": "cd .docs && pnpm install && pnpm update:metadata && pnpm build",
85
+ "docs:preview": "cd .docs && pnpm preview",
86
+ "lint": "eslint .",
87
+ "lint:fix": "eslint . --fix",
88
+ "test:types": "tsc --noEmit"
89
+ },
69
90
  "peerDependencies": {
70
91
  "@apollo/server": "^5.0.0",
71
92
  "@apollo/utils.withrequired": "^3.0.0",
@@ -82,66 +103,57 @@
82
103
  }
83
104
  },
84
105
  "dependencies": {
85
- "@apollo/subgraph": "^2.12.1",
86
- "@graphql-codegen/core": "^5.0.0",
87
- "@graphql-codegen/import-types-preset": "^3.0.1",
88
- "@graphql-codegen/typescript": "^5.0.4",
89
- "@graphql-codegen/typescript-generic-sdk": "^4.0.2",
90
- "@graphql-codegen/typescript-operations": "^5.0.4",
91
- "@graphql-codegen/typescript-resolvers": "^5.1.2",
92
- "@graphql-tools/graphql-file-loader": "^8.1.6",
93
- "@graphql-tools/load": "^8.1.6",
94
- "@graphql-tools/load-files": "^7.0.1",
95
- "@graphql-tools/merge": "^9.1.5",
96
- "@graphql-tools/schema": "^10.0.29",
97
- "@graphql-tools/url-loader": "^9.0.4",
98
- "@graphql-tools/utils": "^10.10.3",
99
- "chokidar": "^4.0.3",
100
- "consola": "^3.4.2",
101
- "defu": "^6.1.4",
102
- "graphql-config": "^5.1.5",
103
- "graphql-scalars": "^1.25.0",
104
- "knitwork": "^1.3.0",
105
- "ohash": "^2.0.11",
106
- "oxc-parser": "^0.97.0",
107
- "pathe": "^2.0.3",
108
- "tinyglobby": "^0.2.15"
106
+ "@apollo/subgraph": "catalog:",
107
+ "@graphql-codegen/core": "catalog:",
108
+ "@graphql-codegen/import-types-preset": "catalog:",
109
+ "@graphql-codegen/typescript": "catalog:",
110
+ "@graphql-codegen/typescript-generic-sdk": "catalog:",
111
+ "@graphql-codegen/typescript-operations": "catalog:",
112
+ "@graphql-codegen/typescript-resolvers": "catalog:",
113
+ "@graphql-tools/graphql-file-loader": "catalog:",
114
+ "@graphql-tools/load": "catalog:",
115
+ "@graphql-tools/load-files": "catalog:",
116
+ "@graphql-tools/merge": "catalog:",
117
+ "@graphql-tools/schema": "catalog:",
118
+ "@graphql-tools/url-loader": "catalog:",
119
+ "@graphql-tools/utils": "catalog:",
120
+ "chokidar": "catalog:",
121
+ "consola": "catalog:",
122
+ "defu": "catalog:",
123
+ "graphql-config": "catalog:",
124
+ "graphql-scalars": "catalog:",
125
+ "knitwork": "catalog:",
126
+ "ohash": "catalog:",
127
+ "oxc-parser": "catalog:",
128
+ "pathe": "catalog:",
129
+ "tinyglobby": "catalog:"
109
130
  },
110
131
  "devDependencies": {
111
- "@antfu/eslint-config": "^6.2.0",
112
- "@nuxt/kit": "^4.2.1",
113
- "@nuxt/schema": "^4.2.1",
114
- "@types/node": "^24.10.1",
115
- "@vitejs/devtools": "^0.0.0-alpha.16",
116
- "bumpp": "^10.3.1",
117
- "changelogen": "^0.6.2",
118
- "crossws": "^0.4.1",
119
- "eslint": "^9.39.1",
120
- "graphql": "^16.12.0",
121
- "graphql-yoga": "^5.16.2",
122
- "h3": "^2.0.1-rc.5",
123
- "nitro": "npm:nitro-nightly@latest",
124
- "tsdown": "^0.16.4",
125
- "typescript": "^5.9.3",
126
- "vite": "npm:rolldown-vite@latest",
127
- "vitepress-plugin-llms": "^1.9.1"
132
+ "@antfu/eslint-config": "catalog:",
133
+ "@nuxt/kit": "catalog:",
134
+ "@nuxt/schema": "catalog:",
135
+ "@types/node": "catalog:",
136
+ "@vitejs/devtools": "catalog:",
137
+ "bumpp": "catalog:",
138
+ "changelogen": "catalog:",
139
+ "crossws": "catalog:",
140
+ "eslint": "catalog:",
141
+ "graphql": "catalog:",
142
+ "graphql-yoga": "catalog:",
143
+ "h3": "catalog:",
144
+ "nitro": "catalog:",
145
+ "tsdown": "catalog:",
146
+ "typescript": "catalog:",
147
+ "vite": "catalog:",
148
+ "vitepress-plugin-llms": "catalog:"
149
+ },
150
+ "pnpm": {
151
+ "overrides": {
152
+ "nitro": "npm:nitro-nightly@latest",
153
+ "vite": "npm:rolldown-vite@latest"
154
+ }
128
155
  },
129
156
  "resolutions": {
130
157
  "nitro-graphql": "link:."
131
- },
132
- "scripts": {
133
- "build": "tsdown",
134
- "dev": "tsdown --watch",
135
- "bumpp": "bumpp package.json",
136
- "release": "pnpm build && pnpm bumpp && pnpm publish --no-git-checks --access public",
137
- "playground:nitro": "cd playgrounds/nitro && pnpm install && pnpm dev",
138
- "playground:nuxt": "cd playgrounds/nuxt && pnpm install && pnpm dev",
139
- "playground:federation": "cd playgrounds/federation && pnpm install && pnpm dev",
140
- "docs:dev": "cd .docs && pnpm install && pnpm update:metadata && pnpm dev",
141
- "docs:build": "cd .docs && pnpm install && pnpm update:metadata && pnpm build",
142
- "docs:preview": "cd .docs && pnpm preview",
143
- "lint": "eslint .",
144
- "lint:fix": "eslint . --fix",
145
- "test:types": "tsc --noEmit"
146
158
  }
147
- }
159
+ }