nitro-graphql 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -210,6 +210,246 @@ query {
210
210
 
211
211
  ## 🚀 Advanced Features
212
212
 
213
+ <details>
214
+ <summary><strong>🎛️ Custom File Generation & Paths</strong></summary>
215
+
216
+ Control which files are auto-generated and customize their output paths. Perfect for library development, monorepos, or custom project structures.
217
+
218
+ ### Library Mode
219
+
220
+ Disable all scaffold files for library/module development:
221
+
222
+ ```ts
223
+ // nitro.config.ts
224
+ export default defineNitroConfig({
225
+ graphql: {
226
+ framework: 'graphql-yoga',
227
+ scaffold: false, // Disable all scaffold files
228
+ clientUtils: false, // Disable client utilities
229
+ }
230
+ })
231
+ ```
232
+
233
+ ### Fine-Grained Control
234
+
235
+ Control each file individually:
236
+
237
+ ```ts
238
+ export default defineNitroConfig({
239
+ graphql: {
240
+ framework: 'graphql-yoga',
241
+
242
+ // Scaffold files
243
+ scaffold: {
244
+ graphqlConfig: false, // Don't generate graphql.config.ts
245
+ serverSchema: true, // Generate server/graphql/schema.ts
246
+ serverConfig: true, // Generate server/graphql/config.ts
247
+ serverContext: false, // Don't generate server/graphql/context.ts
248
+ },
249
+
250
+ // Client utilities (Nuxt only)
251
+ clientUtils: {
252
+ index: true, // Generate app/graphql/index.ts
253
+ ofetch: false, // Don't generate ofetch wrappers
254
+ },
255
+
256
+ // SDK files
257
+ sdk: {
258
+ main: true, // Generate default SDK
259
+ external: true, // Generate external service SDKs
260
+ },
261
+
262
+ // Type files
263
+ types: {
264
+ server: true, // Generate server types
265
+ client: true, // Generate client types
266
+ external: true, // Generate external service types
267
+ }
268
+ }
269
+ })
270
+ ```
271
+
272
+ ### Custom Paths
273
+
274
+ Customize where files are generated:
275
+
276
+ ```ts
277
+ export default defineNitroConfig({
278
+ graphql: {
279
+ framework: 'graphql-yoga',
280
+
281
+ // Method 1: Global paths (affects all files)
282
+ paths: {
283
+ serverGraphql: 'src/server/graphql',
284
+ clientGraphql: 'src/client/graphql',
285
+ buildDir: '.build',
286
+ typesDir: '.build/types',
287
+ },
288
+
289
+ // Method 2: Specific file paths
290
+ scaffold: {
291
+ serverSchema: 'lib/graphql/schema.ts',
292
+ serverConfig: 'lib/graphql/config.ts',
293
+ },
294
+
295
+ sdk: {
296
+ main: 'app/graphql/organization/sdk.ts',
297
+ external: 'app/graphql/{serviceName}/client-sdk.ts',
298
+ },
299
+
300
+ types: {
301
+ server: 'types/graphql-server.d.ts',
302
+ client: 'types/graphql-client.d.ts',
303
+ }
304
+ }
305
+ })
306
+ ```
307
+
308
+ ### Path Placeholders
309
+
310
+ Use placeholders in custom paths:
311
+
312
+ | Placeholder | Description | Example |
313
+ |------------|-------------|---------|
314
+ | `{serviceName}` | External service name | `github`, `stripe` |
315
+ | `{buildDir}` | Build directory | `.nitro` or `.nuxt` |
316
+ | `{rootDir}` | Root directory | `/Users/you/project` |
317
+ | `{framework}` | Framework name | `nuxt` or `nitro` |
318
+ | `{typesDir}` | Types directory | `.nitro/types` |
319
+ | `{serverGraphql}` | Server GraphQL dir | `server/graphql` |
320
+ | `{clientGraphql}` | Client GraphQL dir | `app/graphql` |
321
+
322
+ Example:
323
+ ```ts
324
+ sdk: {
325
+ external: '{clientGraphql}/{serviceName}/sdk.ts'
326
+ }
327
+ // → app/graphql/github/sdk.ts
328
+ // → app/graphql/stripe/sdk.ts
329
+ ```
330
+
331
+ ### Service-Specific Paths
332
+
333
+ Customize paths for individual external services:
334
+
335
+ ```ts
336
+ export default defineNuxtConfig({
337
+ nitro: {
338
+ graphql: {
339
+ framework: 'graphql-yoga',
340
+
341
+ // Global default for all external services
342
+ sdk: {
343
+ external: 'app/graphql/{serviceName}/sdk.ts'
344
+ },
345
+
346
+ externalServices: [
347
+ {
348
+ name: 'github',
349
+ endpoint: 'https://api.github.com/graphql',
350
+ schema: 'https://api.github.com/graphql',
351
+
352
+ // GitHub-specific paths (override global config)
353
+ paths: {
354
+ sdk: 'app/graphql/organization/github-sdk.ts',
355
+ types: 'types/github.d.ts',
356
+ ofetch: 'app/graphql/organization/github-client.ts'
357
+ }
358
+ },
359
+ {
360
+ name: 'stripe',
361
+ endpoint: 'https://api.stripe.com/graphql',
362
+ schema: 'https://api.stripe.com/graphql',
363
+
364
+ // Stripe-specific paths
365
+ paths: {
366
+ sdk: 'app/graphql/payments/stripe-sdk.ts',
367
+ types: 'types/payments/stripe.d.ts',
368
+ // ofetch uses global config
369
+ }
370
+ },
371
+ {
372
+ name: 'shopify',
373
+ endpoint: 'https://api.shopify.com/graphql',
374
+ // No paths → uses global config
375
+ // → app/graphql/shopify/sdk.ts
376
+ }
377
+ ]
378
+ }
379
+ }
380
+ })
381
+ ```
382
+
383
+ ### Path Resolution Priority
384
+
385
+ When resolving file paths, the system follows this priority order:
386
+
387
+ 1. **Service-specific path** (for external services): `service.paths.sdk`
388
+ 2. **Category config**: `sdk.external` or `sdk.main`
389
+ 3. **Global paths**: `paths.clientGraphql`
390
+ 4. **Framework defaults**: Nuxt vs Nitro defaults
391
+
392
+ Example:
393
+ ```ts
394
+ // Given this config:
395
+ {
396
+ paths: { clientGraphql: 'custom/graphql' },
397
+ sdk: { external: '{clientGraphql}/{serviceName}/sdk.ts' },
398
+ externalServices: [
399
+ {
400
+ name: 'github',
401
+ paths: { sdk: 'app/org/github-sdk.ts' } // ← Wins (priority 1)
402
+ },
403
+ {
404
+ name: 'stripe',
405
+ // Uses sdk.external (priority 2)
406
+ // → custom/graphql/stripe/sdk.ts
407
+ }
408
+ ]
409
+ }
410
+ ```
411
+
412
+ ### Use Cases
413
+
414
+ **Monorepo structure:**
415
+ ```ts
416
+ paths: {
417
+ serverGraphql: 'packages/api/src/graphql',
418
+ clientGraphql: 'packages/web/src/graphql',
419
+ typesDir: 'packages/types/src/generated',
420
+ }
421
+ ```
422
+
423
+ **Multiple external service organizations:**
424
+ ```ts
425
+ externalServices: [
426
+ {
427
+ name: 'github',
428
+ paths: { sdk: 'app/graphql/vcs/github-sdk.ts' }
429
+ },
430
+ {
431
+ name: 'gitlab',
432
+ paths: { sdk: 'app/graphql/vcs/gitlab-sdk.ts' }
433
+ },
434
+ {
435
+ name: 'stripe',
436
+ paths: { sdk: 'app/graphql/billing/stripe-sdk.ts' }
437
+ }
438
+ ]
439
+ ```
440
+
441
+ **Library development (no scaffolding):**
442
+ ```ts
443
+ {
444
+ scaffold: false,
445
+ clientUtils: false,
446
+ sdk: { enabled: true }, // Only generate SDKs
447
+ types: { enabled: true }, // Only generate types
448
+ }
449
+ ```
450
+
451
+ </details>
452
+
213
453
  <details>
214
454
  <summary><strong>🎭 Custom Directives</strong></summary>
215
455
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { StandardSchemaV1 } from "./types/standard-schema.js";
2
- import { CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, FederationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions } from "./types/index.js";
2
+ import { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, TypesConfig } from "./types/index.js";
3
3
  import * as nitropack0 from "nitropack";
4
4
 
5
5
  //#region src/index.d.ts
6
6
  declare const _default: nitropack0.NitroModule;
7
7
  //#endregion
8
- export { CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, FederationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, StandardSchemaV1, _default as default };
8
+ export { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, StandardSchemaV1, TypesConfig, _default as default };
package/dist/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { generateDirectiveSchemas } from "./utils/directive-parser.js";
2
2
  import { generateLayerIgnorePatterns, getLayerAppDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanResolvers, scanSchemas, validateExternalServices } from "./utils/index.js";
3
+ import { writeFileIfNotExists } from "./utils/file-generator.js";
4
+ import { getDefaultPaths, getScaffoldConfig, resolveFilePath, shouldGenerateScaffold } from "./utils/path-resolver.js";
3
5
  import { clientTypeGeneration, serverTypeGeneration } from "./utils/type-generation.js";
4
6
  import { rollupConfig } from "./rollup.js";
5
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
7
+ import { existsSync, mkdirSync } from "node:fs";
6
8
  import { fileURLToPath } from "node:url";
7
9
  import { watch } from "chokidar";
8
10
  import consola from "consola";
@@ -236,31 +238,36 @@ var src_default = defineNitroModule({
236
238
  const nuxtOptions = nitro._nuxt?.options;
237
239
  if (nuxtOptions) nuxtOptions.nitroGraphqlExternalServices = nitro.options.graphql?.externalServices || [];
238
240
  });
239
- if (!existsSync(join(nitro.options.rootDir, "graphql.config.ts"))) {
240
- const schemaPath = relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.buildDir, "schema.graphql"));
241
- const documentsPath = relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.clientDir, "**/*.{graphql,js,ts,jsx,tsx}"));
242
- writeFileSync(join(nitro.options.rootDir, "graphql.config.ts"), `
241
+ if (shouldGenerateScaffold(nitro)) {
242
+ const placeholders = getDefaultPaths(nitro);
243
+ const scaffoldConfig = getScaffoldConfig(nitro);
244
+ const graphqlConfigPath = resolveFilePath(scaffoldConfig.graphqlConfig, scaffoldConfig.enabled, true, "graphql.config.ts", placeholders);
245
+ if (graphqlConfigPath) writeFileIfNotExists(graphqlConfigPath, `
243
246
  import type { IGraphQLConfig } from 'graphql-config'
244
247
 
245
248
  export default <IGraphQLConfig> {
246
249
  projects: {
247
250
  default: {
248
251
  schema: [
249
- '${schemaPath}',
252
+ '${relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.buildDir, "schema.graphql"))}',
250
253
  ],
251
254
  documents: [
252
- '${documentsPath}',
255
+ '${relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.clientDir, "**/*.{graphql,js,ts,jsx,tsx}"))}',
253
256
  ],
254
257
  },
255
258
  },
256
- }`, "utf-8");
257
- }
258
- if (!existsSync(nitro.graphql.serverDir)) mkdirSync(nitro.graphql.serverDir, { recursive: true });
259
- if (!existsSync(join(nitro.graphql.serverDir, "schema.ts"))) writeFileSync(join(nitro.graphql.serverDir, "schema.ts"), `export default defineSchema({
259
+ }`, "graphql.config.ts");
260
+ const serverSchemaPath = resolveFilePath(scaffoldConfig.serverSchema, scaffoldConfig.enabled, true, "{serverGraphql}/schema.ts", placeholders);
261
+ const serverConfigPath = resolveFilePath(scaffoldConfig.serverConfig, scaffoldConfig.enabled, true, "{serverGraphql}/config.ts", placeholders);
262
+ const serverContextPath = resolveFilePath(scaffoldConfig.serverContext, scaffoldConfig.enabled, true, "{serverGraphql}/context.ts", placeholders);
263
+ if (serverSchemaPath || serverConfigPath || serverContextPath) {
264
+ if (!existsSync(nitro.graphql.serverDir)) mkdirSync(nitro.graphql.serverDir, { recursive: true });
265
+ }
266
+ if (serverSchemaPath) writeFileIfNotExists(serverSchemaPath, `export default defineSchema({
260
267
 
261
268
  })
262
- `, "utf-8");
263
- if (!existsSync(join(nitro.graphql.serverDir, "config.ts"))) writeFileSync(join(nitro.graphql.serverDir, "config.ts"), `// Example GraphQL config file please change it to your needs
269
+ `, "server schema.ts");
270
+ if (serverConfigPath) writeFileIfNotExists(serverConfigPath, `// Example GraphQL config file please change it to your needs
264
271
  // import * as tables from '../drizzle/schema/index'
265
272
  // import { useDatabase } from '../utils/useDb'
266
273
 
@@ -275,8 +282,8 @@ export default defineGraphQLConfig({
275
282
  // }
276
283
  // },
277
284
  })
278
- `, "utf-8");
279
- if (!existsSync(join(nitro.graphql.serverDir, "context.ts"))) writeFileSync(join(nitro.graphql.serverDir, "context.ts"), `// Example context definition - please change it to your needs
285
+ `, "server config.ts");
286
+ if (serverContextPath) writeFileIfNotExists(serverContextPath, `// Example context definition - please change it to your needs
280
287
  // import type { Database } from '../utils/useDb'
281
288
 
282
289
  declare module 'h3' {
@@ -291,11 +298,12 @@ declare module 'h3' {
291
298
  // }
292
299
  // }
293
300
  }
294
- }`, "utf-8");
295
- if (existsSync(join(nitro.graphql.serverDir, "context.d.ts"))) {
296
- consola.warn("nitro-graphql: Found context.d.ts file. Please rename it to context.ts for the new structure.");
297
- consola.info("The context file should now be context.ts instead of context.d.ts");
298
- }
301
+ }`, "server context.ts");
302
+ if (existsSync(join(nitro.graphql.serverDir, "context.d.ts"))) {
303
+ consola.warn("nitro-graphql: Found context.d.ts file. Please rename it to context.ts for the new structure.");
304
+ consola.info("The context file should now be context.ts instead of context.d.ts");
305
+ }
306
+ } else consola.info("[nitro-graphql] Scaffold file generation is disabled (library mode)");
299
307
  }
