@stonecrop/nuxt-grafserv 0.7.8 → 0.7.9

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
@@ -48,25 +48,33 @@ yarn add @stonecrop/nuxt-grafserv postgraphile
48
48
  npm install @stonecrop/nuxt-grafserv postgraphile
49
49
  ```
50
50
 
51
- 2. Configure in `nuxt.config.ts`:
51
+ 2. Create your preset file `server/graphile.preset.ts`:
52
52
 
53
53
  ```ts
54
54
  import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
55
55
  import { makePgService } from 'postgraphile/adaptors/pg'
56
56
 
57
+ const preset = {
58
+ extends: [PostGraphileAmberPreset],
59
+ pgServices: [
60
+ makePgService({
61
+ connectionString: process.env.DATABASE_URL || 'postgresql://localhost/mydb',
62
+ schemas: ['public'],
63
+ }),
64
+ ],
65
+ }
66
+
67
+ export default preset
68
+ ```
69
+
70
+ 3. Configure in `nuxt.config.ts`:
71
+
72
+ ```ts
57
73
  export default defineNuxtConfig({
58
74
  modules: ['@stonecrop/nuxt-grafserv'],
59
75
  grafserv: {
60
76
  type: 'postgraphile', // Required: specify configuration type
61
- preset: {
62
- extends: [PostGraphileAmberPreset],
63
- pgServices: [
64
- makePgService({
65
- connectionString: process.env.DATABASE_URL || 'postgresql://localhost/mydb',
66
- schemas: ['public'],
67
- }),
68
- ],
69
- },
77
+ preset: './server/graphile.preset.ts', // Path to preset file
70
78
  url: '/graphql',
71
79
  graphiql: true,
72
80
  }
@@ -109,35 +117,45 @@ Use `type: 'postgraphile'` for PostGraphile-based GraphQL APIs:
109
117
  | Option | Type | Required | Description |
110
118
  |--------|------|----------|-------------|
111
119
  | `type` | `'postgraphile'` | ✅ | Configuration type discriminator |
112
- | `preset` | `GraphileConfig.Preset` | ✅ | PostGraphile preset passed to makeSchema() |
120
+ | `preset` | `string` | ✅ | Path to PostGraphile preset file (e.g., './server/graphile.preset.ts') |
113
121
  | `url` | `string` | ❌ | GraphQL endpoint URL (default: '/graphql/') |
114
122
  | `graphiql` | `boolean` | ❌ | Enable GraphiQL IDE (default: true in dev, false in prod) |
115
123
 
124
+ > **Important:** The preset must be a file path, not an inline object. See "Why File-Based Presets?" section below.
125
+
116
126
  **Example:**
117
127
 
118
128
  ```ts
119
- import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
120
- import { makePgService } from 'postgraphile/adaptors/pg'
121
-
129
+ // nuxt.config.ts
122
130
  export default defineNuxtConfig({
123
131
  grafserv: {
124
132
  type: 'postgraphile',
125
- preset: {
126
- extends: [PostGraphileAmberPreset],
127
- pgServices: [
128
- makePgService({
129
- connectionString: process.env.DATABASE_URL,
130
- schemas: ['public'],
131
- }),
132
- ],
133
- plugins: [MyCustomPlugin],
134
- },
133
+ preset: './server/graphile.preset.ts',
135
134
  url: '/graphql',
136
135
  graphiql: true,
137
136
  }
138
137
  })
139
138
  ```
140
139
 
140
+ ```ts
141
+ // server/graphile.preset.ts
142
+ import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
143
+ import { makePgService } from 'postgraphile/adaptors/pg'
144
+
145
+ const preset = {
146
+ extends: [PostGraphileAmberPreset],
147
+ pgServices: [
148
+ makePgService({
149
+ connectionString: process.env.DATABASE_URL,
150
+ schemas: ['public'],
151
+ }),
152
+ ],
153
+ plugins: [MyCustomPlugin],
154
+ }
155
+
156
+ export default preset
157
+ ```
158
+
141
159
  ### Schema Configuration
142
160
 
143
161
  Use `type: 'schema'` for custom GraphQL schemas with Grafast resolvers:
@@ -249,109 +267,47 @@ export default defineNuxtConfig({
249
267
 
250
268
  For database-backed GraphQL APIs:
251
269
 
252
- 1. Configure PostGraphile in `nuxt.config.ts`:
270
+ 1. Create your preset file `server/graphile.preset.ts`:
253
271
 
254
272
  ```ts
255
273
  import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
256
274
  import { makePgService } from 'postgraphile/adaptors/pg'
257
275
 
258
- export default defineNuxtConfig({
259
- modules: ['@stonecrop/nuxt-grafserv'],
260
- grafserv: {
261
- type: 'postgraphile',
262
- preset: {
263
- extends: [PostGraphileAmberPreset],
264
- pgServices: [
265
- makePgService({
266
- connectionString: process.env.DATABASE_URL,
267
- schemas: ['public'],
268
- }),
269
- ],
270
- },
271
- }
272
- })
273
- ```
274
-
275
- 2. That's it! PostGraphile automatically generates your GraphQL schema from your PostgreSQL database.
276
-
277
- ## Advanced Usage
278
-
279
- ## Advanced Usage
280
-
281
- ### Grafserv Middleware and Plugins
276
+ const preset = {
277
+ extends: [PostGraphileAmberPreset],
278
+ pgServices: [
279
+ makePgService({
280
+ connectionString: process.env.DATABASE_URL,
281
+ schemas: ['public'],
282
+ }),
283
+ ],
284
+ }
282
285
 
283
- For cross-cutting concerns like authentication, logging, or rate limiting, use Grafserv plugins through the preset configuration. This works for both PostGraphile and Schema configurations.
286
+ export default preset
287
+ ```
284
288
 
285
- #### Inline Plugin Configuration (PostGraphile)
289
+ 2. Configure PostGraphile in `nuxt.config.ts`:
286
290
 
287
291
  ```ts
288
- import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
289
- import { makePgService } from 'postgraphile/adaptors/pg'
290
-
291
292
  export default defineNuxtConfig({
293
+ modules: ['@stonecrop/nuxt-grafserv'],
292
294
  grafserv: {
293
295
  type: 'postgraphile',
294
- preset: {
295
- extends: [PostGraphileAmberPreset],
296
- pgServices: [makePgService({ /* ... */ })],
297
- plugins: [
298
- {
299
- name: 'request-logging',
300
- version: '1.0.0',
301
- grafserv: {
302
- middleware: {
303
- processGraphQLRequestBody: async (next, event) => {
304
- const start = Date.now()
305
- console.log('[GraphQL] Request started')
306
- const result = await next()
307
- console.log(`[GraphQL] Completed in ${Date.now() - start}ms`)
308
- return result
309
- }
310
- }
311
- }
312
- }
313
- ]
314
- }
296
+ preset: './server/graphile.preset.ts',
315
297
  }
316
298
  })
317
299
  ```
318
300
 
319
- #### Inline Plugin Configuration (Schema)
320
-
321
- ```ts
322
- export default defineNuxtConfig({
323
- grafserv: {
324
- type: 'schema',
325
- schema: 'server/**/*.graphql',
326
- resolvers: 'server/resolvers.ts',
327
- // Note: For Schema config, advanced plugin configuration should be done
328
- // through a preset configuration or custom schema provider
329
- }
330
- })
331
- ```
301
+ 3. That's it! PostGraphile automatically generates your GraphQL schema from your PostgreSQL database.
332
302
 
333
- #### Using External Plugin File
303
+ ## Advanced Usage
334
304
 
335
- ```ts
336
- // nuxt.config.ts
337
- import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
338
- import { makePgService } from 'postgraphile/adaptors/pg'
339
- import plugins from './server/plugins'
305
+ ### Custom Grafserv Plugins
340
306
 
341
- export default defineNuxtConfig({
342
- grafserv: {
343
- type: 'postgraphile',
344
- preset: {
345
- extends: [PostGraphileAmberPreset],
346
- pgServices: [makePgService({ /* ... */ })],
347
- plugins
348
- }
349
- }
350
- })
351
- ```
307
+ Add custom plugins for authentication, logging, or rate limiting through your preset file:
352
308
 
353
309
  ```ts
354
- // server/plugins.ts
310
+ // server/graphile/plugins.ts
355
311
  import type { GraphileConfig } from 'graphile-config'
356
312
 
357
313
  const loggingPlugin: GraphileConfig.Plugin = {
@@ -387,6 +343,23 @@ const authPlugin: GraphileConfig.Plugin = {
387
343
  export default [loggingPlugin, authPlugin]
388
344
  ```
389
345
 
346
+ Import the plugins in your preset:
347
+
348
+ ```ts
349
+ // server/graphile/graphile.preset.ts
350
+ import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
351
+ import { makePgService } from 'postgraphile/adaptors/pg'
352
+ import plugins from './plugins'
353
+
354
+ const preset = {
355
+ extends: [PostGraphileAmberPreset],
356
+ pgServices: [makePgService({ /* ... */ })],
357
+ plugins
358
+ }
359
+
360
+ export default preset
361
+ ```
362
+
390
363
  #### Available Middleware Hooks
391
364
 
392
365
  - `processRequest` - Process all incoming requests
@@ -396,149 +369,120 @@ export default [loggingPlugin, authPlugin]
396
369
 
397
370
  ## PostGraphile Integration
398
371
 
399
- This module has first-class support for PostGraphile v5 using the preset configuration pattern. PostGraphile automatically generates your complete GraphQL schema and resolvers from your PostgreSQL database.
400
-
401
- ### Prerequisites
372
+ PostGraphile v5+ automatically generates your GraphQL schema from PostgreSQL.
402
373
 
403
- ```bash
404
- pnpm add postgraphile
405
- ```
406
-
407
- ### Basic PostGraphile Setup
374
+ ### With Community Plugins
408
375
 
409
376
  ```typescript
410
- // nuxt.config.ts
411
377
  import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
412
378
  import { makePgService } from 'postgraphile/adaptors/pg'
379
+ import PgSimplifyInflectorPlugin from '@graphile-contrib/pg-simplify-inflector'
413
380
 
414
- export default defineNuxtConfig({
415
- modules: ['@stonecrop/nuxt-grafserv'],
416
- grafserv: {
417
- type: 'postgraphile',
418
- preset: {
419
- extends: [PostGraphileAmberPreset],
420
- pgServices: [
421
- makePgService({
422
- connectionString: process.env.DATABASE_URL || 'postgresql://localhost/mydb',
423
- schemas: ['public'],
424
- }),
425
- ],
426
- },
427
- url: '/graphql',
428
- graphiql: true,
429
- }
430
- })
431
- ```
381
+ const preset = {
382
+ extends: [PostGraphileAmberPreset],
383
+ plugins: [PgSimplifyInflectorPlugin],
384
+ pgServices: [
385
+ makePgService({
386
+ connectionString: process.env.DATABASE_URL,
387
+ schemas: ['public'],
388
+ }),
389
+ ],
390
+ schema: {
391
+ defaultBehavior: 'connection', // Enable Relay-style connections
392
+ },
393
+ grafast: {
394
+ explain: process.env.NODE_ENV === 'development', // Plan diagrams in dev
395
+ },
396
+ }
432
397
 
433
- ### PostGraphile with Custom Plugins
398
+ export default preset
399
+ ```
434
400
 
435
- Enhance your PostGraphile setup with community plugins:
401
+ ### Advanced Configuration
436
402
 
437
403
  ```typescript
438
- // nuxt.config.ts
439
404
  import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
440
405
  import { makePgService } from 'postgraphile/adaptors/pg'
441
- import PgSimplifyInflectorPlugin from '@graphile-contrib/pg-simplify-inflector'
442
406
 
443
- export default defineNuxtConfig({
444
- grafserv: {
445
- type: 'postgraphile',
446
- preset: {
447
- extends: [PostGraphileAmberPreset],
448
- plugins: [PgSimplifyInflectorPlugin],
449
- pgServices: [
450
- makePgService({
451
- connectionString: process.env.DATABASE_URL,
452
- schemas: ['public'],
453
- }),
454
- ],
455
- schema: {
456
- defaultBehavior: 'connection', // Enable Relay-style connections
457
- },
458
- grafast: {
459
- explain: process.env.NODE_ENV === 'development', // Plan diagrams in dev
460
- },
461
- },
462
- }
463
- })
407
+ const preset = {
408
+ extends: [PostGraphileAmberPreset],
409
+ pgServices: [
410
+ makePgService({
411
+ connectionString: process.env.DATABASE_URL,
412
+ schemas: ['public', 'app_private'],
413
+ superuserConnectionString: process.env.SUPERUSER_DATABASE_URL, // For watch mode
414
+ pubsub: true, // Enable LISTEN/NOTIFY for subscriptions
415
+ }),
416
+ ],
417
+ gather: {
418
+ // Smart tags for schema customization
419
+ pgJwtTypes: 'app_public.jwt_token',
420
+ },
421
+ schema: {
422
+ // Behavior overrides
423
+ defaultBehavior: '-insert -update -delete', // Read-only by default
424
+ pgJwtSecret: process.env.JWT_SECRET,
425
+ },
426
+ grafast: {
427
+ explain: true,
428
+ context: (requestContext) => ({
429
+ // Custom context for all resolvers
430
+ userId: requestContext.user?.id,
431
+ }),
432
+ },
433
+ }
434
+
435
+ export default preset
464
436
  ```
465
437
 
466
- ### Advanced PostGraphile Configuration
438
+ ### Why File-Based Presets?
467
439
 
468
- ```typescript
469
- import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
470
- import { makePgService } from 'postgraphile/adaptors/pg'
440
+ PostGraphile presets must be in separate files, not inline in `nuxt.config.ts`.
471
441
 
472
- export default defineNuxtConfig({
473
- grafserv: {
474
- type: 'postgraphile',
475
- preset: {
476
- extends: [PostGraphileAmberPreset],
477
- pgServices: [
478
- makePgService({
479
- connectionString: process.env.DATABASE_URL,
480
- schemas: ['public', 'app_private'],
481
- superuserConnectionString: process.env.SUPERUSER_DATABASE_URL, // For watch mode
482
- pubsub: true, // Enable LISTEN/NOTIFY for subscriptions
483
- }),
484
- ],
485
- gather: {
486
- // Smart tags for schema customization
487
- pgJwtTypes: 'app_public.jwt_token',
488
- },
489
- schema: {
490
- // Behavior overrides
491
- defaultBehavior: '-insert -update -delete', // Read-only by default
492
- pgJwtSecret: process.env.JWT_SECRET,
493
- },
494
- grafast: {
495
- explain: true,
496
- context: (requestContext) => ({
497
- // Custom context for all resolvers
498
- userId: requestContext.user?.id,
499
- }),
500
- },
501
- },
502
- }
503
- })
504
- ```
442
+ The module uses PostGraphile's [instance-based approach](https://postgraphile.org/postgraphile/next/usage-library):
505
443
 
506
- ### Benefits of PostGraphile Integration
444
+ 1. At build time, the preset file is imported and a PostGraphile instance is created
445
+ 2. The instance is exposed via Nitro's virtual module system
446
+ 3. At runtime, handlers call `pgl.getSchema()` to get the schema
507
447
 
508
- - **Zero Schema Definition**: Automatically generates GraphQL schema from PostgreSQL
509
- - **Auto-Generated Resolvers**: All queries, mutations, and subscriptions from database
510
- - **Real-time Subscriptions**: Live queries via PostgreSQL LISTEN/NOTIFY
511
- - **Row-Level Security**: Leverages PostgreSQL RLS for fine-grained authorization
512
- - **High Performance**: Grafast execution engine with intelligent query planning
513
- - **Type Safety**: Full TypeScript support for generated schema
514
- - **Plugin Ecosystem**: Rich collection of community plugins for extended functionality
448
+ This approach avoids GraphQL module duplication, follows PostGraphile's recommended pattern, supports watch mode, and properly handles database connections.
515
449
 
516
- ### Accessing Grafserv Instance
450
+ **Your preset file needs a default export:**
517
451
 
518
- For advanced use cases, you can access the grafserv instance directly in server routes:
452
+ ```typescript
453
+ import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
519
454
 
520
- ```ts
521
- // server/api/custom.ts
522
- import { getGrafservInstance } from '@stonecrop/nuxt-grafserv/runtime/handler'
523
- import { useRuntimeConfig } from '#imports'
455
+ const preset = {
456
+ extends: [PostGraphileAmberPreset],
457
+ // ...
458
+ }
524
459
 
525
- export default defineEventHandler(async (event) => {
526
- const config = useRuntimeConfig()
527
- const serv = await getGrafservInstance(config.grafserv)
460
+ export default preset
461
+ ```
528
462
 
529
- // Access grafserv methods
530
- // Note: serv contains the grafserv instance with your schema
463
+ **Import Requirements:**
531
464
 
532
- return {
533
- status: 'GraphQL server is running',
534
- endpoint: config.grafserv.url
535
- }
536
- })
465
+ Relative imports in preset files work with file extensions:
466
+
467
+ ```typescript
468
+ // server/graphile/graphile.preset.ts
469
+ import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
470
+ import { makePgService } from 'postgraphile/adaptors/pg'
471
+ import { MyPlugin } from './plugins/my-plugin'
472
+ import { AnotherPlugin } from './plugins/another'
473
+
474
+ const preset = {
475
+ extends: [PostGraphileAmberPreset],
476
+ pgServices: [makePgService({/*...*/})],
477
+ plugins: [MyPlugin, AnotherPlugin],
478
+ }
479
+
480
+ export default preset
537
481
  ```
538
482
 
539
- ### Schema Building with Objects Structure
483
+ ### Schema Building with Grafast
540
484
 
541
- The module uses Grafast's modern objects structure for better type safety and performance. Leverage Grafast's standard steps for common operations:
485
+ Grafast uses a step-based execution model. Common patterns:
542
486
 
543
487
  ```typescript
544
488
  import { constant, lambda, access, object, filter, type GrafastSchemaConfig } from 'grafast'
@@ -621,26 +565,15 @@ export default resolvers
621
565
  ```
622
566
 
623
567
  **Key Concepts:**
624
- - All resolvers return **steps** (constant, lambda, access, object, filter, etc.), not plain values
625
- - Arguments are accessed via `fieldArgs.$argumentName` (note the `$` prefix)
626
- - Use `constant()` for static values
627
- - Use `lambda()` to transform step values at execution time
628
- - Use `access()` to extract object properties (more efficient than lambda for simple property access)
629
- - Use `object()` to compose objects from multiple steps
630
- - Use `filter()` for list filtering operations
631
- - Source objects (`$source`, `$user`, `$order`, etc.) are also steps that need `lambda()` or `access()` to work with their properties
632
-
633
- **Standard Steps Reference:**
634
- - `constant()` - Create a step from a static value
635
- - `lambda()` - Transform step values with execution-time callbacks
636
- - `access()` - Extract properties from object steps
637
- - `object()` - Compose objects from multiple steps
638
- - `filter()` - Filter list steps based on conditions
639
- - `list()` - Create lists from step tuples
640
- - `first()`/`last()` - Get first/last elements from lists
641
- - `loadOne()`/`loadMany()` - Batch data loading (DataLoader-style)
642
-
643
- For the complete list, see [Grafast Standard Steps](https://grafast.org/grafast/standard-steps)
568
+ - Resolvers return **steps** (constant, lambda, access, object, filter), not plain values
569
+ - Arguments are accessed via `fieldArgs.$argumentName`
570
+ - `constant()` - static values
571
+ - `lambda()` - transform step values at execution time
572
+ - `access()` - extract object properties efficiently
573
+ - `object()` - compose objects from steps
574
+ - `filter()` - filter list steps
575
+
576
+ See [Grafast Standard Steps](https://grafast.org/grafast/standard-steps) for the complete reference.
644
577
 
645
578
  ## Development
646
579
 
package/dist/module.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { NuxtModule } from '@nuxt/schema';
2
2
  import { GraphQLSchema } from 'graphql';
3
- import { GraphileConfig } from 'graphile-config';
4
3
 
5
4
  /**
6
5
  * Schema provider function - returns a GraphQL schema
@@ -10,27 +9,34 @@ type SchemaProvider = () => GraphQLSchema | Promise<GraphQLSchema>;
10
9
  * PostGraphile configuration using preset
11
10
  *
12
11
  * This is the recommended approach for PostGraphile integration.
13
- * The preset is passed to PostGraphile's makeSchema() function to generate the GraphQL schema.
12
+ * The preset file path is resolved and imported at runtime, then passed to PostGraphile's makeSchema() function.
13
+ *
14
+ * Note: Inline preset objects are not supported due to Nitro's build/runtime separation.
15
+ * Complex objects with extends arrays, plugins, and functions cannot be serialized across this boundary.
14
16
  *
15
17
  * @example
16
18
  * ```typescript
19
+ * // 1. Create server/graphile.preset.ts
17
20
  * import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
18
21
  * import { makePgService } from 'postgraphile/adaptors/pg'
19
22
  *
23
+ * export default {
24
+ * extends: [PostGraphileAmberPreset],
25
+ * pgServices: [
26
+ * makePgService({
27
+ * connectionString: process.env.DATABASE_URL,
28
+ * schemas: ['public'],
29
+ * }),
30
+ * ],
31
+ * plugins: [MyCustomPlugin],
32
+ * }
33
+ *
34
+ * // 2. Reference the preset file in nuxt.config.ts
20
35
  * export default defineNuxtConfig({
21
36
  * modules: ['@stonecrop/nuxt-grafserv'],
22
37
  * grafserv: {
23
38
  * type: 'postgraphile',
24
- * preset: {
25
- * extends: [PostGraphileAmberPreset],
26
- * pgServices: [
27
- * makePgService({
28
- * connectionString: process.env.DATABASE_URL,
29
- * schemas: ['public'],
30
- * }),
31
- * ],
32
- * plugins: [MyCustomPlugin],
33
- * },
39
+ * preset: './server/graphile.preset.ts',
34
40
  * url: '/graphql',
35
41
  * graphiql: true,
36
42
  * },
@@ -40,8 +46,18 @@ type SchemaProvider = () => GraphQLSchema | Promise<GraphQLSchema>;
40
46
  interface PostGraphileConfig {
41
47
  /** Configuration type discriminator */
42
48
  type: 'postgraphile';
43
- /** PostGraphile preset configuration - passed to makeSchema() */
44
- preset: GraphileConfig.Preset;
49
+ /**
50
+ * Path to PostGraphile preset file
51
+ *
52
+ * The preset file must export the preset configuration using default export:
53
+ * `export default { extends: [...], pgServices: [...], plugins: [...] }`
54
+ *
55
+ * A PostGraphile instance will be created from this preset at build time.
56
+ *
57
+ * @example './server/graphile.preset.ts'
58
+ * @example './server/graphile.preset.js'
59
+ */
60
+ preset: string;
45
61
  /** GraphQL endpoint URL (default: '/graphql/') */
46
62
  url?: string;
47
63
  /** Whether to enable GraphiQL IDE (default: true in dev, false in prod) */
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stonecrop/nuxt-grafserv",
3
3
  "configKey": "grafserv",
4
- "version": "0.7.8",
4
+ "version": "0.7.9",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -1,6 +1,7 @@
1
- import { join } from 'node:path';
1
+ import { existsSync } from 'node:fs';
2
2
  import { createRequire } from 'node:module';
3
- import { useLogger, defineNuxtModule, createResolver, addTemplate } from '@nuxt/kit';
3
+ import { join } from 'node:path';
4
+ import { useLogger, defineNuxtModule, createResolver } from '@nuxt/kit';
4
5
 
5
6
  const logger = useLogger("@stonecrop/nuxt-grafserv");
6
7
  function validateConfig(options) {
@@ -77,19 +78,53 @@ const module$1 = defineNuxtModule({
77
78
  logger.info(`Grafserv server alias: ${config.alias["#grafserv-server"]}`);
78
79
  if (options.type === "postgraphile") {
79
80
  logger.info("Using PostGraphile preset configuration");
80
- const template = addTemplate({
81
- filename: "grafserv-preset.mjs",
82
- write: true,
83
- getContents: () => {
84
- return `export const preset = ${JSON.stringify(options.preset, null, 2)}`;
81
+ let presetPath = resolveForVirtualModule(options.preset);
82
+ if (!existsSync(presetPath)) {
83
+ const extensions = [".ts", ".js", ".mjs"];
84
+ let found = false;
85
+ for (const ext of extensions) {
86
+ const pathWithExt = presetPath + ext;
87
+ if (existsSync(pathWithExt)) {
88
+ presetPath = pathWithExt;
89
+ found = true;
90
+ break;
91
+ }
85
92
  }
86
- });
93
+ if (!found) {
94
+ throw new Error(
95
+ `[@stonecrop/nuxt-grafserv] Preset file not found: ${presetPath}
96
+ Tried extensions: ${extensions.join(", ")}
97
+
98
+ Create the preset file with your PostGraphile configuration:
99
+
100
+ // ${options.preset}.ts (or .js, .mjs)
101
+ import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
102
+ import { makePgService } from 'postgraphile/adaptors/pg'
103
+
104
+ export default {
105
+ extends: [PostGraphileAmberPreset],
106
+ pgServices: [makePgService({ connectionString: process.env.DATABASE_URL, schemas: ['public'] })],
107
+ plugins: [],
108
+ }
109
+ `
110
+ );
111
+ }
112
+ }
113
+ logger.info(`Resolved preset path: ${presetPath}`);
114
+ config.virtual = config.virtual || {};
115
+ config.virtual["#internal/grafserv/pgl"] = [
116
+ `import { postgraphile } from 'postgraphile'`,
117
+ `import preset from '${presetPath}'`,
118
+ ``,
119
+ `// Create PostGraphile instance with the preset`,
120
+ `// This handles schema building, watch mode, and lifecycle`,
121
+ `export const pgl = postgraphile(preset)`
122
+ ].join("\n");
87
123
  config.runtimeConfig = config.runtimeConfig || {};
88
124
  config.runtimeConfig.grafserv = {
89
125
  type: "postgraphile",
90
126
  url: options.url || "/graphql/",
91
- graphiql: options.graphiql,
92
- presetPath: template.dst
127
+ graphiql: options.graphiql
93
128
  };
94
129
  } else if (options.type === "schema") {
95
130
  logger.info("Using schema configuration");
@@ -128,7 +163,11 @@ const module$1 = defineNuxtModule({
128
163
  config.externals = config.externals || {};
129
164
  config.externals.external = config.externals.external || [];
130
165
  config.externals.external.push(
166
+ "graphql",
131
167
  "grafast",
168
+ "postgraphile",
169
+ "graphile-config",
170
+ "graphile-build",
132
171
  "@graphql-tools/schema",
133
172
  "@graphql-tools/load",
134
173
  "@graphql-tools/graphql-file-loader"
@@ -136,6 +175,11 @@ const module$1 = defineNuxtModule({
136
175
  const grafastPath = require.resolve("grafast");
137
176
  config.alias = config.alias || {};
138
177
  config.alias["grafast"] = grafastPath;
178
+ config.typescript = config.typescript || {};
179
+ config.typescript.tsConfig = config.typescript.tsConfig || {};
180
+ config.typescript.tsConfig.compilerOptions = config.typescript.tsConfig.compilerOptions || {};
181
+ config.typescript.tsConfig.compilerOptions.allowImportingTsExtensions = true;
182
+ config.typescript.tsConfig.compilerOptions.moduleResolution = "bundler";
139
183
  });
140
184
  nuxt.hook("nitro:config", (config) => {
141
185
  config.handlers = config.handlers || [];
@@ -170,7 +214,8 @@ const module$1 = defineNuxtModule({
170
214
  nuxt.hook("builder:watch", async (event, path) => {
171
215
  const isSchemaFile = path.endsWith(".graphql");
172
216
  const isResolverFile = options.type === "schema" && options.resolvers && path.includes(options.resolvers.replace("./", ""));
173
- if (isSchemaFile || isResolverFile) {
217
+ const isPresetFile = options.type === "postgraphile" && path.includes(options.preset.replace("./", ""));
218
+ if (isSchemaFile || isResolverFile || isPresetFile) {
174
219
  if (!cacheClearing) {
175
220
  cacheClearing = true;
176
221
  try {
@@ -19,25 +19,19 @@ async function getSchema(options) {
19
19
  }
20
20
  let schema;
21
21
  if (options.type === "postgraphile") {
22
- console.debug("[@stonecrop/nuxt-grafserv] Creating schema from PostGraphile preset");
22
+ console.debug("[@stonecrop/nuxt-grafserv] Getting schema from PostGraphile instance");
23
23
  try {
24
- const { makeSchema } = await import("postgraphile");
25
- const config = useRuntimeConfig();
26
- if (config.grafserv.type !== "postgraphile") {
27
- throw new Error("Expected PostGraphile configuration");
28
- }
29
- const presetModule = await import(config.grafserv.presetPath);
30
- const preset = presetModule.preset;
31
- const result = await makeSchema(preset);
32
- schema = result.schema;
33
- console.debug("[@stonecrop/nuxt-grafserv] PostGraphile schema created successfully");
24
+ const { pgl } = await import("#internal/grafserv/pgl");
25
+ console.debug("[@stonecrop/nuxt-grafserv] Calling pgl.getSchema()");
26
+ schema = await pgl.getSchema();
27
+ console.debug("[@stonecrop/nuxt-grafserv] PostGraphile schema retrieved successfully");
34
28
  } catch (error) {
35
29
  if (error instanceof Error && "code" in error && error.code === "MODULE_NOT_FOUND") {
36
30
  throw new Error(
37
31
  '[@stonecrop/nuxt-grafserv] PostGraphile preset provided but "postgraphile" package not found. Install it with: npm install postgraphile'
38
32
  );
39
33
  }
40
- console.error("[@stonecrop/nuxt-grafserv] Error creating PostGraphile schema:", error);
34
+ console.error("[@stonecrop/nuxt-grafserv] Error getting PostGraphile schema:", error);
41
35
  throw error;
42
36
  }
43
37
  } else if (options.type === "schema") {
@@ -80,7 +74,9 @@ async function getSchema(options) {
80
74
  }
81
75
  }
82
76
  } else {
83
- throw new Error(`[@stonecrop/nuxt-grafserv] Invalid configuration type: ${options.type}`);
77
+ throw new Error(
78
+ `[@stonecrop/nuxt-grafserv] Invalid configuration type: ${options.type}`
79
+ );
84
80
  }
85
81
  cachedSchema = schema;
86
82
  return schema;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stonecrop/nuxt-grafserv",
3
- "version": "0.7.8",
3
+ "version": "0.7.9",
4
4
  "description": "Pluggable Grafserv GraphQL server as Nuxt Module",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -43,7 +43,7 @@
43
43
  "grafast": "^1.0.0-rc.4",
44
44
  "grafserv": "^1.0.0-rc.4",
45
45
  "graphql": "^16.12.0",
46
- "@stonecrop/graphql-middleware": "0.7.8"
46
+ "@stonecrop/graphql-middleware": "0.7.9"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@eslint/js": "^9.39.2",