nitro-graphql 2.0.0-beta.25 → 2.0.0-beta.27

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/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 h33 from "h3";
1
+ import * as h30 from "h3";
2
2
 
3
3
  //#region src/routes/apollo-server.d.ts
4
- declare const _default: h33.EventHandlerWithFetch<h33.EventHandlerRequest, Promise<any>>;
4
+ declare const _default: h30.EventHandlerWithFetch<h30.EventHandlerRequest, Promise<any>>;
5
5
  //#endregion
6
6
  export { _default as default };
@@ -1,4 +1,4 @@
1
- import * as h35 from "h3";
1
+ import * as h33 from "h3";
2
2
 
3
3
  //#region src/routes/debug.d.ts
4
4
 
@@ -10,7 +10,7 @@ import * as h35 from "h3";
10
10
  * - /_nitro/graphql/debug - HTML dashboard
11
11
  * - /_nitro/graphql/debug?format=json - JSON API
12
12
  */
13
- declare const _default: h35.EventHandlerWithFetch<h35.EventHandlerRequest, Promise<string | {
13
+ declare const _default: h33.EventHandlerWithFetch<h33.EventHandlerRequest, Promise<string | {
14
14
  timestamp: string;
15
15
  environment: {
16
16
  dev: any;
@@ -1,6 +1,6 @@
1
- import * as h30 from "h3";
1
+ import * as h35 from "h3";
2
2
 
3
3
  //#region src/routes/graphql-yoga.d.ts
4
- declare const _default: h30.EventHandlerWithFetch<h30.EventHandlerRequest, Promise<Response>>;
4
+ declare const _default: h35.EventHandlerWithFetch<h35.EventHandlerRequest, Promise<Response>>;
5
5
  //#endregion
6
6
  export { _default as default };
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) consola.warn("No GraphQL framework specified. Please set graphql.framework to \"graphql-yoga\" or \"apollo-server\".");
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
- consola.error("External services configuration errors:");
25
- for (const error of validationErrors) consola.error(` - ${error}`);
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
- consola.info(`Configured ${nitro.options.graphql.externalServices.length} external GraphQL services`);
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);
@@ -42,12 +43,17 @@ async function setupNitroGraphQL(nitro) {
42
43
  };
43
44
  nitro.hooks.hook("rollup:before", (_, rollupConfig$1) => {
44
45
  rollupConfig$1.external = rollupConfig$1.external || [];
45
- const codegenExternals = ["oxc-parser", "@oxc-parser"];
46
- if (Array.isArray(rollupConfig$1.external)) rollupConfig$1.external.push(...codegenExternals);
46
+ const allExternals = [...["oxc-parser", "@oxc-parser"]];
47
+ if (!nitro.options.graphql?.federation?.enabled) allExternals.push(...[
48
+ "@apollo/subgraph",
49
+ "@apollo/federation-internals",
50
+ "@apollo/cache-control-types"
51
+ ]);
52
+ if (Array.isArray(rollupConfig$1.external)) rollupConfig$1.external.push(...allExternals);
47
53
  else if (typeof rollupConfig$1.external === "function") {
48
54
  const originalExternal = rollupConfig$1.external;
49
55
  rollupConfig$1.external = (id, parent, isResolved) => {
50
- if (codegenExternals.some((external) => id.includes(external))) return true;
56
+ if (allExternals.some((external) => id.includes(external))) return true;
51
57
  return originalExternal(id, parent, isResolved);
52
58
  };
53
59
  }
@@ -59,7 +65,7 @@ async function setupNitroGraphQL(nitro) {
59
65
  },
60
66
  playground: true
61
67
  });
62
- if (nitro.options.graphql?.federation?.enabled) consola.info(`Apollo Federation enabled for service: ${nitro.options.graphql.federation.serviceName || "unnamed"}`);
68
+ if (nitro.options.graphql?.federation?.enabled) logger.info(`Apollo Federation enabled for service: ${nitro.options.graphql.federation.serviceName || "unnamed"}`);
63
69
  const graphqlBuildDir = resolve(nitro.options.buildDir, "graphql");
64
70
  nitro.graphql.buildDir = graphqlBuildDir;
65
71
  const watchDirs = [];
@@ -95,11 +101,20 @@ async function setupNitroGraphQL(nitro) {
95
101
  ignoreInitial: true,
96
102
  ignored: [...nitro.options.ignore, ...generateLayerIgnorePatterns()]
97
103
  }).on("all", async (_, path) => {
98
- if (path.endsWith(".graphql") || path.endsWith(".gql")) if (path.includes(nitro.graphql.serverDir) || path.includes("server/graphql") || path.includes("server\\graphql")) {
99
- await serverTypeGeneration(nitro);
100
- await clientTypeGeneration(nitro);
104
+ const isGraphQLFile = path.endsWith(".graphql") || path.endsWith(".gql");
105
+ const isResolverFile = path.endsWith(".resolver.ts") || path.endsWith(".resolver.js");
106
+ const isDirectiveFile = path.endsWith(".directive.ts") || path.endsWith(".directive.js");
107
+ if (isGraphQLFile || isResolverFile || isDirectiveFile) if (path.includes(nitro.graphql.serverDir) || path.includes("server/graphql") || path.includes("server\\graphql") || isResolverFile || isDirectiveFile) {
108
+ await scanResolvers(nitro).then((r) => nitro.scanResolvers = r);
109
+ await scanDirectives(nitro).then((d) => nitro.scanDirectives = d);
110
+ logger.success("Types regenerated");
111
+ await serverTypeGeneration(nitro, { silent: true });
112
+ await clientTypeGeneration(nitro, { silent: true });
101
113
  await nitro.hooks.callHook("dev:reload");
102
- } else await clientTypeGeneration(nitro);
114
+ } else {
115
+ logger.success("Types regenerated");
116
+ await clientTypeGeneration(nitro, { silent: true });
117
+ }
103
118
  });
