nitro-graphql 1.7.0 → 1.8.0

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/dist/index.mjs CHANGED
@@ -31,7 +31,8 @@ function resolveSecurityConfig(config) {
31
31
  var src_default = defineNitroModule({
32
32
  name: "nitro-graphql",
33
33
  async setup(nitro) {
34
- if (!nitro.options.graphql?.framework) consola.warn("No GraphQL framework specified. Please set graphql.framework to \"graphql-yoga\" or \"apollo-server\".");
34
+ const serverEnabled = nitro.options.graphql?.server !== false;
35
+ if (serverEnabled && !nitro.options.graphql?.framework) consola.warn("No GraphQL framework specified. Please set graphql.framework to \"graphql-yoga\" or \"apollo-server\".");
35
36
  if (nitro.options.graphql?.externalServices?.length) {
36
37
  const validationErrors = validateExternalServices(nitro.options.graphql.externalServices);
37
38
  if (validationErrors.length > 0) {
@@ -117,123 +118,133 @@ var src_default = defineNitroModule({
117
118
  watcher.close();
118
119
  });
119
120
  const tsconfigDir = dirname(resolve(nitro.options.buildDir, nitro.options.typescript.tsconfigPath));
120
- nitro.scanSchemas = await scanSchemas(nitro);
121
+ if (serverEnabled) {
122
+ nitro.scanSchemas = await scanSchemas(nitro);
123
+ nitro.scanResolvers = await scanResolvers(nitro);
124
+ const directives = await scanDirectives(nitro);
125
+ nitro.scanDirectives = directives;
126
+ await generateDirectiveSchemas(nitro, directives);
127
+ } else {
128
+ nitro.scanSchemas = [];
129
+ nitro.scanResolvers = [];
130
+ nitro.scanDirectives = [];
131
+ }
121
132
  nitro.scanDocuments = await scanDocs(nitro);
122
- nitro.scanResolvers = await scanResolvers(nitro);
123
- const directives = await scanDirectives(nitro);
124
- nitro.scanDirectives = directives;
125
- await generateDirectiveSchemas(nitro, directives);
126
133
  nitro.hooks.hook("dev:start", async () => {
127
- const schemas = await scanSchemas(nitro);
128
- nitro.scanSchemas = schemas;
129
- const resolvers = await scanResolvers(nitro);
130
- nitro.scanResolvers = resolvers;
131
- const directives$1 = await scanDirectives(nitro);
132
- nitro.scanDirectives = directives$1;
133
- await generateDirectiveSchemas(nitro, directives$1);
134
+ let schemas = [];
135
+ let resolvers = [];
136
+ let directives = [];
137
+ if (serverEnabled) {
138
+ schemas = await scanSchemas(nitro);
139
+ nitro.scanSchemas = schemas;
140
+ resolvers = await scanResolvers(nitro);
141
+ nitro.scanResolvers = resolvers;
142
+ directives = await scanDirectives(nitro);
143
+ nitro.scanDirectives = directives;
144
+ await generateDirectiveSchemas(nitro, directives);
145
+ }
134
146
  const docs = await scanDocs(nitro);
135
147
  nitro.scanDocuments = docs;
136
148
  if (nitro.options.dev) {
137
149
  const runtimeSecurityConfig = nitro.options.runtimeConfig.graphql?.security;
138
150
  const isProd = process.env.NODE_ENV === "production";
139
- consola.box({
140
- title: "Nitro GraphQL",
141
- message: [
142
- `Framework: ${nitro.options.graphql?.framework || "Not configured"}`,
143
- `Environment: ${isProd ? "production" : "development"}`,
144
- `Schemas: ${schemas.length}`,
145
- `Resolvers: ${resolvers.length}`,
146
- `Directives: ${directives$1.length}`,
147
- `Documents: ${docs.length}`,
148
- "",
149
- "Security:",
150
- `├─ Introspection: ${runtimeSecurityConfig?.introspection ? "enabled" : "disabled"}`,
151
- `├─ Playground: ${runtimeSecurityConfig?.playground ? "enabled" : "disabled"}`,
152
- `├─ Error Masking: ${runtimeSecurityConfig?.maskErrors ? "enabled" : "disabled"}`,
153
- `└─ Field Suggestions: ${runtimeSecurityConfig?.disableSuggestions ? "disabled" : "enabled"}`,
154
- "",
155
- "Debug Dashboard: /_nitro/graphql/debug"
156
- ].join("\n"),
157
- style: {
158
- borderColor: isProd ? "yellow" : "cyan",
159
- borderStyle: "rounded"
160
- }
161
- });
162
- if (resolvers.length > 0) {
163
- const totalExports = resolvers.reduce((sum, r) => sum + r.imports.length, 0);
164
- const typeCount = {
165
- query: 0,
166
- mutation: 0,
167
- resolver: 0,
168
- type: 0,
169
- subscription: 0,
170
- directive: 0
171
- };
172
- for (const resolver of resolvers) for (const imp of resolver.imports) if (imp.type in typeCount) typeCount[imp.type]++;
173
- const breakdown = [];
174
- if (typeCount.query > 0) breakdown.push(`${typeCount.query} query`);
175
- if (typeCount.mutation > 0) breakdown.push(`${typeCount.mutation} mutation`);
176
- if (typeCount.resolver > 0) breakdown.push(`${typeCount.resolver} resolver`);
177
- if (typeCount.type > 0) breakdown.push(`${typeCount.type} type`);
178
- if (typeCount.subscription > 0) breakdown.push(`${typeCount.subscription} subscription`);
179
- if (typeCount.directive > 0) breakdown.push(`${typeCount.directive} directive`);
180
- if (breakdown.length > 0) consola.success(`[nitro-graphql] ${totalExports} resolver export(s): ${breakdown.join(", ")}`);
181
- } else consola.warn("[nitro-graphql] No resolvers found. Check /_nitro/graphql/debug for details.");
151
+ if (serverEnabled) {
152
+ consola.box({
153
+ title: "Nitro GraphQL",
154
+ message: [
155
+ `Framework: ${nitro.options.graphql?.framework || "Not configured"}`,
156
+ `Environment: ${isProd ? "production" : "development"}`,
157
+ `Schemas: ${schemas.length}`,
158
+ `Resolvers: ${resolvers.length}`,
159
+ `Directives: ${directives.length}`,
160
+ `Documents: ${docs.length}`,
161
+ "",
162
+ "Security:",
163
+ `├─ Introspection: ${runtimeSecurityConfig?.introspection ? "enabled" : "disabled"}`,
164
+ `├─ Playground: ${runtimeSecurityConfig?.playground ? "enabled" : "disabled"}`,
165
+ `├─ Error Masking: ${runtimeSecurityConfig?.maskErrors ? "enabled" : "disabled"}`,
166
+ `└─ Field Suggestions: ${runtimeSecurityConfig?.disableSuggestions ? "disabled" : "enabled"}`,
167
+ "",
168
+ "Debug Dashboard: /_nitro/graphql/debug"
169
+ ].join("\n"),
170
+ style: {
171
+ borderColor: isProd ? "yellow" : "cyan",
172
+ borderStyle: "rounded"
173
+ }
174
+ });
175
+ if (resolvers.length === 0) consola.warn("[nitro-graphql] No resolvers found. Check /_nitro/graphql/debug for details.");
176
+ } else {
177
+ const externalServicesCount = nitro.options.graphql?.externalServices?.length || 0;
178
+ consola.box({
179
+ title: "Nitro GraphQL (Client Only)",
180
+ message: [
181
+ "Server mode: disabled",
182
+ `External Services: ${externalServicesCount}`,
183
+ `Documents: ${docs.length}`
184
+ ].join("\n"),
185
+ style: {
186
+ borderColor: "blue",
187
+ borderStyle: "rounded"
188
+ }
189
+ });
190
+ }
182
191
  }
183
192
  });
184
- await rollupConfig(nitro);
185
- await serverTypeGeneration(nitro);
193
+ if (serverEnabled) await rollupConfig(nitro);
194
+ else nitro.hooks.hook("dev:reload", async () => {
195
+ await clientTypeGeneration(nitro);
196
+ });
197
+ if (serverEnabled) await serverTypeGeneration(nitro);
186
198
  await clientTypeGeneration(nitro);
187
199
  nitro.hooks.hook("close", async () => {
188
- await serverTypeGeneration(nitro);
200
+ if (serverEnabled) await serverTypeGeneration(nitro);
189
201
  await clientTypeGeneration(nitro);
190
202
  });
191
- const runtime = fileURLToPath(new URL("routes", import.meta.url));
192
- const methods = [
193
- "get",
194
- "post",
195
- "options"
196
- ];
197
- if (nitro.options.graphql?.framework === "graphql-yoga") for (const method of methods) nitro.options.handlers.push({
198
- route: nitro.options.runtimeConfig.graphql?.endpoint?.graphql || "/api/graphql",
199
- handler: join(runtime, "graphql-yoga"),
200
- method
201
- });
202
- if (nitro.options.graphql?.framework === "apollo-server") for (const method of methods) nitro.options.handlers.push({
203
- route: nitro.options.runtimeConfig.graphql?.endpoint?.graphql || "/api/graphql",
204
- handler: join(runtime, "apollo-server"),
205
- method
206
- });
207
- nitro.options.handlers.push({
208
- route: nitro.options.runtimeConfig.graphql?.endpoint?.healthCheck || "/api/graphql/health",
209
- handler: join(runtime, "health"),
210
- method: "get"
211
- });
212
- if (nitro.options.graphql?.subscriptions?.enabled) {
213
- nitro.options.experimental ||= {};
214
- nitro.options.experimental.websocket = true;
215
- const wsEndpoint = nitro.options.runtimeConfig.graphql?.endpoint?.ws || nitro.options.graphql?.subscriptions?.endpoint || "/api/graphql/ws";
216
- if (nitro.options.graphql?.framework === "graphql-yoga") nitro.options.handlers.push({
217
- route: wsEndpoint,
218
- handler: join(runtime, "graphql-yoga-ws")
203
+ if (serverEnabled) {
204
+ const runtime = fileURLToPath(new URL("routes", import.meta.url));
205
+ const methods = [
206
+ "get",
207
+ "post",
208
+ "options"
209
+ ];
210
+ if (nitro.options.graphql?.framework === "graphql-yoga") for (const method of methods) nitro.options.handlers.push({
211
+ route: nitro.options.runtimeConfig.graphql?.endpoint?.graphql || "/api/graphql",
212
+ handler: join(runtime, "graphql-yoga"),
213
+ method
219
214
  });
220
- if (nitro.options.graphql?.framework === "apollo-server") nitro.options.handlers.push({
221
- route: wsEndpoint,
222
- handler: join(runtime, "apollo-server-ws")
215
+ if (nitro.options.graphql?.framework === "apollo-server") for (const method of methods) nitro.options.handlers.push({
216
+ route: nitro.options.runtimeConfig.graphql?.endpoint?.graphql || "/api/graphql",
217
+ handler: join(runtime, "apollo-server"),
218
+ method
223
219
  });
224
- nitro.options.plugins ??= [];
225
- nitro.options.plugins.push(join(runtime, "ws-shutdown"));
226
- consola.info(`[nitro-graphql] WebSocket subscriptions enabled at: ${wsEndpoint}`);
227
- }
228
- if (nitro.options.dev) {
229
220
  nitro.options.handlers.push({
221
+ route: nitro.options.runtimeConfig.graphql?.endpoint?.healthCheck || "/api/graphql/health",
222
+ handler: join(runtime, "health"),
223
+ method: "get"
224
+ });
225
+ if (nitro.options.graphql?.subscriptions?.enabled) {
226
+ nitro.options.experimental ||= {};
227
+ nitro.options.experimental.websocket = true;
228
+ const wsEndpoint = nitro.options.runtimeConfig.graphql?.endpoint?.ws || nitro.options.graphql?.subscriptions?.endpoint || "/api/graphql/ws";
229
+ if (nitro.options.graphql?.framework === "graphql-yoga") nitro.options.handlers.push({
230
+ route: wsEndpoint,
231
+ handler: join(runtime, "graphql-yoga-ws")
232
+ });
233
+ if (nitro.options.graphql?.framework === "apollo-server") nitro.options.handlers.push({
234
+ route: wsEndpoint,
235
+ handler: join(runtime, "apollo-server-ws")
236
+ });
237
+ nitro.options.plugins ??= [];
238
+ nitro.options.plugins.push(join(runtime, "ws-shutdown"));
239
+ consola.info(`[nitro-graphql] WebSocket subscriptions enabled at: ${wsEndpoint}`);
240
+ }
241
+ if (nitro.options.dev) nitro.options.handlers.push({
230
242
  route: "/_nitro/graphql/debug",
231
243
  handler: join(runtime, "debug"),
232
244
  method: "get"
233
245
  });
234
- consola.info("[nitro-graphql] Debug dashboard available at: /_nitro/graphql/debug");
235
246
  }
236
- if (nitro.options.imports) {
247
+ if (serverEnabled && nitro.options.imports) {
237
248
  nitro.options.imports.presets ??= [];
238
249
  nitro.options.imports.presets.push({
239
250
  from: fileURLToPath(new URL("utils/define", import.meta.url)),
@@ -250,7 +261,7 @@ var src_default = defineNitroModule({
250
261
  ]
251
262
  });
252
263
  }
253
- nitro.hooks.hook("rollup:before", (_, rollupConfig$1) => {
264
+ if (serverEnabled) nitro.hooks.hook("rollup:before", (_, rollupConfig$1) => {
254
265
  const manualChunks = rollupConfig$1.output?.manualChunks;
255
266
  const chunkFiles = rollupConfig$1.output?.chunkFileNames;
256
267
  if (!rollupConfig$1.output.inlineDynamicImports) rollupConfig$1.output.manualChunks = (id, meta) => {
@@ -271,11 +282,14 @@ var src_default = defineNitroModule({
271
282
  types.tsConfig.compilerOptions.paths ??= {};
272
283
  const placeholders = getDefaultPaths(nitro);
273
284
  const typesConfig = getTypesConfig(nitro);
274
- const serverTypesPath = resolveFilePath(typesConfig.server, typesConfig.enabled, true, "{typesDir}/nitro-graphql-server.d.ts", placeholders);
275
- if (serverTypesPath) types.tsConfig.compilerOptions.paths["#graphql/server"] = [relativeWithDot(tsconfigDir, serverTypesPath)];
285
+ let serverTypesPath = null;
286
+ if (serverEnabled) {
287
+ serverTypesPath = resolveFilePath(typesConfig.server, typesConfig.enabled, true, "{typesDir}/nitro-graphql-server.d.ts", placeholders);
288
+ if (serverTypesPath) types.tsConfig.compilerOptions.paths["#graphql/server"] = [relativeWithDot(tsconfigDir, serverTypesPath)];
289
+ types.tsConfig.compilerOptions.paths["#graphql/schema"] = [relativeWithDot(tsconfigDir, join(nitro.graphql.serverDir, "schema.ts"))];
290
+ }
276
291
  const clientTypesPath = resolveFilePath(typesConfig.client, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client.d.ts", placeholders);
277
292
  if (clientTypesPath) types.tsConfig.compilerOptions.paths["#graphql/client"] = [relativeWithDot(tsconfigDir, clientTypesPath)];
278
- types.tsConfig.compilerOptions.paths["#graphql/schema"] = [relativeWithDot(tsconfigDir, join(nitro.graphql.serverDir, "schema.ts"))];
279
293
  if (nitro.options.graphql?.externalServices?.length) for (const service of nitro.options.graphql.externalServices) {
280
294
  const servicePlaceholders = {
281
295
  ...placeholders,
@@ -304,8 +318,9 @@ var src_default = defineNitroModule({
304
318
  if (shouldGenerateScaffold(nitro)) {
305
319
  const placeholders = getDefaultPaths(nitro);
306
320
  const scaffoldConfig = getScaffoldConfig(nitro);
307
- const graphqlConfigPath = resolveFilePath(scaffoldConfig.graphqlConfig, scaffoldConfig.enabled, true, "graphql.config.ts", placeholders);
308
- if (graphqlConfigPath) writeFileIfNotExists(graphqlConfigPath, `
321
+ if (serverEnabled) {
322
+ const graphqlConfigPath = resolveFilePath(scaffoldConfig.graphqlConfig, scaffoldConfig.enabled, true, "graphql.config.ts", placeholders);
323
+ if (graphqlConfigPath) writeFileIfNotExists(graphqlConfigPath, `
309
324
  import type { IGraphQLConfig } from 'graphql-config'
310
325
 
311
326
  export default <IGraphQLConfig> {
@@ -320,17 +335,17 @@ export default <IGraphQLConfig> {
320
335
  },
321
336
  },
322
337
  }`, "graphql.config.ts");
323
- const serverSchemaPath = resolveFilePath(scaffoldConfig.serverSchema, scaffoldConfig.enabled, true, "{serverGraphql}/schema.ts", placeholders);
324
- const serverConfigPath = resolveFilePath(scaffoldConfig.serverConfig, scaffoldConfig.enabled, true, "{serverGraphql}/config.ts", placeholders);
325
- const serverContextPath = resolveFilePath(scaffoldConfig.serverContext, scaffoldConfig.enabled, true, "{serverGraphql}/context.ts", placeholders);
326
- if (serverSchemaPath || serverConfigPath || serverContextPath) {
327
- if (!existsSync(nitro.graphql.serverDir)) mkdirSync(nitro.graphql.serverDir, { recursive: true });
328
- }
329
- if (serverSchemaPath) writeFileIfNotExists(serverSchemaPath, `export default defineSchema({
338
+ const serverSchemaPath = resolveFilePath(scaffoldConfig.serverSchema, scaffoldConfig.enabled, true, "{serverGraphql}/schema.ts", placeholders);
339
+ const serverConfigPath = resolveFilePath(scaffoldConfig.serverConfig, scaffoldConfig.enabled, true, "{serverGraphql}/config.ts", placeholders);
340
+ const serverContextPath = resolveFilePath(scaffoldConfig.serverContext, scaffoldConfig.enabled, true, "{serverGraphql}/context.ts", placeholders);
341
+ if (serverSchemaPath || serverConfigPath || serverContextPath) {
342
+ if (!existsSync(nitro.graphql.serverDir)) mkdirSync(nitro.graphql.serverDir, { recursive: true });
343
+ }
344
+ if (serverSchemaPath) writeFileIfNotExists(serverSchemaPath, `export default defineSchema({
330
345
 
331
346
  })
332
347
  `, "server schema.ts");
333
- if (serverConfigPath) writeFileIfNotExists(serverConfigPath, `// Example GraphQL config file please change it to your needs
348
+ if (serverConfigPath) writeFileIfNotExists(serverConfigPath, `// Example GraphQL config file please change it to your needs
334
349
  // import * as tables from '../drizzle/schema/index'
335
350
  // import { useDatabase } from '../utils/useDb'
336
351
 
@@ -346,7 +361,7 @@ export default defineGraphQLConfig({
346
361
  // },
347
362
  })
348
363
  `, "server config.ts");
349
- if (serverContextPath) writeFileIfNotExists(serverContextPath, `// Example context definition - please change it to your needs
364
+ if (serverContextPath) writeFileIfNotExists(serverContextPath, `// Example context definition - please change it to your needs
350
365
  // import type { Database } from '../utils/useDb'
351
366
 
352
367
  declare module 'h3' {
@@ -362,15 +377,16 @@ declare module 'h3' {
362
377
  // }
363
378
  }
364
379
  }`, "server context.ts");
365
- if (existsSync(join(nitro.graphql.serverDir, "context.d.ts"))) {
366
- consola.warn("nitro-graphql: Found context.d.ts file. Please rename it to context.ts for the new structure.");
367
- consola.info("The context file should now be context.ts instead of context.d.ts");
368
- }
369
- if (nitro.options.graphql?.subscriptions?.enabled) {
370
- if (!existsSync(nitro.graphql.clientDir)) mkdirSync(nitro.graphql.clientDir, { recursive: true });
371
- const defaultDir = resolve(nitro.graphql.clientDir, "default");
372
- if (!existsSync(defaultDir)) mkdirSync(defaultDir, { recursive: true });
373
- writeFileIfNotExists(resolve(defaultDir, "subscribe.ts"), subscribeClientTemplate, "subscribe.ts");
380
+ if (existsSync(join(nitro.graphql.serverDir, "context.d.ts"))) {
381
+ consola.warn("nitro-graphql: Found context.d.ts file. Please rename it to context.ts for the new structure.");
382
+ consola.info("The context file should now be context.ts instead of context.d.ts");
383
+ }
384
+ if (nitro.options.graphql?.subscriptions?.enabled) {
385
+ if (!existsSync(nitro.graphql.clientDir)) mkdirSync(nitro.graphql.clientDir, { recursive: true });
386
+ const defaultDir = resolve(nitro.graphql.clientDir, "default");
387
+ if (!existsSync(defaultDir)) mkdirSync(defaultDir, { recursive: true });
388
+ writeFileIfNotExists(resolve(defaultDir, "subscribe.ts"), subscribeClientTemplate, "subscribe.ts");
389
+ }
374
390
  }
375
391
  } else consola.info("[nitro-graphql] Scaffold file generation is disabled (library mode)");
376
392
  }
package/dist/rollup.mjs CHANGED
@@ -62,15 +62,13 @@ function virtualSchemas(app) {
62
62
  }
63
63
  const importStatements = imports.map((handler) => `import ${getImportId(handler)} from '${handler}';`);
64
64
  const schemaArray = imports.map((h) => `{ def: ${getImportId(h)} }`);
65
- const code = `
65
+ return `
66
66
  ${importStatements.join("\n")}
67
67
 
68
68
  export const schemas = [
69
69
  ${schemaArray.join(",\n")}
70
70
  ];
71
71
  `;
72
- if (app.options.dev) app.logger.success(`[nitro-graphql] Generated virtual schema module: ${imports.length} schema(s)`);
73
- return code;
74
72
  } catch (error) {
75
73
  app.logger.error("[nitro-graphql] Failed to generate virtual schema module:", error);
76
74
  return "export const schemas = []";
@@ -108,7 +106,7 @@ function virtualResolvers(app) {
108
106
  for (const msg of invalidImports) app.logger.warn(` - ${msg}`);
109
107
  }
110
108
  const data = imports.map(({ imports: importList }) => importList.map((i) => `{ resolver: ${i.as} }`).join(",\n")).filter(Boolean).join(",\n");
111
- const code = [
109
+ return [
112
110
  ...importsContent,
113
111
  "",
114
112
  "export const resolvers = [",
@@ -116,11 +114,6 @@ function virtualResolvers(app) {
116
114
  "]",
117
115
  ""
118
116
  ].join("\n");
119
- if (app.options.dev) {
120
- const totalExports = imports.reduce((sum, r) => sum + r.imports.length, 0);
121
- app.logger.success(`[nitro-graphql] Generated virtual resolver module: ${totalExports} export(s) from ${imports.length} file(s)`);
122
- }
123
- return code;
124
117
  } catch (error) {
125
118
  app.logger.error("[nitro-graphql] Failed to generate virtual resolver module:", error);
126
119
  return "export const resolvers = []";
@@ -155,7 +148,7 @@ function virtualDirectives(app) {
155
148
  for (const msg of invalidImports) app.logger.warn(` - ${msg}`);
156
149
  }
157
150
  const data = imports.map(({ imports: importList }) => importList.map((i) => `{ directive: ${i.as} }`).join(",\n")).filter(Boolean).join(",\n");
158
- const code = [
151
+ return [
159
152
  ...importsContent,
160
153
  "",
161
154
  "export const directives = [",
@@ -163,11 +156,6 @@ function virtualDirectives(app) {
163
156
  "]",
164
157
  ""
165
158
  ].join("\n");
166
- if (app.options.dev) {
167
- const totalExports = imports.reduce((sum, d) => sum + d.imports.length, 0);
168
- app.logger.success(`[nitro-graphql] Generated virtual directive module: ${totalExports} directive(s) from ${imports.length} file(s)`);
169
- }
170
- return code;
171
159
  } catch (error) {
172
160
  app.logger.error("[nitro-graphql] Failed to generate virtual directive module:", error);
173
161
  return "export const directives = []";
@@ -1,4 +1,4 @@
1
- import * as h39 from "h3";
1
+ import * as h33 from "h3";
2
2
 
3
3
  //#region src/routes/apollo-server-ws.d.ts
4
4
 
@@ -7,6 +7,6 @@ import * as h39 from "h3";
7
7
  * Called by the Nitro runtime plugin on server close.
8
8
  */
9
9
  declare function shutdownAllConnections(): Promise<void>;
10
- declare const _default: h39.EventHandler<h39.EventHandlerRequest, never>;
10
+ declare const _default: h33.EventHandler<h33.EventHandlerRequest, never>;
11
11
  //#endregion
12
12
  export { _default as default, shutdownAllConnections };
@@ -1,4 +1,4 @@
1
- import * as h31 from "h3";
1
+ import * as h37 from "h3";
2
2
 
3
3
  //#region src/routes/graphql-yoga-ws.d.ts
4
4
 
@@ -7,6 +7,6 @@ import * as h31 from "h3";
7
7
  * Called by the Nitro runtime plugin on server close.
8
8
  */
9
9
  declare function shutdownAllConnections(): Promise<void>;
10
- declare const _default: h31.EventHandler<h31.EventHandlerRequest, never>;
10
+ declare const _default: h37.EventHandler<h37.EventHandlerRequest, never>;
11
11
  //#endregion
12
12
  export { _default as default, shutdownAllConnections };
@@ -1,6 +1,6 @@
1
- import * as h33 from "h3";
1
+ import * as h39 from "h3";
2
2
 
3
3
  //#region src/routes/graphql-yoga.d.ts
4
- declare const _default: h33.EventHandler<h33.EventHandlerRequest, Promise<Response>>;
4
+ declare const _default: h39.EventHandler<h39.EventHandlerRequest, Promise<Response>>;
5
5
  //#endregion
6
6
  export { _default as default };
@@ -1,7 +1,7 @@
1
- import * as h37 from "h3";
1
+ import * as h31 from "h3";
2
2
 
3
3
  //#region src/routes/health.d.ts
4
- declare const _default: h37.EventHandler<h37.EventHandlerRequest, Promise<{
4
+ declare const _default: h31.EventHandler<h31.EventHandlerRequest, Promise<{
5
5
  status: string;
6
6
  message: string;
7
7
  timestamp: string;
@@ -79,10 +79,13 @@ interface ExternalServicePaths {
79
79
  interface ExternalGraphQLService {
80
80
  /** Unique name for this service (used for file naming and type generation) */
81
81
  name: string;
82
- /** Schema source - can be URL(s) for remote schemas or file path(s) for local schemas */
83
- schema: string | string[];
84
- /** GraphQL endpoint for this service */
82
+ /** GraphQL endpoint for this service (also used as schema source if `schema` is not specified) */
85
83
  endpoint: string;
84
+ /**
85
+ * Schema source - can be URL(s) for remote schemas or file path(s) for local schemas
86
+ * @default Uses `endpoint` for introspection if not specified
87
+ */
88
+ schema?: string | string[];
86
89
  /** Optional headers for schema introspection and client requests */
87
90
  headers?: Record<string, string> | (() => Record<string, string>);
88
91
  /** Optional: specific document patterns for this service */
@@ -235,6 +238,13 @@ interface SecurityConfig {
235
238
  }
236
239
  interface NitroGraphQLOptions {
237
240
  framework: 'graphql-yoga' | 'apollo-server';
241
+ /**
242
+ * Enable/disable GraphQL server functionality
243
+ * When set to false, only external services client types will be generated
244
+ * Server routes, resolvers, schemas, and directives will not be processed
245
+ * @default true
246
+ */
247
+ server?: boolean;
238
248
  endpoint?: {
239
249
  graphql?: string;
240
250
  healthCheck?: string;
@@ -53,7 +53,8 @@ async function graphQLLoadSchemaSync(schemaPointers, data = {}) {
53
53
  async function loadExternalSchema(service, buildDir) {
54
54
  try {
55
55
  const headers = typeof service.headers === "function" ? service.headers() : service.headers || {};
56
- const schemas = Array.isArray(service.schema) ? service.schema : [service.schema];
56
+ const schemaSource = service.schema ?? service.endpoint;
57
+ const schemas = Array.isArray(schemaSource) ? schemaSource : [schemaSource];
57
58
  if (service.downloadSchema && buildDir) {
58
59
  const defaultPath = resolve(buildDir, "graphql", "schemas", `${service.name}.graphql`);
59
60
  const schemaFilePath = service.downloadPath ? resolve(service.downloadPath) : defaultPath;
@@ -88,14 +89,15 @@ function isUrl(path) {
88
89
  * Download and save schema from external service
89
90
  */
90
91
  async function downloadAndSaveSchema(service, buildDir) {
91
- const downloadMode = service.downloadSchema;
92
+ const schemaSource = service.schema ?? service.endpoint;
93
+ const schemas = Array.isArray(schemaSource) ? schemaSource : [schemaSource];
94
+ const hasUrlSchemas = schemas.some((schema) => isUrl(schema));
95
+ const downloadMode = service.downloadSchema ?? (hasUrlSchemas ? true : false);
92
96
  if (!downloadMode || downloadMode === "manual") return;
93
97
  const defaultPath = resolve(buildDir, "graphql", "schemas", `${service.name}.graphql`);
94
98
  const schemaFilePath = service.downloadPath ? resolve(service.downloadPath) : defaultPath;
95
99
  try {
96
100
  const headers = typeof service.headers === "function" ? service.headers() : service.headers || {};
97
- const schemas = Array.isArray(service.schema) ? service.schema : [service.schema];
98
- const hasUrlSchemas = schemas.some((schema) => isUrl(schema));
99
101
  const hasLocalSchemas = schemas.some((schema) => !isUrl(schema));
100
102
  let shouldDownload = false;
101
103
  const fileExists = existsSync(schemaFilePath);
@@ -216,7 +216,6 @@ function validateExternalServices(services) {
216
216
  if (!("name" in service) || typeof service.name !== "string") errors.push(`${prefix}.name is required and must be a string`);
217
217
  else if (serviceNames.has(service.name)) errors.push(`${prefix}.name "${service.name}" must be unique`);
218
218
  else serviceNames.add(service.name);
219
- if (!("schema" in service) || !service.schema) errors.push(`${prefix}.schema is required`);
220
219
  if (!("endpoint" in service) || typeof service.endpoint !== "string") errors.push(`${prefix}.endpoint is required and must be a string`);
221
220
  else try {
222
221
  new URL(service.endpoint);
@@ -232,7 +232,6 @@ async function serverTypeGeneration(app) {
232
232
  if (serverTypesPath) {
233
233
  mkdirSync(dirname(serverTypesPath), { recursive: true });
234
234
  writeFileSync(serverTypesPath, data, "utf-8");
235
- consola.success(`[nitro-graphql] Generated server types at: ${serverTypesPath}`);
236
235
  }
237
236
  } catch (error) {
238
237
  consola.error("Server schema generation error:", error);
@@ -293,13 +292,11 @@ async function generateMainClientTypes(nitro) {
293
292
  if (clientTypesPath) {
294
293
  mkdirSync(dirname(clientTypesPath), { recursive: true });
295
294
  writeFileSync(clientTypesPath, types.types, "utf-8");
296
- consola.success(`[nitro-graphql] Generated client types at: ${clientTypesPath}`);
297
295
  }
298
296
  const sdkPath = resolveFilePath(sdkConfig.main, sdkConfig.enabled, true, "{clientGraphql}/default/sdk.ts", placeholders);
299
297
  if (sdkPath) {
300
298
  mkdirSync(dirname(sdkPath), { recursive: true });
301
299
  writeFileSync(sdkPath, types.sdk, "utf-8");
302
- consola.success(`[nitro-graphql] Generated SDK at: ${sdkPath}`);
303
300
  }
304
301
  if (nitro.options.framework?.name === "nuxt") {
305
302
  generateNuxtOfetchClient(nitro, nitro.graphql.clientDir, "default");
@@ -310,7 +307,6 @@ async function generateMainClientTypes(nitro) {
310
307
  async function generateExternalServicesTypes(nitro) {
311
308
  const externalServices = nitro.options.graphql?.externalServices || [];
312
309
  for (const service of externalServices) try {
313
- consola.info(`[graphql:${service.name}] Processing external service`);
314
310
  await downloadAndSaveSchema(service, nitro.options.buildDir);
315
311
  const schema = await loadExternalSchema(service, nitro.options.buildDir);
316
312
  if (!schema) {
@@ -344,16 +340,13 @@ async function generateExternalServicesTypes(nitro) {
344
340
  if (serviceTypesPath) {
345
341
  mkdirSync(dirname(serviceTypesPath), { recursive: true });
346
342
  writeFileSync(serviceTypesPath, types.types, "utf-8");
347
- consola.success(`[graphql:${service.name}] Generated types at: ${serviceTypesPath}`);
348
343
  }
349
344
  const serviceSdkPath = resolveFilePath(service.paths?.sdk ?? sdkConfig.external, sdkConfig.enabled, true, "{clientGraphql}/{serviceName}/sdk.ts", placeholders);
350
345
  if (serviceSdkPath) {
351
346
  mkdirSync(dirname(serviceSdkPath), { recursive: true });
352
347
  writeFileSync(serviceSdkPath, types.sdk, "utf-8");
353
- consola.success(`[graphql:${service.name}] Generated SDK at: ${serviceSdkPath}`);
354
348
  }
355
349
  if (nitro.options.framework?.name === "nuxt") generateExternalOfetchClient(nitro, service, service.endpoint);
356
- consola.success(`[graphql:${service.name}] External service types generated successfully`);
357
350
  } catch (error) {
358
351
  consola.error(`[graphql:${service.name}] External service generation failed:`, error);
359
352
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nitro-graphql",
3
3
  "type": "module",
4
- "version": "1.7.0",
4
+ "version": "1.8.0",
5
5
  "description": "GraphQL integration for Nitro",
6
6
  "license": "MIT",
7
7
  "repository": {