nitro-graphql 2.0.0-beta.24 → 2.0.0-beta.26
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 +127 -520
- package/dist/define.d.mts +16 -14
- package/dist/define.mjs +16 -14
- package/dist/rollup.mjs +2 -2
- package/dist/routes/apollo-server.d.mts +2 -2
- package/dist/routes/graphql-yoga.mjs +4 -0
- package/dist/routes/health.d.mts +2 -2
- package/dist/setup.mjs +37 -46
- package/dist/types/define.d.mts +12 -1
- package/dist/types/define.mjs +1 -0
- package/dist/types/index.d.mts +1 -1
- package/dist/types/index.mjs +1 -0
- package/dist/types/standard-schema.mjs +1 -0
- package/dist/utils/client-codegen.d.mts +4 -1
- package/dist/utils/client-codegen.mjs +2 -2
- package/dist/utils/errors.d.mts +73 -0
- package/dist/utils/errors.mjs +89 -0
- package/dist/utils/index.d.mts +2 -1
- package/dist/utils/index.mjs +16 -5
- package/dist/utils/server-codegen.mjs +1 -1
- package/dist/utils/type-generation.d.mts +7 -2
- package/dist/utils/type-generation.mjs +20 -19
- package/package.json +5 -1
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 (
|
|
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 (
|
|
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 (
|
|
77
|
+
* user: async (parent, { id }, context) => {
|
|
78
78
|
* return await fetchUser(id)
|
|
79
79
|
* },
|
|
80
|
-
* users: async (
|
|
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 (
|
|
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 (
|
|
107
|
+
* updateUser: async (parent, { id, input }, context) => {
|
|
108
108
|
* return await context.db.users.update(id, input)
|
|
109
109
|
* },
|
|
110
|
-
* deleteUser: async (
|
|
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* (
|
|
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 (
|
|
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
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
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 (
|
|
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 (
|
|
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 (
|
|
75
|
+
* user: async (parent, { id }, context) => {
|
|
76
76
|
* return await fetchUser(id)
|
|
77
77
|
* },
|
|
78
|
-
* users: async (
|
|
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 (
|
|
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 (
|
|
107
|
+
* updateUser: async (parent, { id, input }, context) => {
|
|
108
108
|
* return await context.db.users.update(id, input)
|
|
109
109
|
* },
|
|
110
|
-
* deleteUser: async (
|
|
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* (
|
|
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 (
|
|
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
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
219
|
+
* maskedErrors: {
|
|
220
|
+
* maskError: createDefaultMaskError()
|
|
221
|
+
* },
|
|
222
|
+
* graphiql: true
|
|
221
223
|
* })
|
|
222
224
|
* ```
|
|
223
225
|
*
|
package/dist/rollup.mjs
CHANGED
|
@@ -94,8 +94,8 @@ async function rollupConfig(app) {
|
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
96
|
app.hooks.hook("dev:reload", async () => {
|
|
97
|
-
await serverTypeGeneration(app);
|
|
98
|
-
await clientTypeGeneration(app);
|
|
97
|
+
await serverTypeGeneration(app, { silent: true });
|
|
98
|
+
await clientTypeGeneration(app, { silent: true });
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
101
|
function virtualSchemas(app) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h30 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/apollo-server.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h30.EventHandlerWithFetch<h30.EventHandlerRequest, Promise<any>>;
|
|
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
|
|
package/dist/routes/health.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h33 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/health.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h33.EventHandlerWithFetch<h33.EventHandlerRequest, Promise<{
|
|
5
5
|
status: string;
|
|
6
6
|
message: string;
|
|
7
7
|
timestamp: string;
|
package/dist/setup.mjs
CHANGED
|
@@ -12,20 +12,21 @@ import consola from "consola";
|
|
|
12
12
|
import { dirname, join, relative, resolve } from "pathe";
|
|
13
13
|
|
|
14
14
|
//#region src/setup.ts
|
|
15
|
+
const logger = consola.withTag("nitro-graphql");
|
|
15
16
|
/**
|
|
16
17
|
* Shared setup logic for nitro-graphql module
|
|
17
18
|
* Used by both the direct Nitro module export and the Vite plugin's nitro: hook
|
|
18
19
|
*/
|
|
19
20
|
async function setupNitroGraphQL(nitro) {
|
|
20
|
-
if (!nitro.options.graphql?.framework)
|
|
21
|
+
if (!nitro.options.graphql?.framework) logger.warn("No GraphQL framework specified. Please set graphql.framework to \"graphql-yoga\" or \"apollo-server\".");
|
|
21
22
|
if (nitro.options.graphql?.externalServices?.length) {
|
|
22
23
|
const validationErrors = validateExternalServices(nitro.options.graphql.externalServices);
|
|
23
24
|
if (validationErrors.length > 0) {
|
|
24
|
-
|
|
25
|
-
for (const error of validationErrors)
|
|
25
|
+
logger.error("External services configuration errors:");
|
|
26
|
+
for (const error of validationErrors) logger.error(` - ${error}`);
|
|
26
27
|
throw new Error("Invalid external services configuration");
|
|
27
28
|
}
|
|
28
|
-
|
|
29
|
+
logger.info(`Configured ${nitro.options.graphql.externalServices.length} external GraphQL services`);
|
|
29
30
|
}
|
|
30
31
|
const { getDefaultPaths } = await import("./utils/path-resolver.mjs");
|
|
31
32
|
const defaultPaths = getDefaultPaths(nitro);
|
|
@@ -59,7 +60,7 @@ async function setupNitroGraphQL(nitro) {
|
|
|
59
60
|
},
|
|
60
61
|
playground: true
|
|
61
62
|
});
|
|
62
|
-
if (nitro.options.graphql?.federation?.enabled)
|
|
63
|
+
if (nitro.options.graphql?.federation?.enabled) logger.info(`Apollo Federation enabled for service: ${nitro.options.graphql.federation.serviceName || "unnamed"}`);
|
|
63
64
|
const graphqlBuildDir = resolve(nitro.options.buildDir, "graphql");
|
|
64
65
|
nitro.graphql.buildDir = graphqlBuildDir;
|
|
65
66
|
const watchDirs = [];
|
|
@@ -95,11 +96,20 @@ async function setupNitroGraphQL(nitro) {
|
|
|
95
96
|
ignoreInitial: true,
|
|
96
97
|
ignored: [...nitro.options.ignore, ...generateLayerIgnorePatterns()]
|
|
97
98
|
}).on("all", async (_, path) => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
const isGraphQLFile = path.endsWith(".graphql") || path.endsWith(".gql");
|
|
100
|
+
const isResolverFile = path.endsWith(".resolver.ts") || path.endsWith(".resolver.js");
|
|
101
|
+
const isDirectiveFile = path.endsWith(".directive.ts") || path.endsWith(".directive.js");
|
|
102
|
+
if (isGraphQLFile || isResolverFile || isDirectiveFile) if (path.includes(nitro.graphql.serverDir) || path.includes("server/graphql") || path.includes("server\\graphql") || isResolverFile || isDirectiveFile) {
|
|
103
|
+
await scanResolvers(nitro).then((r) => nitro.scanResolvers = r);
|
|
104
|
+
await scanDirectives(nitro).then((d) => nitro.scanDirectives = d);
|
|
105
|
+
logger.success("Types regenerated");
|
|
106
|
+
await serverTypeGeneration(nitro, { silent: true });
|
|
107
|
+
await clientTypeGeneration(nitro, { silent: true });
|
|
101
108
|
await nitro.hooks.callHook("dev:reload");
|
|
102
|
-
} else
|
|
109
|
+
} else {
|
|
110
|
+
logger.success("Types regenerated");
|
|
111
|
+
await clientTypeGeneration(nitro, { silent: true });
|
|
112
|
+
}
|
|
103
113
|
});
|
|
104
114
|
nitro.hooks.hook("close", () => {
|
|
105
115
|
watcher.close();
|
|
@@ -111,33 +121,17 @@ async function setupNitroGraphQL(nitro) {
|
|
|
111
121
|
const directives = await scanDirectives(nitro);
|
|
112
122
|
nitro.scanDirectives = directives;
|
|
113
123
|
await generateDirectiveSchemas(nitro, directives);
|
|
124
|
+
let hasShownInitialLogs = false;
|
|
114
125
|
nitro.hooks.hook("dev:start", async () => {
|
|
115
|
-
|
|
116
|
-
nitro.scanSchemas = schemas;
|
|
126
|
+
nitro.scanSchemas = await scanSchemas(nitro);
|
|
117
127
|
const resolvers = await scanResolvers(nitro);
|
|
118
128
|
nitro.scanResolvers = resolvers;
|
|
119
129
|
const directives$1 = await scanDirectives(nitro);
|
|
120
130
|
nitro.scanDirectives = directives$1;
|
|
121
131
|
await generateDirectiveSchemas(nitro, directives$1);
|
|
122
|
-
|
|
123
|
-
nitro.
|
|
124
|
-
|
|
125
|
-
consola.box({
|
|
126
|
-
title: "Nitro GraphQL",
|
|
127
|
-
message: [
|
|
128
|
-
`Framework: ${nitro.options.graphql?.framework || "Not configured"}`,
|
|
129
|
-
`Schemas: ${schemas.length}`,
|
|
130
|
-
`Resolvers: ${resolvers.length}`,
|
|
131
|
-
`Directives: ${directives$1.length}`,
|
|
132
|
-
`Documents: ${docs.length}`,
|
|
133
|
-
"",
|
|
134
|
-
"Debug Dashboard: /_nitro/graphql/debug"
|
|
135
|
-
].join("\n"),
|
|
136
|
-
style: {
|
|
137
|
-
borderColor: "cyan",
|
|
138
|
-
borderStyle: "rounded"
|
|
139
|
-
}
|
|
140
|
-
});
|
|
132
|
+
nitro.scanDocuments = await scanDocs(nitro);
|
|
133
|
+
if (nitro.options.dev && !hasShownInitialLogs) {
|
|
134
|
+
hasShownInitialLogs = true;
|
|
141
135
|
if (resolvers.length > 0) {
|
|
142
136
|
const totalExports = resolvers.reduce((sum, r) => sum + r.imports.length, 0);
|
|
143
137
|
const typeCount = {
|
|
@@ -156,16 +150,16 @@ async function setupNitroGraphQL(nitro) {
|
|
|
156
150
|
if (typeCount.type > 0) breakdown.push(`${typeCount.type} type`);
|
|
157
151
|
if (typeCount.subscription > 0) breakdown.push(`${typeCount.subscription} subscription`);
|
|
158
152
|
if (typeCount.directive > 0) breakdown.push(`${typeCount.directive} directive`);
|
|
159
|
-
if (breakdown.length > 0)
|
|
160
|
-
} else
|
|
153
|
+
if (breakdown.length > 0) logger.success(`${totalExports} resolver export(s): ${breakdown.join(", ")}`);
|
|
154
|
+
} else logger.warn("No resolvers found. Check /_nitro/graphql/debug for details.");
|
|
161
155
|
}
|
|
162
156
|
});
|
|
163
157
|
await rollupConfig(nitro);
|
|
164
158
|
await serverTypeGeneration(nitro);
|
|
165
|
-
await clientTypeGeneration(nitro);
|
|
159
|
+
await clientTypeGeneration(nitro, { isInitial: true });
|
|
166
160
|
nitro.hooks.hook("close", async () => {
|
|
167
|
-
await serverTypeGeneration(nitro);
|
|
168
|
-
await clientTypeGeneration(nitro);
|
|
161
|
+
await serverTypeGeneration(nitro, { silent: true });
|
|
162
|
+
await clientTypeGeneration(nitro, { silent: true });
|
|
169
163
|
});
|
|
170
164
|
const runtime = fileURLToPath(new URL("routes", import.meta.url));
|
|
171
165
|
const methods = [
|
|
@@ -188,14 +182,11 @@ async function setupNitroGraphQL(nitro) {
|
|
|
188
182
|
handler: join(runtime, "health"),
|
|
189
183
|
method: "GET"
|
|
190
184
|
});
|
|
191
|
-
if (nitro.options.dev) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
});
|
|
197
|
-
consola.info("[nitro-graphql] Debug dashboard available at: /_nitro/graphql/debug");
|
|
198
|
-
}
|
|
185
|
+
if (nitro.options.dev) nitro.options.handlers.push({
|
|
186
|
+
route: "/_nitro/graphql/debug",
|
|
187
|
+
handler: join(runtime, "debug"),
|
|
188
|
+
method: "GET"
|
|
189
|
+
});
|
|
199
190
|
if (nitro.options.imports) {
|
|
200
191
|
nitro.options.imports.presets ??= [];
|
|
201
192
|
nitro.options.imports.presets.push({
|
|
@@ -380,10 +371,10 @@ declare module 'nitro/h3' {
|
|
|
380
371
|
export {}
|
|
381
372
|
`, "server context.d.ts");
|
|
382
373
|
if (existsSync(join(nitro.graphql.serverDir, "context.ts"))) {
|
|
383
|
-
|
|
384
|
-
|
|
374
|
+
logger.warn("Found context.ts file. Please rename it to context.d.ts for type-only definitions.");
|
|
375
|
+
logger.info("The context file should now be context.d.ts instead of context.ts");
|
|
385
376
|
}
|
|
386
|
-
} else
|
|
377
|
+
} else logger.info("Scaffold file generation is disabled (library mode)");
|
|
387
378
|
}
|
|
388
379
|
|
|
389
380
|
//#endregion
|
package/dist/types/define.d.mts
CHANGED
|
@@ -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 { };
|
package/dist/types/index.d.mts
CHANGED
|
@@ -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 { };
|
|
@@ -23,7 +23,10 @@ declare function loadExternalSchema(service: ExternalGraphQLService, buildDir?:
|
|
|
23
23
|
*/
|
|
24
24
|
declare function downloadAndSaveSchema(service: ExternalGraphQLService, buildDir: string): Promise<string | undefined>;
|
|
25
25
|
declare function loadGraphQLDocuments(patterns: string | string[]): Promise<Source[]>;
|
|
26
|
-
declare function generateClientTypes(schema: GraphQLSchema, docs: Source[], config?: CodegenClientConfig, sdkConfig?: GenericSdkConfig, outputPath?: string, serviceName?: string, virtualTypesPath?: string
|
|
26
|
+
declare function generateClientTypes(schema: GraphQLSchema, docs: Source[], config?: CodegenClientConfig, sdkConfig?: GenericSdkConfig, outputPath?: string, serviceName?: string, virtualTypesPath?: string, options?: {
|
|
27
|
+
silent?: boolean;
|
|
28
|
+
isInitial?: boolean;
|
|
29
|
+
}): Promise<false | {
|
|
27
30
|
types: string;
|
|
28
31
|
sdk: string;
|
|
29
32
|
}>;
|
|
@@ -165,9 +165,9 @@ async function loadGraphQLDocuments(patterns) {
|
|
|
165
165
|
else throw e;
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
-
async function generateClientTypes(schema, docs, config = {}, sdkConfig = {}, outputPath, serviceName, virtualTypesPath) {
|
|
168
|
+
async function generateClientTypes(schema, docs, config = {}, sdkConfig = {}, outputPath, serviceName, virtualTypesPath, options = {}) {
|
|
169
169
|
if (docs.length === 0 && !serviceName) {
|
|
170
|
-
consola$1.info("No client GraphQL files found. Skipping client type generation.");
|
|
170
|
+
if (!options.silent && options.isInitial) consola$1.info("No client GraphQL files found. Skipping client type generation.");
|
|
171
171
|
return false;
|
|
172
172
|
}
|
|
173
173
|
const serviceLabel = serviceName ? `:${serviceName}` : "";
|
|
@@ -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 };
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -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 };
|