104
119
  nitro.hooks.hook("close", () => {
105
120
  watcher.close();
@@ -111,33 +126,17 @@ async function setupNitroGraphQL(nitro) {
111
126
  const directives = await scanDirectives(nitro);
112
127
  nitro.scanDirectives = directives;
113
128
  await generateDirectiveSchemas(nitro, directives);
129
+ let hasShownInitialLogs = false;
114
130
  nitro.hooks.hook("dev:start", async () => {
115
- const schemas = await scanSchemas(nitro);
116
- nitro.scanSchemas = schemas;
131
+ nitro.scanSchemas = await scanSchemas(nitro);
117
132
  const resolvers = await scanResolvers(nitro);
118
133
  nitro.scanResolvers = resolvers;
119
134
  const directives$1 = await scanDirectives(nitro);
120
135
  nitro.scanDirectives = directives$1;
121
136
  await generateDirectiveSchemas(nitro, directives$1);
122
- const docs = await scanDocs(nitro);
123
- nitro.scanDocuments = docs;
124
- if (nitro.options.dev) {
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
- });
137
+ nitro.scanDocuments = await scanDocs(nitro);
138
+ if (nitro.options.dev && !hasShownInitialLogs) {
139
+ hasShownInitialLogs = true;
141
140
  if (resolvers.length > 0) {
142
141
  const totalExports = resolvers.reduce((sum, r) => sum + r.imports.length, 0);
143
142
  const typeCount = {
@@ -156,16 +155,16 @@ async function setupNitroGraphQL(nitro) {
156
155
  if (typeCount.type > 0) breakdown.push(`${typeCount.type} type`);
157
156
  if (typeCount.subscription > 0) breakdown.push(`${typeCount.subscription} subscription`);
158
157
  if (typeCount.directive > 0) breakdown.push(`${typeCount.directive} directive`);
159
- if (breakdown.length > 0) consola.success(`[nitro-graphql] ${totalExports} resolver export(s): ${breakdown.join(", ")}`);
160
- } else consola.warn("[nitro-graphql] No resolvers found. Check /_nitro/graphql/debug for details.");
158
+ if (breakdown.length > 0) logger.success(`${totalExports} resolver export(s): ${breakdown.join(", ")}`);
159
+ } else logger.warn("No resolvers found. Check /_nitro/graphql/debug for details.");
161
160
  }
162
161
  });
163
162
  await rollupConfig(nitro);
164
163
  await serverTypeGeneration(nitro);
165
- await clientTypeGeneration(nitro);
164
+ await clientTypeGeneration(nitro, { isInitial: true });
166
165
  nitro.hooks.hook("close", async () => {
167
- await serverTypeGeneration(nitro);
168
- await clientTypeGeneration(nitro);
166
+ await serverTypeGeneration(nitro, { silent: true });
167
+ await clientTypeGeneration(nitro, { silent: true });
169
168
  });
170
169
  const runtime = fileURLToPath(new URL("routes", import.meta.url));
171
170
  const methods = [
@@ -188,14 +187,11 @@ async function setupNitroGraphQL(nitro) {
188
187
  handler: join(runtime, "health"),
189
188
  method: "GET"
190
189
  });
191
- if (nitro.options.dev) {
192
- nitro.options.handlers.push({
193
- route: "/_nitro/graphql/debug",
194
- handler: join(runtime, "debug"),
195
- method: "GET"
196
- });
197
- consola.info("[nitro-graphql] Debug dashboard available at: /_nitro/graphql/debug");
198
- }
190
+ if (nitro.options.dev) nitro.options.handlers.push({
191
+ route: "/_nitro/graphql/debug",
192
+ handler: join(runtime, "debug"),
193
+ method: "GET"
194
+ });
199
195
  if (nitro.options.imports) {
200
196
  nitro.options.imports.presets ??= [];
201
197
  nitro.options.imports.presets.push({
@@ -380,10 +376,10 @@ declare module 'nitro/h3' {
380
376
  export {}
381
377
  `, "server context.d.ts");
382
378
  if (existsSync(join(nitro.graphql.serverDir, "context.ts"))) {
383
- consola.warn("nitro-graphql: Found context.ts file. Please rename it to context.d.ts for type-only definitions.");
384
- consola.info("The context file should now be context.d.ts instead of context.ts");
379
+ logger.warn("Found context.ts file. Please rename it to context.d.ts for type-only definitions.");
380
+ logger.info("The context file should now be context.d.ts instead of context.ts");
385
381
  }
386
- } else consola.info("[nitro-graphql] Scaffold file generation is disabled (library mode)");
382
+ } else logger.info("Scaffold file generation is disabled (library mode)");
387
383
  }
388
384
 
389
385
  //#endregion
@@ -1,9 +1,9 @@
1
1
  import { ApolloServer, BaseContext, ContextFunction } from "@apollo/server";
2
2
  import { EventHandler, H3Event } from "h3";
3
- import { WithRequired } from "@apollo/utils.withrequired";
4
3
  import { Hooks } from "crossws";
5
4
 
6
5
  //#region src/utils/apollo.d.ts
6
+ type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
7
7
  interface H3ContextFunctionArgument {
8
8
  event: H3Event;
9
9
  }
@@ -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): Promise<false | {
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}` : "";
@@ -1,7 +1,7 @@
1
1
  import { directiveParser, generateDirectiveSchema, generateDirectiveSchemas } from "./directive-parser.mjs";
2
2
  import { createDefaultMaskError } from "./errors.mjs";
3
3
  import { readFile } from "node:fs/promises";
4
- import { join, relative } from "pathe";
4
+ import { basename, join, relative } from "pathe";
5
5
  import { hash } from "ohash";
6
6
  import { parseAsync } from "oxc-parser";
7
7
  import { glob } from "tinyglobby";
@@ -77,6 +77,17 @@ async function scanResolvers(nitro) {
77
77
  for (const file of files) try {
78
78
  const fileContent = await readFile(file.fullPath, "utf-8");
79
79
  const parsed = await parseAsync(file.fullPath, fileContent);
80
+ if (parsed.errors && parsed.errors.length > 0) {
81
+ if (nitro.options.dev) {
82
+ const fileName = basename(file.fullPath);
83
+ const firstError = parsed.errors[0];
84
+ const location = firstError.labels?.[0];
85
+ const lineInfo = location ? `:${location.start}` : "";
86
+ const message = firstError.message.split(",")[0];
87
+ console.error(`✖ ${fileName}${lineInfo} - ${message}`);
88
+ }
89
+ continue;
90
+ }
80
91
  const exports = {
81
92
  imports: [],
82
93
  specifier: file.fullPath
@@ -126,7 +137,6 @@ async function scanResolvers(nitro) {
126
137
  }
127
138
  }
128
139
  if (nitro.options.dev) {
129
- const relPath = relative(nitro.options.rootDir, file.fullPath);
130
140
  if (hasDefaultExport && !hasNamedExport) nitro.logger.warn(`[nitro-graphql] ${relPath}: Using default export instead of named export. Resolvers must use named exports like "export const myResolver = defineQuery(...)". Default exports are not detected.`);
131
141
  if (exports.imports.length === 0 && hasNamedExport) {
132
142
  const validFunctions = VALID_DEFINE_FUNCTIONS.join(", ");
@@ -136,8 +146,8 @@ async function scanResolvers(nitro) {
136
146
  }
137
147
  if (exports.imports.length > 0) exportName.push(exports);
138
148
  } catch (error) {
139
- const relPath = relative(nitro.options.rootDir, file.fullPath);
140
- nitro.logger.error(`[nitro-graphql] Failed to parse resolver file ${relPath}:`, error);
149
+ const relPath$1 = relative(nitro.options.rootDir, file.fullPath);
150
+ nitro.logger.error(`[nitro-graphql] Failed to parse resolver file ${relPath$1}:`, error);
141
151
  }
142
152
  return exportName;
143
153
  }
@@ -1,7 +1,12 @@
1
1
  import { Nitro } from "nitro/types";
2
2
 
3
3
  //#region src/utils/type-generation.d.ts
4
- declare function serverTypeGeneration(app: Nitro): Promise<void>;
5
- declare function clientTypeGeneration(nitro: Nitro): Promise<void>;
4
+ declare function serverTypeGeneration(app: Nitro, options?: {
5
+ silent?: boolean;
6
+ }): Promise<void>;
7
+ declare function clientTypeGeneration(nitro: Nitro, options?: {
8
+ silent?: boolean;
9
+ isInitial?: boolean;
10
+ }): Promise<void>;
6
11
  //#endregion
7
12
  export { clientTypeGeneration, serverTypeGeneration };
@@ -6,12 +6,22 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
6
6
  import consola from "consola";
7
7
  import { basename, dirname, join, resolve } from "pathe";
8
8
  import { buildSchema, parse } from "graphql";
9
- import { buildSubgraphSchema } from "@apollo/subgraph";
10
9
  import { loadFilesSync } from "@graphql-tools/load-files";
11
10
  import { mergeTypeDefs } from "@graphql-tools/merge";
12
11
  import { printSchemaWithDirectives } from "@graphql-tools/utils";
13
12
 
14
13
  //#region src/utils/type-generation.ts
14
+ const logger = consola.withTag("nitro-graphql");
15
+ let buildSubgraphSchema = null;
16
+ async function loadFederationSupport() {
17
+ if (buildSubgraphSchema !== null) return buildSubgraphSchema;
18
+ try {
19
+ buildSubgraphSchema = (await import("@apollo/subgraph")).buildSubgraphSchema;
20
+ } catch {
21
+ buildSubgraphSchema = false;
22
+ }
23
+ return buildSubgraphSchema;
24
+ }
15
25
  function generateGraphQLIndexFile(nitro, clientDir, externalServices = []) {
16
26
  if (!shouldGenerateClientUtils(nitro)) return;
17
27
  const placeholders = getDefaultPaths(nitro);
@@ -238,15 +248,15 @@ function validateNoDuplicateTypes(schemas, schemaStrings) {
238
248
  }
239
249
  return true;
240
250
  }
241
- async function serverTypeGeneration(app) {
251
+ async function serverTypeGeneration(app, options = {}) {
242
252
  try {
243
253
  if (!shouldGenerateTypes(app)) {
244
- consola.debug("[nitro-graphql] Server type generation is disabled");
254
+ logger.debug("Server type generation is disabled");
245
255
  return;
246
256
  }
247
257
  const schemas = app.scanSchemas || [];
248
258
  if (!schemas.length) {
249
- consola.info("No GraphQL definitions found for server type generation.");
259
+ if (!options.silent) consola.info("No GraphQL definitions found for server type generation.");
250
260
  return;
251
261
  }
252
262
  const schemaStrings = loadFilesSync(schemas).map((schema$1) => typeof schema$1 === "string" ? schema$1 : schema$1.loc?.source?.body || "").filter(Boolean);
@@ -257,7 +267,12 @@ async function serverTypeGeneration(app) {
257
267
  commentDescriptions: true,
258
268
  sort: true
259
269
  });
260
- const schema = federationEnabled ? buildSubgraphSchema([{ typeDefs: parse(mergedSchemas) }]) : buildSchema(mergedSchemas);
270
+ let schema;
271
+ if (federationEnabled) {
272
+ const buildSubgraph = await loadFederationSupport();
273
+ if (!buildSubgraph) throw new Error("Federation is enabled but @apollo/subgraph is not installed. Run: pnpm add @apollo/subgraph");
274
+ schema = buildSubgraph([{ typeDefs: parse(mergedSchemas) }]);
275
+ } else schema = buildSchema(mergedSchemas);
261
276
  const data = await generateTypes(app.options.graphql?.framework || "graphql-yoga", schema, app.options.graphql ?? {});
262
277
  const printSchema = printSchemaWithDirectives(schema);
263
278
  const schemaPath = resolve(app.graphql.buildDir, "schema.graphql");
@@ -269,18 +284,18 @@ async function serverTypeGeneration(app) {
269
284
  if (serverTypesPath) {
270
285
  mkdirSync(dirname(serverTypesPath), { recursive: true });
271
286
  writeFileSync(serverTypesPath, data, "utf-8");
272
- consola.success(`[nitro-graphql] Generated server types at: ${serverTypesPath}`);
287
+ if (!options.silent) logger.success(`Generated server types at: ${serverTypesPath}`);
273
288
  }
274
289
  } catch (error) {
275
- consola.error("Server schema generation error:", error);
290
+ logger.error("Server schema generation error:", error);
276
291
  }
277
292
  }
278
- async function clientTypeGeneration(nitro) {
293
+ async function clientTypeGeneration(nitro, options = {}) {
279
294
  try {
280
- if (nitro.scanSchemas && nitro.scanSchemas.length > 0) await generateMainClientTypes(nitro);
281
- if (nitro.options.graphql?.externalServices?.length) await generateExternalServicesTypes(nitro);
295
+ if (nitro.scanSchemas && nitro.scanSchemas.length > 0) await generateMainClientTypes(nitro, options);
296
+ if (nitro.options.graphql?.externalServices?.length) await generateExternalServicesTypes(nitro, options);
282
297
  } catch (error) {
283
- consola.error("Client schema generation error:", error);
298
+ logger.error("Client schema generation error:", error);
284
299
  }
285
300
  }
286
301
  /**
@@ -311,17 +326,24 @@ function checkOldStructure(clientDir) {
311
326
  🚫 The old files will cause import conflicts until moved!`);
312
327
  }
313
328
  }
314
- async function generateMainClientTypes(nitro) {
329
+ async function generateMainClientTypes(nitro, options = {}) {
315
330
  checkOldStructure(nitro.graphql.clientDir);
316
331
  const docs = nitro.scanDocuments;
317
332
  const loadDocs = await loadGraphQLDocuments(docs);
318
333
  const schemaFilePath = join(nitro.graphql.buildDir, "schema.graphql");
319
334
  if (!existsSync(schemaFilePath)) {
320
- consola.info("Schema file not ready yet for client type generation. Server types need to be generated first.");
335
+ if (!options.silent) consola.info("Schema file not ready yet for client type generation. Server types need to be generated first.");
321
336
  return;
322
337
  }
323
338
  const graphqlString = readFileSync(schemaFilePath, "utf-8");
324
- const types = await generateClientTypes(nitro.options.graphql?.federation?.enabled === true ? buildSubgraphSchema([{ typeDefs: parse(graphqlString) }]) : buildSchema(graphqlString), loadDocs, nitro.options.graphql?.codegen?.client ?? {}, nitro.options.graphql?.codegen?.clientSDK ?? {});
339
+ const federationEnabled = nitro.options.graphql?.federation?.enabled === true;
340
+ let schema;
341
+ if (federationEnabled) {
342
+ const buildSubgraph = await loadFederationSupport();
343
+ if (!buildSubgraph) throw new Error("Federation is enabled but @apollo/subgraph is not installed. Run: pnpm add @apollo/subgraph");
344
+ schema = buildSubgraph([{ typeDefs: parse(graphqlString) }]);
345
+ } else schema = buildSchema(graphqlString);
346
+ const types = await generateClientTypes(schema, loadDocs, nitro.options.graphql?.codegen?.client ?? {}, nitro.options.graphql?.codegen?.clientSDK ?? {}, void 0, void 0, void 0, options);
325
347
  if (types === false) return;
326
348
  const placeholders = getDefaultPaths(nitro);
327
349
  const typesConfig = getTypesConfig(nitro);
@@ -330,22 +352,22 @@ async function generateMainClientTypes(nitro) {
330
352
  if (clientTypesPath) {
331
353
  mkdirSync(dirname(clientTypesPath), { recursive: true });
332
354
  writeFileSync(clientTypesPath, types.types, "utf-8");
333
- consola.success(`[nitro-graphql] Generated client types at: ${clientTypesPath}`);
355
+ if (!options.silent) logger.success(`Generated client types at: ${clientTypesPath}`);
334
356
  }
335
357
  const sdkPath = resolveFilePath(sdkConfig.main, sdkConfig.enabled, true, "{clientGraphql}/default/sdk.ts", placeholders);
336
358
  if (sdkPath) {
337
359
  mkdirSync(dirname(sdkPath), { recursive: true });
338
360
  writeFileSync(sdkPath, types.sdk, "utf-8");
339
- consola.success(`[nitro-graphql] Generated SDK at: ${sdkPath}`);
361
+ if (!options.silent) logger.success(`Generated SDK at: ${sdkPath}`);
340
362
  }
341
363
  generateNuxtOfetchClient(nitro, nitro.graphql.clientDir, "default");
342
364
  const externalServices = nitro.options.graphql?.externalServices || [];
343
365
  if (externalServices.length > 0) generateGraphQLIndexFile(nitro, nitro.graphql.clientDir, externalServices);
344
366
  }
345
- async function generateExternalServicesTypes(nitro) {
367
+ async function generateExternalServicesTypes(nitro, options = {}) {
346
368
  const externalServices = nitro.options.graphql?.externalServices || [];
347
369
  for (const service of externalServices) try {
348
- consola.info(`[graphql:${service.name}] Processing external service`);
370
+ if (!options.silent) consola.info(`[graphql:${service.name}] Processing external service`);
349
371
  await downloadAndSaveSchema(service, nitro.options.buildDir);
350
372
  const schema = await loadExternalSchema(service, nitro.options.buildDir);
351
373
  if (!schema) {
@@ -379,16 +401,16 @@ async function generateExternalServicesTypes(nitro) {
379
401
  if (serviceTypesPath) {
380
402
  mkdirSync(dirname(serviceTypesPath), { recursive: true });
381
403
  writeFileSync(serviceTypesPath, types.types, "utf-8");
382
- consola.success(`[graphql:${service.name}] Generated types at: ${serviceTypesPath}`);
404
+ if (!options.silent) consola.success(`[graphql:${service.name}] Generated types at: ${serviceTypesPath}`);
383
405
  }
384
406
  const serviceSdkPath = resolveFilePath(service.paths?.sdk ?? sdkConfig.external, sdkConfig.enabled, true, "{clientGraphql}/{serviceName}/sdk.ts", placeholders);
385
407
  if (serviceSdkPath) {
386
408
  mkdirSync(dirname(serviceSdkPath), { recursive: true });
387
409
  writeFileSync(serviceSdkPath, types.sdk, "utf-8");
388
- consola.success(`[graphql:${service.name}] Generated SDK at: ${serviceSdkPath}`);
410
+ if (!options.silent) consola.success(`[graphql:${service.name}] Generated SDK at: ${serviceSdkPath}`);
389
411
  }
390
412
  generateExternalOfetchClient(nitro, service, service.endpoint);
391
- consola.success(`[graphql:${service.name}] External service types generated successfully`);
413
+ if (!options.silent) consola.success(`[graphql:${service.name}] External service types generated successfully`);
392
414
  } catch (error) {
393
415
  consola.error(`[graphql:${service.name}] External service generation failed:`, error);
394
416
  }
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "nitro-graphql",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.25",
5
- "packageManager": "pnpm@10.22.0",
4
+ "version": "2.0.0-beta.27",
6
5
  "description": "GraphQL integration for Nitro",
7
6
  "license": "MIT",
8
7
  "sideEffects": false,
@@ -71,25 +70,8 @@
71
70
  "files": [
72
71
  "dist"
73
72
  ],
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
- },
90
73
  "peerDependencies": {
91
74
  "@apollo/server": "^5.0.0",
92
- "@apollo/utils.withrequired": "^3.0.0",
93
75
  "graphql": "^16.11.0",
94
76
  "h3": "^2.0.1-rc.2",
95
77
  "nitro": "^3.0.1-alpha.0"
@@ -97,63 +79,69 @@
97
79
  "peerDependenciesMeta": {
98
80
  "@apollo/server": {
99
81
  "optional": true
100
- },
101
- "@apollo/utils.withrequired": {
102
- "optional": true
103
82
  }
104
83
  },
105
84
  "dependencies": {
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:"
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"
130
109
  },
131
110
  "devDependencies": {
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
- }
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"
155
128
  },
156
129
  "resolutions": {
157
130
  "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"
158
146
  }
159
- }
147
+ }