300
308
  });
301
309
 
@@ -1,6 +1,6 @@
1
- import * as h31 from "h3";
1
+ import * as h35 from "h3";
2
2
 
3
3
  //#region src/routes/apollo-server.d.ts
4
- declare const _default: h31.EventHandler<h31.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 h33 from "h3";
1
+ import * as h31 from "h3";
2
2
 
3
3
  //#region src/routes/debug.d.ts
4
4
 
@@ -10,7 +10,7 @@ import * as h33 from "h3";
10
10
  * - /_nitro/graphql/debug - HTML dashboard
11
11
  * - /_nitro/graphql/debug?format=json - JSON API
12
12
  */
13
- declare const _default: h33.EventHandler<h33.EventHandlerRequest, Promise<string | {
13
+ declare const _default: h31.EventHandler<h31.EventHandlerRequest, Promise<string | {
14
14
  timestamp: string;
15
15
  environment: {
16
16
  dev: any;
@@ -1,7 +1,7 @@
1
- import * as h35 from "h3";
1
+ import * as h33 from "h3";
2
2
 
3
3
  //#region src/routes/health.d.ts
4
- declare const _default: h35.EventHandler<h35.EventHandlerRequest, Promise<{
4
+ declare const _default: h33.EventHandler<h33.EventHandlerRequest, Promise<{
5
5
  status: string;
6
6
  message: string;
7
7
  timestamp: string;
@@ -57,6 +57,18 @@ declare module 'nitropack' {
57
57
  graphql?: NitroGraphQLOptions;
58
58
  }
59
59
  }
60
+ /**
61
+ * Service-specific path overrides for external GraphQL services
62
+ * These paths override global config for this specific service
63
+ */
64
+ interface ExternalServicePaths {
65
+ /** SDK file path (overrides global sdk.external config) */
66
+ sdk?: FileGenerationConfig;
67
+ /** Type definitions file path (overrides global types.external config) */
68
+ types?: FileGenerationConfig;
69
+ /** ofetch client wrapper path (overrides global clientUtils.ofetch config) */
70
+ ofetch?: FileGenerationConfig;
71
+ }
60
72
  interface ExternalGraphQLService {
61
73
  /** Unique name for this service (used for file naming and type generation) */
62
74
  name: string;
@@ -83,6 +95,12 @@ interface ExternalGraphQLService {
83
95
  client?: CodegenClientConfig;
84
96
  clientSDK?: GenericSdkConfig;
85
97
  };
98
+ /**
99
+ * Optional: Service-specific path overrides
100
+ * These paths take precedence over global config (sdk, types, clientUtils)
101
+ * Supports placeholders: {serviceName}, {buildDir}, {rootDir}, {framework}, {typesDir}, {clientGraphql}
102
+ */
103
+ paths?: ExternalServicePaths;
86
104
  }
87
105
  interface FederationConfig {
88
106
  /** Enable Apollo Federation subgraph support */
@@ -94,6 +112,81 @@ interface FederationConfig {
94
112
  /** Service URL for federation gateway */
95
113
  serviceUrl?: string;
96
114
  }
115
+ /**
116
+ * File generation control:
117
+ * - false: Do not generate this file
118
+ * - true: Generate at default location
119
+ * - string: Generate at custom path (supports placeholders: {serviceName}, {buildDir}, {rootDir}, {framework})
120
+ */
121
+ type FileGenerationConfig = boolean | string;
122
+ /**
123
+ * Scaffold files configuration
124
+ * Control auto-generation of scaffold/boilerplate files
125
+ */
126
+ interface ScaffoldConfig {
127
+ /** Enable/disable all scaffold files */
128
+ enabled?: boolean;
129
+ /** graphql.config.ts - GraphQL Config file for IDE tooling */
130
+ graphqlConfig?: FileGenerationConfig;
131
+ /** server/graphql/schema.ts - Schema definition file */
132
+ serverSchema?: FileGenerationConfig;
133
+ /** server/graphql/config.ts - GraphQL server configuration */
134
+ serverConfig?: FileGenerationConfig;
135
+ /** server/graphql/context.ts - H3 context augmentation */
136
+ serverContext?: FileGenerationConfig;
137
+ }
138
+ /**
139
+ * Client utilities configuration
140
+ * Control auto-generation of client-side utility files (Nuxt only)
141
+ */
142
+ interface ClientUtilsConfig {
143
+ /** Enable/disable all client utilities */
144
+ enabled?: boolean;
145
+ /** app/graphql/index.ts - Main exports file */
146
+ index?: FileGenerationConfig;
147
+ /** app/graphql/{serviceName}/ofetch.ts - ofetch client wrapper */
148
+ ofetch?: FileGenerationConfig;
149
+ }
150
+ /**
151
+ * SDK files configuration
152
+ * Control auto-generation of GraphQL SDK files
153
+ */
154
+ interface SdkConfig {
155
+ /** Enable/disable all SDK files */
156
+ enabled?: boolean;
157
+ /** app/graphql/default/sdk.ts - Main service SDK */
158
+ main?: FileGenerationConfig;
159
+ /** app/graphql/{serviceName}/sdk.ts - External service SDKs */
160
+ external?: FileGenerationConfig;
161
+ }
162
+ /**
163
+ * Type files configuration
164
+ * Control auto-generation of TypeScript type definition files
165
+ */
166
+ interface TypesConfig {
167
+ /** Enable/disable all type files */
168
+ enabled?: boolean;
169
+ /** .nitro/types/nitro-graphql-server.d.ts - Server-side types */
170
+ server?: FileGenerationConfig;
171
+ /** .nitro/types/nitro-graphql-client.d.ts - Client-side types */
172
+ client?: FileGenerationConfig;
173
+ /** .nitro/types/nitro-graphql-client-{serviceName}.d.ts - External service types */
174
+ external?: FileGenerationConfig;
175
+ }
176
+ /**
177
+ * Global path overrides
178
+ * Set base directories for file generation
179
+ */
180
+ interface PathsConfig {
181
+ /** Server GraphQL directory (default: 'server/graphql') */
182
+ serverGraphql?: string;
183
+ /** Client GraphQL directory (default: 'app/graphql' for Nuxt, 'graphql' for Nitro) */
184
+ clientGraphql?: string;
185
+ /** Build directory (default: '.nitro' or '.nuxt') */
186
+ buildDir?: string;
187
+ /** Types directory (default: '{buildDir}/types') */
188
+ typesDir?: string;
189
+ }
97
190
  interface NitroGraphQLOptions {
98
191
  framework: 'graphql-yoga' | 'apollo-server';
99
192
  endpoint?: {
@@ -123,6 +216,31 @@ interface NitroGraphQLOptions {
123
216
  layerDirectories?: string[];
124
217
  layerServerDirs?: string[];
125
218
  layerAppDirs?: string[];
219
+ /**
220
+ * Scaffold files configuration
221
+ * Set to false to disable all scaffold file generation (library mode)
222
+ */
223
+ scaffold?: false | ScaffoldConfig;
224
+ /**
225
+ * Client utilities configuration
226
+ * Set to false to disable all client utility generation
227
+ */
228
+ clientUtils?: false | ClientUtilsConfig;
229
+ /**
230
+ * SDK files configuration
231
+ * Set to false to disable all SDK generation
232
+ */
233
+ sdk?: false | SdkConfig;
234
+ /**
235
+ * Type files configuration
236
+ * Set to false to disable all type generation
237
+ */
238
+ types?: false | TypesConfig;
239
+ /**
240
+ * Global path overrides
241
+ * Customize base directories for file generation
242
+ */
243
+ paths?: PathsConfig;
126
244
  }
127
245
  //#endregion
128
- export { CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, FederationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions };
246
+ export { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, TypesConfig };
@@ -0,0 +1,37 @@
1
+ import { Nitro } from "nitropack/types";
2
+
3
+ //#region src/utils/file-generator.d.ts
4
+
5
+ /**
6
+ * Safely write a file to disk, creating parent directories if needed
7
+ */
8
+ declare function writeFile(filePath: string, content: string, description?: string): void;
9
+ /**
10
+ * Write a file only if it doesn't already exist
11
+ * Returns true if file was created, false if it already existed
12
+ */
13
+ declare function writeFileIfNotExists(filePath: string, content: string, description?: string): boolean;
14
+ /**
15
+ * Write a file and always overwrite (used for generated files like SDK)
16
+ * This is for files that are auto-generated and should be updated on every build
17
+ */
18
+ declare function writeGeneratedFile(filePath: string, content: string, description?: string): void;
19
+ /**
20
+ * Check if a path is configured and should be generated
21
+ * Returns the resolved path if should generate, null otherwise
22
+ */
23
+ declare function getGenerationPath(resolvedPath: string | null, description?: string): string | null;
24
+ /**
25
+ * Log skipped file generation (helpful for debugging library mode)
26
+ */
27
+ declare function logSkipped(fileName: string, reason?: string): void;
28
+ /**
29
+ * Log generated file path
30
+ */
31
+ declare function logGenerated(fileName: string, path: string): void;
32
+ /**
33
+ * Validate that a Nitro instance has the required GraphQL configuration
34
+ */
35
+ declare function validateGraphQLConfig(nitro: Nitro): boolean;
36
+ //#endregion
37
+ export { getGenerationPath, logGenerated, logSkipped, validateGraphQLConfig, writeFile, writeFileIfNotExists, writeGeneratedFile };
@@ -0,0 +1,72 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import consola from "consola";
3
+ import { dirname } from "pathe";
4
+
5
+ //#region src/utils/file-generator.ts
6
+ /**
7
+ * Safely write a file to disk, creating parent directories if needed
8
+ */
9
+ function writeFile(filePath, content, description) {
10
+ try {
11
+ const dir = dirname(filePath);
12
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
13
+ writeFileSync(filePath, content, "utf-8");
14
+ if (description) consola.success(`[nitro-graphql] Generated: ${description}`);
15
+ } catch (error) {
16
+ consola.error(`[nitro-graphql] Failed to write file: ${filePath}`, error);
17
+ throw error;
18
+ }
19
+ }
20
+ /**
21
+ * Write a file only if it doesn't already exist
22
+ * Returns true if file was created, false if it already existed
23
+ */
24
+ function writeFileIfNotExists(filePath, content, description) {
25
+ if (existsSync(filePath)) return false;
26
+ writeFile(filePath, content, description);
27
+ return true;
28
+ }
29
+ /**
30
+ * Write a file and always overwrite (used for generated files like SDK)
31
+ * This is for files that are auto-generated and should be updated on every build
32
+ */
33
+ function writeGeneratedFile(filePath, content, description) {
34
+ writeFile(filePath, content, description);
35
+ }
36
+ /**
37
+ * Check if a path is configured and should be generated
38
+ * Returns the resolved path if should generate, null otherwise
39
+ */
40
+ function getGenerationPath(resolvedPath, description) {
41
+ if (!resolvedPath) {
42
+ if (description) consola.debug(`[nitro-graphql] Skipping generation: ${description} (disabled in config)`);
43
+ return null;
44
+ }
45
+ return resolvedPath;
46
+ }
47
+ /**
48
+ * Log skipped file generation (helpful for debugging library mode)
49
+ */
50
+ function logSkipped(fileName, reason) {
51
+ const message = reason ? `Skipped ${fileName}: ${reason}` : `Skipped ${fileName}`;
52
+ consola.debug(`[nitro-graphql] ${message}`);
53
+ }
54
+ /**
55
+ * Log generated file path
56
+ */
57
+ function logGenerated(fileName, path) {
58
+ consola.info(`[nitro-graphql] Generated ${fileName} at: ${path}`);
59
+ }
60
+ /**
61
+ * Validate that a Nitro instance has the required GraphQL configuration
62
+ */
63
+ function validateGraphQLConfig(nitro) {
64
+ if (!nitro.options.graphql?.framework) {
65
+ consola.warn("[nitro-graphql] No GraphQL framework specified. Some features may not work correctly.");
66
+ return false;
67
+ }
68
+ return true;
69
+ }
70
+
71
+ //#endregion
72
+ export { getGenerationPath, logGenerated, logSkipped, validateGraphQLConfig, writeFile, writeFileIfNotExists, writeGeneratedFile };
@@ -0,0 +1,70 @@
1
+ import { ClientUtilsConfig, FileGenerationConfig, ScaffoldConfig, SdkConfig, TypesConfig } from "../types/index.js";
2
+ import { Nitro } from "nitropack/types";
3
+
4
+ //#region src/utils/path-resolver.d.ts
5
+
6
+ /**
7
+ * Placeholder values for path resolution
8
+ */
9
+ interface PathPlaceholders {
10
+ serviceName?: string;
11
+ buildDir: string;
12
+ rootDir: string;
13
+ framework: 'nuxt' | 'nitro';
14
+ typesDir: string;
15
+ serverGraphql: string;
16
+ clientGraphql: string;
17
+ }
18
+ /**
19
+ * Replace placeholders in a path string
20
+ * Supports: {serviceName}, {buildDir}, {rootDir}, {framework}, {typesDir}, {serverGraphql}, {clientGraphql}
21
+ */
22
+ declare function replacePlaceholders(path: string, placeholders: PathPlaceholders): string;
23
+ /**
24
+ * Get default paths based on framework and user configuration
25
+ */
26
+ declare function getDefaultPaths(nitro: Nitro): Required<PathPlaceholders>;
27
+ /**
28
+ * Check if a file should be generated based on config
29
+ * Returns: true if should generate, false if should skip
30
+ */
31
+ declare function shouldGenerateFile(config: FileGenerationConfig | undefined, categoryEnabled: boolean | undefined, topLevelEnabled: boolean): boolean;
32
+ /**
33
+ * Resolve the file path based on configuration
34
+ * Returns: resolved absolute path or null if file should not be generated
35
+ */
36
+ declare function resolveFilePath(config: FileGenerationConfig | undefined, categoryEnabled: boolean | undefined, topLevelEnabled: boolean, defaultPath: string, placeholders: PathPlaceholders): string | null;
37
+ /**
38
+ * Check if scaffold files should be generated (category-level check)
39
+ */
40
+ declare function shouldGenerateScaffold(nitro: Nitro): boolean;
41
+ /**
42
+ * Get scaffold configuration (handles false case)
43
+ */
44
+ declare function getScaffoldConfig(nitro: Nitro): ScaffoldConfig;
45
+ /**
46
+ * Check if client utilities should be generated (category-level check)
47
+ */
48
+ declare function shouldGenerateClientUtils(nitro: Nitro): boolean;
49
+ /**
50
+ * Get client utilities configuration (handles false case)
51
+ */
52
+ declare function getClientUtilsConfig(nitro: Nitro): ClientUtilsConfig;
53
+ /**
54
+ * Check if SDK files should be generated (category-level check)
55
+ */
56
+ declare function shouldGenerateSDK(nitro: Nitro): boolean;
57
+ /**
58
+ * Get SDK configuration (handles false case)
59
+ */
60
+ declare function getSdkConfig(nitro: Nitro): SdkConfig;
61
+ /**
62
+ * Check if type files should be generated (category-level check)
63
+ */
64
+ declare function shouldGenerateTypes(nitro: Nitro): boolean;
65
+ /**
66
+ * Get types configuration (handles false case)
67
+ */
68
+ declare function getTypesConfig(nitro: Nitro): TypesConfig;
69
+ //#endregion
70
+ export { PathPlaceholders, getClientUtilsConfig, getDefaultPaths, getScaffoldConfig, getSdkConfig, getTypesConfig, replacePlaceholders, resolveFilePath, shouldGenerateClientUtils, shouldGenerateFile, shouldGenerateSDK, shouldGenerateScaffold, shouldGenerateTypes };
@@ -0,0 +1,127 @@
1
+ import { resolve } from "pathe";
2
+
3
+ //#region src/utils/path-resolver.ts
4
+ /**
5
+ * Replace placeholders in a path string
6
+ * Supports: {serviceName}, {buildDir}, {rootDir}, {framework}, {typesDir}, {serverGraphql}, {clientGraphql}
7
+ */
8
+ function replacePlaceholders(path, placeholders) {
9
+ return path.replace(/\{serviceName\}/g, placeholders.serviceName || "default").replace(/\{buildDir\}/g, placeholders.buildDir).replace(/\{rootDir\}/g, placeholders.rootDir).replace(/\{framework\}/g, placeholders.framework).replace(/\{typesDir\}/g, placeholders.typesDir).replace(/\{serverGraphql\}/g, placeholders.serverGraphql).replace(/\{clientGraphql\}/g, placeholders.clientGraphql);
10
+ }
11
+ /**
12
+ * Get default paths based on framework and user configuration
13
+ */
14
+ function getDefaultPaths(nitro) {
15
+ const isNuxt = nitro.options.framework?.name === "nuxt";
16
+ const rootDir = nitro.options.rootDir;
17
+ const buildDir = nitro.options.buildDir;
18
+ const pathsConfig = nitro.options.graphql?.paths || {};
19
+ const defaultServerGraphql = pathsConfig.serverGraphql || resolve(rootDir, "server", "graphql");
20
+ const defaultClientGraphql = pathsConfig.clientGraphql || resolve(rootDir, isNuxt ? "app/graphql" : "graphql");
21
+ const defaultBuildDir = pathsConfig.buildDir || buildDir;
22
+ const defaultTypesDir = pathsConfig.typesDir || resolve(defaultBuildDir, "types");
23
+ return {
24
+ serviceName: "default",
25
+ buildDir: defaultBuildDir,
26
+ rootDir,
27
+ framework: isNuxt ? "nuxt" : "nitro",
28
+ typesDir: defaultTypesDir,
29
+ serverGraphql: defaultServerGraphql,
30
+ clientGraphql: defaultClientGraphql
31
+ };
32
+ }
33
+ /**
34
+ * Check if a file should be generated based on config
35
+ * Returns: true if should generate, false if should skip
36
+ */
37
+ function shouldGenerateFile(config, categoryEnabled, topLevelEnabled) {
38
+ if (config === false) return false;
39
+ if (config === true || typeof config === "string") return true;
40
+ if (categoryEnabled === false) return false;
41
+ if (categoryEnabled === true) return true;
42
+ return topLevelEnabled;
43
+ }
44
+ /**
45
+ * Resolve the file path based on configuration
46
+ * Returns: resolved absolute path or null if file should not be generated
47
+ */
48
+ function resolveFilePath(config, categoryEnabled, topLevelEnabled, defaultPath, placeholders) {
49
+ if (!shouldGenerateFile(config, categoryEnabled, topLevelEnabled)) return null;
50
+ if (typeof config === "string") {
51
+ const customPath = replacePlaceholders(config, placeholders);
52
+ return resolve(placeholders.rootDir, customPath);
53
+ }
54
+ const resolvedDefault = replacePlaceholders(defaultPath, placeholders);
55
+ return resolve(placeholders.rootDir, resolvedDefault);
56
+ }
57
+ /**
58
+ * Check if scaffold files should be generated (category-level check)
59
+ */
60
+ function shouldGenerateScaffold(nitro) {
61
+ const scaffoldConfig = nitro.options.graphql?.scaffold;
62
+ if (scaffoldConfig === false) return false;
63
+ if (scaffoldConfig && scaffoldConfig.enabled === false) return false;
64
+ return true;
65
+ }
66
+ /**
67
+ * Get scaffold configuration (handles false case)
68
+ */
69
+ function getScaffoldConfig(nitro) {
70
+ const scaffoldConfig = nitro.options.graphql?.scaffold;
71
+ if (scaffoldConfig === false) return { enabled: false };
72
+ return scaffoldConfig || {};
73
+ }
74
+ /**
75
+ * Check if client utilities should be generated (category-level check)
76
+ */
77
+ function shouldGenerateClientUtils(nitro) {
78
+ const clientUtilsConfig = nitro.options.graphql?.clientUtils;
79
+ if (clientUtilsConfig === false) return false;
80
+ if (clientUtilsConfig && clientUtilsConfig.enabled === false) return false;
81
+ return nitro.options.framework?.name === "nuxt";
82
+ }
83
+ /**
84
+ * Get client utilities configuration (handles false case)
85
+ */
86
+ function getClientUtilsConfig(nitro) {
87
+ const clientUtilsConfig = nitro.options.graphql?.clientUtils;
88
+ if (clientUtilsConfig === false) return { enabled: false };
89
+ return clientUtilsConfig || {};
90
+ }
91
+ /**
92
+ * Check if SDK files should be generated (category-level check)
93
+ */
94
+ function shouldGenerateSDK(nitro) {
95
+ const sdkConfig = nitro.options.graphql?.sdk;
96
+ if (sdkConfig === false) return false;
97
+ if (sdkConfig && sdkConfig.enabled === false) return false;
98
+ return true;
99
+ }
100
+ /**
101
+ * Get SDK configuration (handles false case)
102
+ */
103
+ function getSdkConfig(nitro) {
104
+ const sdkConfig = nitro.options.graphql?.sdk;
105
+ if (sdkConfig === false) return { enabled: false };
106
+ return sdkConfig || {};
107
+ }
108
+ /**
109
+ * Check if type files should be generated (category-level check)
110
+ */
111
+ function shouldGenerateTypes(nitro) {
112
+ const typesConfig = nitro.options.graphql?.types;
113
+ if (typesConfig === false) return false;
114
+ if (typesConfig && typesConfig.enabled === false) return false;
115
+ return true;
116
+ }
117
+ /**
118
+ * Get types configuration (handles false case)
119
+ */
120
+ function getTypesConfig(nitro) {
121
+ const typesConfig = nitro.options.graphql?.types;
122
+ if (typesConfig === false) return { enabled: false };
123
+ return typesConfig || {};
124
+ }
125
+
126
+ //#endregion
127
+ export { getClientUtilsConfig, getDefaultPaths, getScaffoldConfig, getSdkConfig, getTypesConfig, replacePlaceholders, resolveFilePath, shouldGenerateClientUtils, shouldGenerateFile, shouldGenerateSDK, shouldGenerateScaffold, shouldGenerateTypes };
@@ -1,4 +1,6 @@
1
1
  import { downloadAndSaveSchema, generateClientTypes, generateExternalClientTypes, loadExternalSchema, loadGraphQLDocuments } from "./client-codegen.js";
2
+ import { writeFileIfNotExists } from "./file-generator.js";
3
+ import { getClientUtilsConfig, getDefaultPaths, getSdkConfig, getTypesConfig, resolveFilePath, shouldGenerateClientUtils, shouldGenerateTypes } from "./path-resolver.js";
2
4
  import { generateTypes } from "./server-codegen.js";
3
5
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
6
  import consola from "consola";
@@ -10,12 +12,16 @@ import { mergeTypeDefs } from "@graphql-tools/merge";
10
12
  import { printSchemaWithDirectives } from "@graphql-tools/utils";
11
13
 
12
14
  //#region src/utils/type-generation.ts
13
- function generateGraphQLIndexFile(clientDir, externalServices = []) {
14
- const indexPath = resolve(clientDir, "index.ts");
15
+ function generateGraphQLIndexFile(nitro, clientDir, externalServices = []) {
16
+ if (!shouldGenerateClientUtils(nitro)) return;
17
+ const placeholders = getDefaultPaths(nitro);
18
+ const clientUtilsConfig = getClientUtilsConfig(nitro);
19
+ const indexPath = resolveFilePath(clientUtilsConfig.index, clientUtilsConfig.enabled, true, "{clientGraphql}/index.ts", placeholders);
20
+ if (!indexPath) return;
15
21
  if (!existsSync(indexPath)) {
16
22
  let indexContent = `// This file is auto-generated once by nitro-graphql for quick start
17
23
  // You can modify this file according to your needs
18
- //
24
+ //
19
25
  // Export your main GraphQL service (auto-generated)
20
26
  export * from './default/ofetch'
21
27
 
@@ -24,14 +30,21 @@ export * from './default/ofetch'
24
30
  // export * from './yourServiceName/ofetch'
25
31
  `;
26
32
  for (const service of externalServices) indexContent += `export * from './${service.name}/ofetch'\n`;
27
- writeFileSync(indexPath, indexContent, "utf-8");
33
+ writeFileIfNotExists(indexPath, indexContent, "client index.ts");
28
34
  }
29
35
  }
30
- function generateNuxtOfetchClient(clientDir, serviceName = "default") {
31
- const serviceDir = resolve(clientDir, serviceName);
32
- const ofetchPath = resolve(serviceDir, "ofetch.ts");
36
+ function generateNuxtOfetchClient(nitro, clientDir, serviceName = "default") {
37
+ if (!shouldGenerateClientUtils(nitro)) return;
38
+ const placeholders = {
39
+ ...getDefaultPaths(nitro),
40
+ serviceName
41
+ };
42
+ const clientUtilsConfig = getClientUtilsConfig(nitro);
43
+ const ofetchPath = resolveFilePath(clientUtilsConfig.ofetch, clientUtilsConfig.enabled, true, "{clientGraphql}/{serviceName}/ofetch.ts", placeholders);
44
+ if (!ofetchPath) return;
45
+ const serviceDir = dirname(ofetchPath);
33
46
  if (!existsSync(serviceDir)) mkdirSync(serviceDir, { recursive: true });
34
- if (!existsSync(ofetchPath)) writeFileSync(ofetchPath, `// This file is auto-generated once by nitro-graphql for quick start
47
+ if (!existsSync(ofetchPath)) writeFileIfNotExists(ofetchPath, `// This file is auto-generated once by nitro-graphql for quick start
35
48
  // You can modify this file according to your needs
36
49
  import type { Requester } from './sdk'
37
50
  import { getSdk } from './sdk'
@@ -53,15 +66,23 @@ export function createGraphQLClient(endpoint: string): Requester {
53
66
  }
54
67
  }
55
68
 
56
- export const $sdk = getSdk(createGraphQLClient('/api/graphql'))`, "utf-8");
69
+ export const $sdk = getSdk(createGraphQLClient('/api/graphql'))`, `${serviceName} ofetch.ts`);
57
70
  }
58
- function generateExternalOfetchClient(clientDir, serviceName, endpoint) {
59
- const serviceDir = resolve(clientDir, serviceName);
60
- const ofetchPath = resolve(serviceDir, "ofetch.ts");
71
+ function generateExternalOfetchClient(nitro, service, endpoint) {
72
+ if (!shouldGenerateClientUtils(nitro)) return;
73
+ const serviceName = service.name;
74
+ const placeholders = {
75
+ ...getDefaultPaths(nitro),
76
+ serviceName
77
+ };
78
+ const clientUtilsConfig = getClientUtilsConfig(nitro);
79
+ const ofetchPath = resolveFilePath(service.paths?.ofetch ?? clientUtilsConfig.ofetch, clientUtilsConfig.enabled, true, "{clientGraphql}/{serviceName}/ofetch.ts", placeholders);
80
+ if (!ofetchPath) return;
81
+ const serviceDir = dirname(ofetchPath);
61
82
  if (!existsSync(serviceDir)) mkdirSync(serviceDir, { recursive: true });
62
83
  if (!existsSync(ofetchPath)) {
63
84
  const capitalizedServiceName = serviceName.charAt(0).toUpperCase() + serviceName.slice(1);
64
- writeFileSync(ofetchPath, `// This file is auto-generated once by nitro-graphql for quick start
85
+ writeFileIfNotExists(ofetchPath, `// This file is auto-generated once by nitro-graphql for quick start
65
86
  // You can modify this file according to your needs
66
87
  import type { Sdk, Requester } from './sdk'
67
88
  import { getSdk } from './sdk'
@@ -83,7 +104,7 @@ export function create${capitalizedServiceName}GraphQLClient(endpoint: string =
83
104
  }
84
105
  }
85
106
 
86
- export const $${serviceName}Sdk: Sdk = getSdk(create${capitalizedServiceName}GraphQLClient())`, "utf-8");
107
+ export const $${serviceName}Sdk: Sdk = getSdk(create${capitalizedServiceName}GraphQLClient())`, `${serviceName} external ofetch.ts`);
87
108
  }
88
109
  }
89
110
  /**
@@ -178,6 +199,10 @@ function validateNoDuplicateTypes(schemas, schemaStrings) {
178
199
  }
179
200
  async function serverTypeGeneration(app) {
180
201
  try {
202
+ if (!shouldGenerateTypes(app)) {
203
+ consola.debug("[nitro-graphql] Server type generation is disabled");
204
+ return;
205
+ }
181
206
  const schemas = app.scanSchemas || [];
182
207
  if (!schemas.length) {
183
208
  consola.info("No GraphQL definitions found for server type generation.");
@@ -197,9 +222,14 @@ async function serverTypeGeneration(app) {
197
222
  const schemaPath = resolve(app.graphql.buildDir, "schema.graphql");
198
223
  mkdirSync(dirname(schemaPath), { recursive: true });
199
224
  writeFileSync(schemaPath, printSchema, "utf-8");
200
- const serverTypesPath = resolve(app.options.buildDir, "types", "nitro-graphql-server.d.ts");
201
- mkdirSync(dirname(serverTypesPath), { recursive: true });
202
- writeFileSync(serverTypesPath, data, "utf-8");
225
+ const placeholders = getDefaultPaths(app);
226
+ const typesConfig = getTypesConfig(app);
227
+ const serverTypesPath = resolveFilePath(typesConfig.server, typesConfig.enabled, true, "{typesDir}/nitro-graphql-server.d.ts", placeholders);
228
+ if (serverTypesPath) {
229
+ mkdirSync(dirname(serverTypesPath), { recursive: true });
230
+ writeFileSync(serverTypesPath, data, "utf-8");
231
+ consola.success(`[nitro-graphql] Generated server types at: ${serverTypesPath}`);
232
+ }
203
233
  } catch (error) {
204
234
  consola.error("Server schema generation error:", error);
205
235
  }
@@ -252,17 +282,25 @@ async function generateMainClientTypes(nitro) {
252
282
  const graphqlString = readFileSync(schemaFilePath, "utf-8");
253
283
  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 ?? {});
254
284
  if (types === false) return;
255
- const clientTypesPath = resolve(nitro.options.buildDir, "types", "nitro-graphql-client.d.ts");
256
- const defaultServiceDir = resolve(nitro.graphql.clientDir, "default");
257
- const sdkTypesPath = resolve(defaultServiceDir, "sdk.ts");
258
- mkdirSync(dirname(clientTypesPath), { recursive: true });
259
- writeFileSync(clientTypesPath, types.types, "utf-8");
260
- mkdirSync(defaultServiceDir, { recursive: true });
261
- writeFileSync(sdkTypesPath, types.sdk, "utf-8");
285
+ const placeholders = getDefaultPaths(nitro);
286
+ const typesConfig = getTypesConfig(nitro);
287
+ const sdkConfig = getSdkConfig(nitro);
288
+ const clientTypesPath = resolveFilePath(typesConfig.client, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client.d.ts", placeholders);
289
+ if (clientTypesPath) {
290
+ mkdirSync(dirname(clientTypesPath), { recursive: true });
291
+ writeFileSync(clientTypesPath, types.types, "utf-8");
292
+ consola.success(`[nitro-graphql] Generated client types at: ${clientTypesPath}`);
293
+ }
294
+ const sdkPath = resolveFilePath(sdkConfig.main, sdkConfig.enabled, true, "{clientGraphql}/default/sdk.ts", placeholders);
295
+ if (sdkPath) {
296
+ mkdirSync(dirname(sdkPath), { recursive: true });
297
+ writeFileSync(sdkPath, types.sdk, "utf-8");
298
+ consola.success(`[nitro-graphql] Generated SDK at: ${sdkPath}`);
299
+ }
262
300
  if (nitro.options.framework?.name === "nuxt") {
263
- generateNuxtOfetchClient(nitro.graphql.clientDir, "default");
301
+ generateNuxtOfetchClient(nitro, nitro.graphql.clientDir, "default");
264
302
  const externalServices = nitro.options.graphql?.externalServices || [];
265
- generateGraphQLIndexFile(nitro.graphql.clientDir, externalServices);
303
+ generateGraphQLIndexFile(nitro, nitro.graphql.clientDir, externalServices);
266
304
  }
267
305
  }
268
306
  async function generateExternalServicesTypes(nitro) {
@@ -292,14 +330,25 @@ async function generateExternalServicesTypes(nitro) {
292
330
  consola.warn(`[graphql:${service.name}] Type generation failed`);
293
331
  continue;
294
332
  }
295
- const serviceTypesPath = resolve(nitro.options.buildDir, "types", `nitro-graphql-client-${service.name}.d.ts`);
296
- const serviceDir = resolve(nitro.graphql.clientDir, service.name);
297
- const serviceSdkPath = resolve(serviceDir, "sdk.ts");
298
- mkdirSync(dirname(serviceTypesPath), { recursive: true });
299
- writeFileSync(serviceTypesPath, types.types, "utf-8");
300
- mkdirSync(serviceDir, { recursive: true });
301
- writeFileSync(serviceSdkPath, types.sdk, "utf-8");
302
- if (nitro.options.framework?.name === "nuxt") generateExternalOfetchClient(nitro.graphql.clientDir, service.name, service.endpoint);
333
+ const placeholders = {
334
+ ...getDefaultPaths(nitro),
335
+ serviceName: service.name
336
+ };
337
+ const typesConfig = getTypesConfig(nitro);
338
+ const sdkConfig = getSdkConfig(nitro);
339
+ const serviceTypesPath = resolveFilePath(service.paths?.types ?? typesConfig.external, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client-{serviceName}.d.ts", placeholders);
340
+ if (serviceTypesPath) {
341
+ mkdirSync(dirname(serviceTypesPath), { recursive: true });
342
+ writeFileSync(serviceTypesPath, types.types, "utf-8");
343
+ consola.success(`[graphql:${service.name}] Generated types at: ${serviceTypesPath}`);
344
+ }
345
+ const serviceSdkPath = resolveFilePath(service.paths?.sdk ?? sdkConfig.external, sdkConfig.enabled, true, "{clientGraphql}/{serviceName}/sdk.ts", placeholders);
346
+ if (serviceSdkPath) {
347
+ mkdirSync(dirname(serviceSdkPath), { recursive: true });
348
+ writeFileSync(serviceSdkPath, types.sdk, "utf-8");
349
+ consola.success(`[graphql:${service.name}] Generated SDK at: ${serviceSdkPath}`);
350
+ }
351
+ if (nitro.options.framework?.name === "nuxt") generateExternalOfetchClient(nitro, service, service.endpoint);
303
352
  consola.success(`[graphql:${service.name}] External service types generated successfully`);
304
353
  } catch (error) {
305
354
  consola.error(`[graphql:${service.name}] External service generation failed:`, error);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nitro-graphql",
3
3
  "type": "module",
4
- "version": "1.5.0",
4
+ "version": "1.5.1",
5
5
  "description": "GraphQL integration for Nitro",
6
6
  "license": "MIT",
7
7
  "sideEffects": false,