nitro-graphql 1.7.1 → 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,101 +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) 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
+ }
163
191
  }
164
192
  });
165
- await rollupConfig(nitro);
166
- 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);
167
198
  await clientTypeGeneration(nitro);
168
199
  nitro.hooks.hook("close", async () => {
169
- await serverTypeGeneration(nitro);
200
+ if (serverEnabled) await serverTypeGeneration(nitro);
170
201
  await clientTypeGeneration(nitro);
171
202
  });
172
- const runtime = fileURLToPath(new URL("routes", import.meta.url));
173
- const methods = [
174
- "get",
175
- "post",
176
- "options"
177
- ];
178
- if (nitro.options.graphql?.framework === "graphql-yoga") for (const method of methods) nitro.options.handlers.push({
179
- route: nitro.options.runtimeConfig.graphql?.endpoint?.graphql || "/api/graphql",
180
- handler: join(runtime, "graphql-yoga"),
181
- method
182
- });
183
- if (nitro.options.graphql?.framework === "apollo-server") for (const method of methods) nitro.options.handlers.push({
184
- route: nitro.options.runtimeConfig.graphql?.endpoint?.graphql || "/api/graphql",
185
- handler: join(runtime, "apollo-server"),
186
- method
187
- });
188
- nitro.options.handlers.push({
189
- route: nitro.options.runtimeConfig.graphql?.endpoint?.healthCheck || "/api/graphql/health",
190
- handler: join(runtime, "health"),
191
- method: "get"
192
- });
193
- if (nitro.options.graphql?.subscriptions?.enabled) {
194
- nitro.options.experimental ||= {};
195
- nitro.options.experimental.websocket = true;
196
- const wsEndpoint = nitro.options.runtimeConfig.graphql?.endpoint?.ws || nitro.options.graphql?.subscriptions?.endpoint || "/api/graphql/ws";
197
- if (nitro.options.graphql?.framework === "graphql-yoga") nitro.options.handlers.push({
198
- route: wsEndpoint,
199
- 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
200
214
  });
201
- if (nitro.options.graphql?.framework === "apollo-server") nitro.options.handlers.push({
202
- route: wsEndpoint,
203
- 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
219
+ });
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({
242
+ route: "/_nitro/graphql/debug",
243
+ handler: join(runtime, "debug"),
244
+ method: "get"
204
245
  });
205
- nitro.options.plugins ??= [];
206
- nitro.options.plugins.push(join(runtime, "ws-shutdown"));
207
- consola.info(`[nitro-graphql] WebSocket subscriptions enabled at: ${wsEndpoint}`);
208
246
  }
