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 +240 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +28 -20
- package/dist/routes/apollo-server.d.ts +2 -2
- package/dist/routes/debug.d.ts +2 -2
- package/dist/routes/health.d.ts +2 -2
- package/dist/types/index.d.ts +119 -1
- package/dist/utils/file-generator.d.ts +37 -0
- package/dist/utils/file-generator.js +72 -0
- package/dist/utils/path-resolver.d.ts +70 -0
- package/dist/utils/path-resolver.js +127 -0
- package/dist/utils/type-generation.js +83 -34
- package/package.json +1 -1
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
|
|
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 (
|
|
240
|
-
const
|
|
241
|
-
const
|
|
242
|
-
|
|
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
|
-
'${
|
|
252
|
+
'${relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.buildDir, "schema.graphql"))}',
|
|
250
253
|
],
|
|
251
254
|
documents: [
|
|
252
|
-
'${
|
|
255
|
+
'${relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.clientDir, "**/*.{graphql,js,ts,jsx,tsx}"))}',
|
|
253
256
|
],
|
|
254
257
|
},
|
|
255
258
|
},
|
|
256
|
-
}`, "
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
-
`, "
|
|
263
|
-
|
|
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
|
-
`, "
|
|
279
|
-
|
|
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
|
-
}`, "
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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
|
|
1
|
+
import * as h35 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/apollo-server.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h35.EventHandler<h35.EventHandlerRequest, Promise<any>>;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { _default as default };
|
package/dist/routes/debug.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
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:
|
|
13
|
+
declare const _default: h31.EventHandler<h31.EventHandlerRequest, Promise<string | {
|
|
14
14
|
timestamp: string;
|
|
15
15
|
environment: {
|
|
16
16
|
dev: any;
|
package/dist/routes/health.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h33 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/health.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h33.EventHandler<h33.EventHandlerRequest, Promise<{
|
|
5
5
|
status: string;
|
|
6
6
|
message: string;
|
|
7
7
|
timestamp: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
33
|
+
writeFileIfNotExists(indexPath, indexContent, "client index.ts");
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
|
-
function generateNuxtOfetchClient(clientDir, serviceName = "default") {
|
|
31
|
-
|
|
32
|
-
const
|
|
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))
|
|
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'))`,
|
|
69
|
+
export const $sdk = getSdk(createGraphQLClient('/api/graphql'))`, `${serviceName} ofetch.ts`);
|
|
57
70
|
}
|
|
58
|
-
function generateExternalOfetchClient(
|
|
59
|
-
|
|
60
|
-
const
|
|
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
|
-
|
|
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())`,
|
|
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
|
|
201
|
-
|
|
202
|
-
|
|
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
|
|
256
|
-
const
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (
|
|
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);
|