209
- if (nitro.options.dev) nitro.options.handlers.push({
210
- route: "/_nitro/graphql/debug",
211
- handler: join(runtime, "debug"),
212
- method: "get"
213
- });
214
- if (nitro.options.imports) {
247
+ if (serverEnabled && nitro.options.imports) {
215
248
  nitro.options.imports.presets ??= [];
216
249
  nitro.options.imports.presets.push({
217
250
  from: fileURLToPath(new URL("utils/define", import.meta.url)),
@@ -228,7 +261,7 @@ var src_default = defineNitroModule({
228
261
  ]
229
262
  });
230
263
  }
231
- nitro.hooks.hook("rollup:before", (_, rollupConfig$1) => {
264
+ if (serverEnabled) nitro.hooks.hook("rollup:before", (_, rollupConfig$1) => {
232
265
  const manualChunks = rollupConfig$1.output?.manualChunks;
233
266
  const chunkFiles = rollupConfig$1.output?.chunkFileNames;
234
267
  if (!rollupConfig$1.output.inlineDynamicImports) rollupConfig$1.output.manualChunks = (id, meta) => {
@@ -249,11 +282,14 @@ var src_default = defineNitroModule({
249
282
  types.tsConfig.compilerOptions.paths ??= {};
250
283
  const placeholders = getDefaultPaths(nitro);
251
284
  const typesConfig = getTypesConfig(nitro);
252
- const serverTypesPath = resolveFilePath(typesConfig.server, typesConfig.enabled, true, "{typesDir}/nitro-graphql-server.d.ts", placeholders);
253
- 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
+ }
254
291
  const clientTypesPath = resolveFilePath(typesConfig.client, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client.d.ts", placeholders);
255
292
  if (clientTypesPath) types.tsConfig.compilerOptions.paths["#graphql/client"] = [relativeWithDot(tsconfigDir, clientTypesPath)];
256
- types.tsConfig.compilerOptions.paths["#graphql/schema"] = [relativeWithDot(tsconfigDir, join(nitro.graphql.serverDir, "schema.ts"))];
257
293
  if (nitro.options.graphql?.externalServices?.length) for (const service of nitro.options.graphql.externalServices) {
258
294
  const servicePlaceholders = {
259
295
  ...placeholders,
@@ -282,8 +318,9 @@ var src_default = defineNitroModule({
282
318
  if (shouldGenerateScaffold(nitro)) {
283
319
  const placeholders = getDefaultPaths(nitro);
284
320
  const scaffoldConfig = getScaffoldConfig(nitro);
285
- const graphqlConfigPath = resolveFilePath(scaffoldConfig.graphqlConfig, scaffoldConfig.enabled, true, "graphql.config.ts", placeholders);
286
- 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, `
287
324
  import type { IGraphQLConfig } from 'graphql-config'
288
325
 
289
326
  export default <IGraphQLConfig> {
@@ -298,17 +335,17 @@ export default <IGraphQLConfig> {
298
335
  },
299
336
  },
300
337
  }`, "graphql.config.ts");
301
- const serverSchemaPath = resolveFilePath(scaffoldConfig.serverSchema, scaffoldConfig.enabled, true, "{serverGraphql}/schema.ts", placeholders);
302
- const serverConfigPath = resolveFilePath(scaffoldConfig.serverConfig, scaffoldConfig.enabled, true, "{serverGraphql}/config.ts", placeholders);
303
- const serverContextPath = resolveFilePath(scaffoldConfig.serverContext, scaffoldConfig.enabled, true, "{serverGraphql}/context.ts", placeholders);
304
- if (serverSchemaPath || serverConfigPath || serverContextPath) {
305
- if (!existsSync(nitro.graphql.serverDir)) mkdirSync(nitro.graphql.serverDir, { recursive: true });
306
- }
307
- 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({
308
345
 
309
346
  })
310
347
  `, "server schema.ts");
311
- 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
312
349
  // import * as tables from '../drizzle/schema/index'
313
350
  // import { useDatabase } from '../utils/useDb'
314
351
 
@@ -324,7 +361,7 @@ export default defineGraphQLConfig({
324
361
  // },
325
362
  })
326
363
  `, "server config.ts");
327
- 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
328
365
  // import type { Database } from '../utils/useDb'
329
366
 
330
367
  declare module 'h3' {
@@ -340,15 +377,16 @@ declare module 'h3' {
340
377
  // }
341
378
  }
342
379
  }`, "server context.ts");
343
- if (existsSync(join(nitro.graphql.serverDir, "context.d.ts"))) {
344
- consola.warn("nitro-graphql: Found context.d.ts file. Please rename it to context.ts for the new structure.");
345
- consola.info("The context file should now be context.ts instead of context.d.ts");
346
- }
347
- if (nitro.options.graphql?.subscriptions?.enabled) {
348
- if (!existsSync(nitro.graphql.clientDir)) mkdirSync(nitro.graphql.clientDir, { recursive: true });
349
- const defaultDir = resolve(nitro.graphql.clientDir, "default");
350
- if (!existsSync(defaultDir)) mkdirSync(defaultDir, { recursive: true });
351
- 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
+ }
352
390
  }
353
391
  } else consola.info("[nitro-graphql] Scaffold file generation is disabled (library mode)");
354
392
  }
@@ -1,6 +1,6 @@
1
- import * as h39 from "h3";
1
+ import * as h35 from "h3";
2
2
 
3
3
  //#region src/routes/apollo-server.d.ts
4
- declare const _default: h39.EventHandler<h39.EventHandlerRequest, Promise<any>>;
4
+ declare const _default: h35.EventHandler<h35.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 h30 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.EventHandler<h35.EventHandlerRequest, Promise<string | {
13
+ declare const _default: h30.EventHandler<h30.EventHandlerRequest, Promise<string | {
14
14
  timestamp: string;
15
15
  environment: {
16
16
  dev: any;
@@ -1,4 +1,4 @@
1
- import * as h30 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 h30 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: h30.EventHandler<h30.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 h31 from "h3";
1
+ import * as h39 from "h3";
2
2
 
3
3
  //#region src/routes/graphql-yoga.d.ts
4
- declare const _default: h31.EventHandler<h31.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);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nitro-graphql",
3
3
  "type": "module",
4
- "version": "1.7.1",
4
+ "version": "1.8.0",
5
5
  "description": "GraphQL integration for Nitro",
6
6
  "license": "MIT",
7
7
  "repository": {