@stonecrop/nuxt-grafserv 0.7.6 → 0.7.8
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 +284 -161
- package/dist/module.d.mts +93 -16
- package/dist/module.json +1 -1
- package/dist/module.mjs +96 -46
- package/dist/runtime/handler.js +54 -49
- package/dist/types.d.mts +1 -1
- package/package.json +13 -9
package/README.md
CHANGED
|
@@ -31,79 +31,169 @@ The module automatically registers these handlers:
|
|
|
31
31
|
|
|
32
32
|
## Quick Setup
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
### PostGraphile Integration (Recommended)
|
|
35
|
+
|
|
36
|
+
For PostGraphile users, this is the recommended configuration approach:
|
|
37
|
+
|
|
38
|
+
1. Add dependencies:
|
|
35
39
|
|
|
36
40
|
```bash
|
|
37
41
|
# Using pnpm
|
|
38
|
-
pnpm add @stonecrop/nuxt-grafserv
|
|
42
|
+
pnpm add @stonecrop/nuxt-grafserv postgraphile
|
|
39
43
|
|
|
40
44
|
# Using yarn
|
|
41
|
-
yarn add @stonecrop/nuxt-grafserv
|
|
45
|
+
yarn add @stonecrop/nuxt-grafserv postgraphile
|
|
42
46
|
|
|
43
47
|
# Using npm
|
|
44
|
-
npm install @stonecrop/nuxt-grafserv
|
|
48
|
+
npm install @stonecrop/nuxt-grafserv postgraphile
|
|
45
49
|
```
|
|
46
50
|
|
|
47
|
-
2.
|
|
51
|
+
2. Configure in `nuxt.config.ts`:
|
|
48
52
|
|
|
49
53
|
```ts
|
|
54
|
+
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
55
|
+
import { makePgService } from 'postgraphile/adaptors/pg'
|
|
56
|
+
|
|
50
57
|
export default defineNuxtConfig({
|
|
51
58
|
modules: ['@stonecrop/nuxt-grafserv'],
|
|
52
59
|
grafserv: {
|
|
60
|
+
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
|
+
},
|
|
70
|
+
url: '/graphql',
|
|
71
|
+
graphiql: true,
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Custom Schema Configuration
|
|
77
|
+
|
|
78
|
+
For custom GraphQL schemas with your own resolvers:
|
|
79
|
+
|
|
80
|
+
1. Add dependency:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pnpm add @stonecrop/nuxt-grafserv
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
2. Configure in `nuxt.config.ts`:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
export default defineNuxtConfig({
|
|
90
|
+
modules: ['@stonecrop/nuxt-grafserv'],
|
|
91
|
+
grafserv: {
|
|
92
|
+
type: 'schema', // Required: specify configuration type
|
|
53
93
|
schema: 'server/**/*.graphql',
|
|
54
94
|
resolvers: 'server/resolvers.ts',
|
|
55
|
-
url: '/graphql
|
|
95
|
+
url: '/graphql',
|
|
96
|
+
graphiql: true,
|
|
56
97
|
}
|
|
57
98
|
})
|
|
58
99
|
```
|
|
59
100
|
|
|
60
101
|
## Configuration
|
|
61
102
|
|
|
62
|
-
|
|
103
|
+
The module supports two configuration types using a discriminated union pattern:
|
|
104
|
+
|
|
105
|
+
### PostGraphile Configuration
|
|
63
106
|
|
|
64
|
-
|
|
65
|
-
|--------|------|---------|-------------|
|
|
66
|
-
| `schema` | `string \| string[] \| SchemaProvider \| PostGraphileInstance` | `'server/**/*.graphql'` | Path(s) to GraphQL schema files, schema provider function, or PostGraphile instance |
|
|
67
|
-
| `resolvers` | `string` | `undefined` | Path to resolvers file (optional - not needed for PostGraphile) |
|
|
68
|
-
| `url` | `string` | `'/graphql/'` | GraphQL endpoint URL (also serves Ruru UI) |
|
|
69
|
-
| `graphiql` | `boolean` | `true` in dev, `false` in prod | Enable GraphiQL IDE |
|
|
70
|
-
| `preset` | `GraphileConfig.Preset` | `undefined` | Custom Graphile preset for advanced configuration |
|
|
107
|
+
Use `type: 'postgraphile'` for PostGraphile-based GraphQL APIs:
|
|
71
108
|
|
|
72
|
-
|
|
109
|
+
| Option | Type | Required | Description |
|
|
110
|
+
|--------|------|----------|-------------|
|
|
111
|
+
| `type` | `'postgraphile'` | ✅ | Configuration type discriminator |
|
|
112
|
+
| `preset` | `GraphileConfig.Preset` | ✅ | PostGraphile preset passed to makeSchema() |
|
|
113
|
+
| `url` | `string` | ❌ | GraphQL endpoint URL (default: '/graphql/') |
|
|
114
|
+
| `graphiql` | `boolean` | ❌ | Enable GraphiQL IDE (default: true in dev, false in prod) |
|
|
115
|
+
|
|
116
|
+
**Example:**
|
|
73
117
|
|
|
74
118
|
```ts
|
|
119
|
+
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
120
|
+
import { makePgService } from 'postgraphile/adaptors/pg'
|
|
121
|
+
|
|
75
122
|
export default defineNuxtConfig({
|
|
76
|
-
modules: ['@stonecrop/nuxt-grafserv'],
|
|
77
123
|
grafserv: {
|
|
78
|
-
|
|
124
|
+
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
|
+
},
|
|
135
|
+
url: '/graphql',
|
|
136
|
+
graphiql: true,
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Schema Configuration
|
|
142
|
+
|
|
143
|
+
Use `type: 'schema'` for custom GraphQL schemas with Grafast resolvers:
|
|
144
|
+
|
|
145
|
+
| Option | Type | Required | Description |
|
|
146
|
+
|--------|------|----------|-------------|
|
|
147
|
+
| `type` | `'schema'` | ✅ | Configuration type discriminator |
|
|
148
|
+
| `schema` | `string \| string[] \| SchemaProvider` | ✅ | Path(s) to .graphql files or schema provider function |
|
|
149
|
+
| `resolvers` | `string` | ❌ | Path to resolvers file (required for .graphql files) |
|
|
150
|
+
| `url` | `string` | ❌ | GraphQL endpoint URL (default: '/graphql/') |
|
|
151
|
+
| `graphiql` | `boolean` | ❌ | Enable GraphiQL IDE (default: true in dev, false in prod) |
|
|
152
|
+
|
|
153
|
+
**Example with files:**
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
export default defineNuxtConfig({
|
|
157
|
+
grafserv: {
|
|
158
|
+
type: 'schema',
|
|
79
159
|
schema: 'server/**/*.graphql',
|
|
80
160
|
resolvers: 'server/resolvers.ts',
|
|
161
|
+
url: '/graphql',
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
```
|
|
81
165
|
|
|
82
|
-
|
|
83
|
-
url: '/graphql/', // Serves both GraphQL API and Ruru UI
|
|
84
|
-
graphiql: true,
|
|
166
|
+
**Example with schema provider function:**
|
|
85
167
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
'application/json',
|
|
94
|
-
'application/graphql+json'
|
|
95
|
-
]
|
|
96
|
-
},
|
|
97
|
-
grafast: {
|
|
98
|
-
explain: true, // Enable plan diagrams
|
|
99
|
-
}
|
|
168
|
+
```ts
|
|
169
|
+
export default defineNuxtConfig({
|
|
170
|
+
grafserv: {
|
|
171
|
+
type: 'schema',
|
|
172
|
+
schema: async () => {
|
|
173
|
+
// Return a GraphQLSchema instance
|
|
174
|
+
return myCustomSchema
|
|
100
175
|
},
|
|
101
176
|
}
|
|
102
177
|
})
|
|
103
178
|
```
|
|
104
179
|
|
|
180
|
+
### Configuration Comparison
|
|
181
|
+
|
|
182
|
+
| Feature | PostGraphile Config | Schema Config |
|
|
183
|
+
|---------|---------------------|---------------|
|
|
184
|
+
| Type discriminator | `type: 'postgraphile'` | `type: 'schema'` |
|
|
185
|
+
| Schema source | Generated from preset | Files or function |
|
|
186
|
+
| Resolvers | Auto-generated by PostGraphile | Must provide via resolvers file |
|
|
187
|
+
| Primary use case | PostgreSQL-backed APIs | Custom GraphQL APIs |
|
|
188
|
+
| Setup complexity | Minimal (DB connection only) | Moderate (schema + resolvers) |
|
|
189
|
+
| Plugin system | PostGraphile plugins | Grafast standard steps |
|
|
190
|
+
|
|
105
191
|
## Basic Usage
|
|
106
192
|
|
|
193
|
+
### Schema Configuration Example
|
|
194
|
+
|
|
195
|
+
For custom schemas with resolvers:
|
|
196
|
+
|
|
107
197
|
1. Create your GraphQL schema (`server/schema.graphql`):
|
|
108
198
|
|
|
109
199
|
```graphql
|
|
@@ -120,7 +210,7 @@ type Mutation {
|
|
|
120
210
|
2. Create your resolvers (`server/resolvers.ts`):
|
|
121
211
|
|
|
122
212
|
```typescript
|
|
123
|
-
import { constant, lambda,
|
|
213
|
+
import { constant, lambda, type GrafastSchemaConfig } from 'grafast'
|
|
124
214
|
|
|
125
215
|
const resolvers: GrafastSchemaConfig['objects'] = {
|
|
126
216
|
Query: {
|
|
@@ -142,18 +232,68 @@ const resolvers: GrafastSchemaConfig['objects'] = {
|
|
|
142
232
|
export default resolvers
|
|
143
233
|
```
|
|
144
234
|
|
|
235
|
+
3. Configure Nuxt:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
export default defineNuxtConfig({
|
|
239
|
+
modules: ['@stonecrop/nuxt-grafserv'],
|
|
240
|
+
grafserv: {
|
|
241
|
+
type: 'schema',
|
|
242
|
+
schema: 'server/schema.graphql',
|
|
243
|
+
resolvers: 'server/resolvers.ts',
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### PostGraphile Configuration Example
|
|
249
|
+
|
|
250
|
+
For database-backed GraphQL APIs:
|
|
251
|
+
|
|
252
|
+
1. Configure PostGraphile in `nuxt.config.ts`:
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
256
|
+
import { makePgService } from 'postgraphile/adaptors/pg'
|
|
257
|
+
|
|
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
|
+
|
|
145
279
|
## Advanced Usage
|
|
146
280
|
|
|
147
|
-
### Middleware
|
|
281
|
+
### Grafserv Middleware and Plugins
|
|
148
282
|
|
|
149
|
-
For
|
|
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.
|
|
150
284
|
|
|
151
|
-
#### Inline Plugin Configuration
|
|
285
|
+
#### Inline Plugin Configuration (PostGraphile)
|
|
152
286
|
|
|
153
287
|
```ts
|
|
288
|
+
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
289
|
+
import { makePgService } from 'postgraphile/adaptors/pg'
|
|
290
|
+
|
|
154
291
|
export default defineNuxtConfig({
|
|
155
292
|
grafserv: {
|
|
293
|
+
type: 'postgraphile',
|
|
156
294
|
preset: {
|
|
295
|
+
extends: [PostGraphileAmberPreset],
|
|
296
|
+
pgServices: [makePgService({ /* ... */ })],
|
|
157
297
|
plugins: [
|
|
158
298
|
{
|
|
159
299
|
name: 'request-logging',
|
|
@@ -163,9 +303,7 @@ export default defineNuxtConfig({
|
|
|
163
303
|
processGraphQLRequestBody: async (next, event) => {
|
|
164
304
|
const start = Date.now()
|
|
165
305
|
console.log('[GraphQL] Request started')
|
|
166
|
-
|
|
167
306
|
const result = await next()
|
|
168
|
-
|
|
169
307
|
console.log(`[GraphQL] Completed in ${Date.now() - start}ms`)
|
|
170
308
|
return result
|
|
171
309
|
}
|
|
@@ -178,17 +316,34 @@ export default defineNuxtConfig({
|
|
|
178
316
|
})
|
|
179
317
|
```
|
|
180
318
|
|
|
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
|
+
```
|
|
332
|
+
|
|
181
333
|
#### Using External Plugin File
|
|
182
334
|
|
|
183
335
|
```ts
|
|
184
336
|
// nuxt.config.ts
|
|
337
|
+
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
338
|
+
import { makePgService } from 'postgraphile/adaptors/pg'
|
|
185
339
|
import plugins from './server/plugins'
|
|
186
340
|
|
|
187
341
|
export default defineNuxtConfig({
|
|
188
342
|
grafserv: {
|
|
189
|
-
|
|
190
|
-
resolvers: 'server/resolvers.ts',
|
|
343
|
+
type: 'postgraphile',
|
|
191
344
|
preset: {
|
|
345
|
+
extends: [PostGraphileAmberPreset],
|
|
346
|
+
pgServices: [makePgService({ /* ... */ })],
|
|
192
347
|
plugins
|
|
193
348
|
}
|
|
194
349
|
}
|
|
@@ -219,7 +374,10 @@ const authPlugin: GraphileConfig.Plugin = {
|
|
|
219
374
|
middleware: {
|
|
220
375
|
processGraphQLRequestBody: async (next, event) => {
|
|
221
376
|
const token = event.request.headers.get('authorization')
|
|
222
|
-
//
|
|
377
|
+
// Validate token and add user to context
|
|
378
|
+
if (!token) {
|
|
379
|
+
throw new Error('Unauthorized')
|
|
380
|
+
}
|
|
223
381
|
return next()
|
|
224
382
|
}
|
|
225
383
|
}
|
|
@@ -236,166 +394,128 @@ export default [loggingPlugin, authPlugin]
|
|
|
236
394
|
- `ruruHTML` - Customize Ruru IDE HTML generation
|
|
237
395
|
- `onSubscribe` - Handle GraphQL subscriptions
|
|
238
396
|
|
|
239
|
-
##
|
|
240
|
-
|
|
241
|
-
### PostGraphile Integration
|
|
397
|
+
## PostGraphile Integration
|
|
242
398
|
|
|
243
|
-
This module has first-class support for PostGraphile
|
|
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.
|
|
244
400
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
1. Install PostGraphile:
|
|
401
|
+
### Prerequisites
|
|
248
402
|
|
|
249
403
|
```bash
|
|
250
|
-
pnpm add postgraphile
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
2. Create a PostGraphile schema provider (`server/graphql/schema.ts`):
|
|
254
|
-
|
|
255
|
-
```typescript
|
|
256
|
-
import { postgraphile } from 'postgraphile'
|
|
257
|
-
import type { GraphQLSchema } from 'graphql'
|
|
258
|
-
|
|
259
|
-
// Define your PostGraphile preset
|
|
260
|
-
const preset = {
|
|
261
|
-
pgServices: [
|
|
262
|
-
{
|
|
263
|
-
name: 'main',
|
|
264
|
-
connectionString: process.env.DATABASE_URL || 'postgres://localhost/mydb',
|
|
265
|
-
schemas: ['public'],
|
|
266
|
-
},
|
|
267
|
-
],
|
|
268
|
-
grafserv: {
|
|
269
|
-
websockets: false, // Disable websockets for Nuxt compatibility
|
|
270
|
-
},
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Create PostGraphile instance
|
|
274
|
-
const pgl = postgraphile(preset)
|
|
275
|
-
|
|
276
|
-
// Export schema provider function
|
|
277
|
-
export async function createPostGraphileSchema(): Promise<GraphQLSchema> {
|
|
278
|
-
const { schema } = await pgl.getSchemaResult()
|
|
279
|
-
return schema
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Export the instance if you need direct access
|
|
283
|
-
export { pgl }
|
|
404
|
+
pnpm add postgraphile
|
|
284
405
|
```
|
|
285
406
|
|
|
286
|
-
|
|
407
|
+
### Basic PostGraphile Setup
|
|
287
408
|
|
|
288
409
|
```typescript
|
|
289
410
|
// nuxt.config.ts
|
|
290
|
-
import {
|
|
411
|
+
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
412
|
+
import { makePgService } from 'postgraphile/adaptors/pg'
|
|
291
413
|
|
|
292
414
|
export default defineNuxtConfig({
|
|
293
415
|
modules: ['@stonecrop/nuxt-grafserv'],
|
|
294
416
|
grafserv: {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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
|
+
},
|
|
298
427
|
url: '/graphql',
|
|
299
|
-
graphiql: true,
|
|
428
|
+
graphiql: true,
|
|
300
429
|
}
|
|
301
430
|
})
|
|
302
431
|
```
|
|
303
432
|
|
|
304
|
-
|
|
433
|
+
### PostGraphile with Custom Plugins
|
|
305
434
|
|
|
306
|
-
|
|
435
|
+
Enhance your PostGraphile setup with community plugins:
|
|
307
436
|
|
|
308
437
|
```typescript
|
|
309
438
|
// nuxt.config.ts
|
|
310
|
-
import {
|
|
439
|
+
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
440
|
+
import { makePgService } from 'postgraphile/adaptors/pg'
|
|
441
|
+
import PgSimplifyInflectorPlugin from '@graphile-contrib/pg-simplify-inflector'
|
|
311
442
|
|
|
312
443
|
export default defineNuxtConfig({
|
|
313
444
|
grafserv: {
|
|
314
|
-
|
|
315
|
-
|
|
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
|
+
},
|
|
316
462
|
}
|
|
317
463
|
})
|
|
318
464
|
```
|
|
319
465
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
Enhance your PostGraphile setup with custom plugins:
|
|
466
|
+
### Advanced PostGraphile Configuration
|
|
323
467
|
|
|
324
468
|
```typescript
|
|
325
|
-
// server/graphql/schema.ts
|
|
326
|
-
import { postgraphile } from 'postgraphile'
|
|
327
|
-
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
328
|
-
import PgSimplifyInflectorPlugin from '@graphile-contrib/pg-simplify-inflector'
|
|
329
|
-
|
|
330
|
-
const preset = {
|
|
331
|
-
extends: [PostGraphileAmberPreset],
|
|
332
|
-
plugins: [PgSimplifyInflectorPlugin],
|
|
333
|
-
pgServices: [
|
|
334
|
-
{
|
|
335
|
-
name: 'main',
|
|
336
|
-
connectionString: process.env.DATABASE_URL,
|
|
337
|
-
schemas: ['public'],
|
|
338
|
-
},
|
|
339
|
-
],
|
|
340
|
-
grafserv: {
|
|
341
|
-
websockets: false,
|
|
342
|
-
},
|
|
343
|
-
grafast: {
|
|
344
|
-
explain: process.env.NODE_ENV === 'development', // Enable plan diagrams in dev
|
|
345
|
-
},
|
|
346
|
-
schema: {
|
|
347
|
-
// Add custom behavior overrides
|
|
348
|
-
defaultBehavior: 'connection', // Enable Relay-style connections by default
|
|
349
|
-
},
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const pgl = postgraphile(preset)
|
|
353
|
-
|
|
354
|
-
export async function createPostGraphileSchema() {
|
|
355
|
-
const { schema } = await pgl.getSchemaResult()
|
|
356
|
-
return schema
|
|
357
|
-
}
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
#### Benefits of PostGraphile Integration
|
|
361
|
-
|
|
362
|
-
- **Zero Schema Definition**: Automatically generates GraphQL schema from PostgreSQL
|
|
363
|
-
- **Auto-Generated Resolvers**: All queries and mutations created from database schema
|
|
364
|
-
- **Real-time Subscriptions**: Live query support via PostgreSQL LISTEN/NOTIFY
|
|
365
|
-
- **Row-Level Security**: Leverages PostgreSQL RLS for authorization
|
|
366
|
-
- **High Performance**: Uses Grafast execution engine with intelligent batching
|
|
367
|
-
- **Type Safety**: Full TypeScript support for generated schema
|
|
368
|
-
|
|
369
|
-
### Custom Graphile Preset
|
|
370
|
-
|
|
371
|
-
Leverage the full power of the Graphile ecosystem with custom presets:
|
|
372
|
-
|
|
373
|
-
```ts
|
|
374
469
|
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
470
|
+
import { makePgService } from 'postgraphile/adaptors/pg'
|
|
375
471
|
|
|
376
472
|
export default defineNuxtConfig({
|
|
377
473
|
grafserv: {
|
|
474
|
+
type: 'postgraphile',
|
|
378
475
|
preset: {
|
|
379
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
|
+
},
|
|
380
494
|
grafast: {
|
|
381
|
-
explain: true,
|
|
382
|
-
context: {
|
|
383
|
-
// Custom context
|
|
384
|
-
|
|
385
|
-
}
|
|
495
|
+
explain: true,
|
|
496
|
+
context: (requestContext) => ({
|
|
497
|
+
// Custom context for all resolvers
|
|
498
|
+
userId: requestContext.user?.id,
|
|
499
|
+
}),
|
|
386
500
|
},
|
|
387
|
-
|
|
388
|
-
graphqlOverGET: true,
|
|
389
|
-
maxRequestLength: 200000
|
|
390
|
-
}
|
|
391
|
-
}
|
|
501
|
+
},
|
|
392
502
|
}
|
|
393
503
|
})
|
|
394
504
|
```
|
|
395
505
|
|
|
506
|
+
### Benefits of PostGraphile Integration
|
|
507
|
+
|
|
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
|
|
515
|
+
|
|
396
516
|
### Accessing Grafserv Instance
|
|
397
517
|
|
|
398
|
-
For advanced use cases, you can access the grafserv instance directly:
|
|
518
|
+
For advanced use cases, you can access the grafserv instance directly in server routes:
|
|
399
519
|
|
|
400
520
|
```ts
|
|
401
521
|
// server/api/custom.ts
|
|
@@ -406,10 +526,13 @@ export default defineEventHandler(async (event) => {
|
|
|
406
526
|
const config = useRuntimeConfig()
|
|
407
527
|
const serv = await getGrafservInstance(config.grafserv)
|
|
408
528
|
|
|
409
|
-
// Access grafserv methods
|
|
410
|
-
|
|
529
|
+
// Access grafserv methods
|
|
530
|
+
// Note: serv contains the grafserv instance with your schema
|
|
411
531
|
|
|
412
|
-
return {
|
|
532
|
+
return {
|
|
533
|
+
status: 'GraphQL server is running',
|
|
534
|
+
endpoint: config.grafserv.url
|
|
535
|
+
}
|
|
413
536
|
})
|
|
414
537
|
```
|
|
415
538
|
|
package/dist/module.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { NuxtModule } from '@nuxt/schema';
|
|
2
|
-
import { PromiseOrDirect } from 'grafast';
|
|
3
2
|
import { GraphQLSchema } from 'graphql';
|
|
4
3
|
import { GraphileConfig } from 'graphile-config';
|
|
5
4
|
|
|
@@ -8,32 +7,110 @@ import { GraphileConfig } from 'graphile-config';
|
|
|
8
7
|
*/
|
|
9
8
|
type SchemaProvider = () => GraphQLSchema | Promise<GraphQLSchema>;
|
|
10
9
|
/**
|
|
11
|
-
* PostGraphile
|
|
10
|
+
* PostGraphile configuration using preset
|
|
11
|
+
*
|
|
12
|
+
* This is the recommended approach for PostGraphile integration.
|
|
13
|
+
* The preset is passed to PostGraphile's makeSchema() function to generate the GraphQL schema.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
|
|
18
|
+
* import { makePgService } from 'postgraphile/adaptors/pg'
|
|
19
|
+
*
|
|
20
|
+
* export default defineNuxtConfig({
|
|
21
|
+
* modules: ['@stonecrop/nuxt-grafserv'],
|
|
22
|
+
* grafserv: {
|
|
23
|
+
* 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
|
+
* },
|
|
34
|
+
* url: '/graphql',
|
|
35
|
+
* graphiql: true,
|
|
36
|
+
* },
|
|
37
|
+
* })
|
|
38
|
+
* ```
|
|
12
39
|
*/
|
|
13
|
-
interface
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
40
|
+
interface PostGraphileConfig {
|
|
41
|
+
/** Configuration type discriminator */
|
|
42
|
+
type: 'postgraphile';
|
|
43
|
+
/** PostGraphile preset configuration - passed to makeSchema() */
|
|
44
|
+
preset: GraphileConfig.Preset;
|
|
45
|
+
/** GraphQL endpoint URL (default: '/graphql/') */
|
|
46
|
+
url?: string;
|
|
47
|
+
/** Whether to enable GraphiQL IDE (default: true in dev, false in prod) */
|
|
48
|
+
graphiql?: boolean;
|
|
19
49
|
}
|
|
20
50
|
/**
|
|
21
|
-
*
|
|
51
|
+
* Schema configuration using GraphQL schema files or provider function
|
|
52
|
+
*
|
|
53
|
+
* Use this for custom GraphQL schemas with Grafast resolvers.
|
|
54
|
+
* Schema files (.graphql) are loaded and combined with resolver functions.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Using schema files with resolvers
|
|
59
|
+
* export default defineNuxtConfig({
|
|
60
|
+
* modules: ['@stonecrop/nuxt-grafserv'],
|
|
61
|
+
* grafserv: {
|
|
62
|
+
* type: 'schema',
|
|
63
|
+
* schema: 'server/schema/**\/*.graphql',
|
|
64
|
+
* resolvers: 'server/resolvers/index.ts',
|
|
65
|
+
* url: '/graphql',
|
|
66
|
+
* graphiql: true,
|
|
67
|
+
* },
|
|
68
|
+
* })
|
|
69
|
+
*
|
|
70
|
+
* // Using schema provider function
|
|
71
|
+
* export default defineNuxtConfig({
|
|
72
|
+
* grafserv: {
|
|
73
|
+
* type: 'schema',
|
|
74
|
+
* schema: async () => {
|
|
75
|
+
* // Return a GraphQLSchema instance
|
|
76
|
+
* return myCustomSchema
|
|
77
|
+
* },
|
|
78
|
+
* },
|
|
79
|
+
* })
|
|
80
|
+
* ```
|
|
22
81
|
*/
|
|
23
|
-
interface
|
|
24
|
-
/**
|
|
25
|
-
schema
|
|
26
|
-
/**
|
|
82
|
+
interface SchemaConfig {
|
|
83
|
+
/** Configuration type discriminator */
|
|
84
|
+
type: 'schema';
|
|
85
|
+
/**
|
|
86
|
+
* Path to schema file(s) or schema provider function
|
|
87
|
+
* - String: Single file path (e.g., 'server/schema/schema.graphql')
|
|
88
|
+
* - Array: Multiple file paths (e.g., ['server/schema/**\/*.graphql'])
|
|
89
|
+
* - Function: Returns a GraphQL schema directly
|
|
90
|
+
*/
|
|
91
|
+
schema: string | string[] | SchemaProvider;
|
|
92
|
+
/**
|
|
93
|
+
* Path to resolvers file (optional)
|
|
94
|
+
* Only needed when using .graphql schema files.
|
|
95
|
+
* Should export Grafast resolver objects.
|
|
96
|
+
*
|
|
97
|
+
* @example 'server/resolvers/index.ts'
|
|
98
|
+
*/
|
|
27
99
|
resolvers?: string;
|
|
28
100
|
/** GraphQL endpoint URL (default: '/graphql/') */
|
|
29
101
|
url?: string;
|
|
30
102
|
/** Whether to enable GraphiQL IDE (default: true in dev, false in prod) */
|
|
31
103
|
graphiql?: boolean;
|
|
32
|
-
/** Custom Graphile preset to extend (for advanced grafast configuration) */
|
|
33
|
-
preset?: GraphileConfig.Preset;
|
|
34
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Module configuration - use either PostGraphile preset or custom schema
|
|
107
|
+
*
|
|
108
|
+
* @see PostGraphileConfig for PostGraphile integration
|
|
109
|
+
* @see SchemaConfig for custom schemas with resolvers
|
|
110
|
+
*/
|
|
111
|
+
type ModuleOptions = PostGraphileConfig | SchemaConfig;
|
|
35
112
|
|
|
36
113
|
declare const module$1: NuxtModule<ModuleOptions>;
|
|
37
114
|
|
|
38
115
|
export { module$1 as default };
|
|
39
|
-
export type { ModuleOptions, SchemaProvider };
|
|
116
|
+
export type { ModuleOptions, PostGraphileConfig, SchemaConfig, SchemaProvider };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,28 +1,59 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { useLogger, defineNuxtModule, createResolver } from '@nuxt/kit';
|
|
3
|
+
import { useLogger, defineNuxtModule, createResolver, addTemplate } from '@nuxt/kit';
|
|
4
4
|
|
|
5
5
|
const logger = useLogger("@stonecrop/nuxt-grafserv");
|
|
6
|
+
function validateConfig(options) {
|
|
7
|
+
if (!options.type) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`[@stonecrop/nuxt-grafserv] Configuration error: 'type' field is required. Must be either 'postgraphile' or 'schema'.
|
|
10
|
+
Example: grafserv: { type: 'postgraphile', preset: { ... } }`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
if (options.type === "postgraphile") {
|
|
14
|
+
const config = options;
|
|
15
|
+
if (!config.preset) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`[@stonecrop/nuxt-grafserv] PostGraphile configuration error: 'preset' field is required when type is 'postgraphile'.
|
|
18
|
+
Example: { type: 'postgraphile', preset: { extends: [PostGraphileAmberPreset], ... } }`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
if ("schema" in config || "resolvers" in config) {
|
|
22
|
+
logger.warn(
|
|
23
|
+
`PostGraphile configuration should not include 'schema' or 'resolvers' fields. The schema is generated from the 'preset' configuration.`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
} else if (options.type === "schema") {
|
|
27
|
+
const config = options;
|
|
28
|
+
if (!config.schema) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`[@stonecrop/nuxt-grafserv] Schema configuration error: 'schema' field is required when type is 'schema'.
|
|
31
|
+
Example: { type: 'schema', schema: 'server/**/*.graphql', resolvers: 'server/resolvers/index.ts' }`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
if ("preset" in config) {
|
|
35
|
+
logger.warn(
|
|
36
|
+
`Schema configuration should not include 'preset' field. Use type: 'postgraphile' for PostGraphile preset configuration.`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`[@stonecrop/nuxt-grafserv] Configuration error: Invalid type '${options.type}'. Must be either 'postgraphile' or 'schema'.`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
6
45
|
const module$1 = defineNuxtModule({
|
|
7
46
|
meta: {
|
|
8
47
|
name: "@stonecrop/nuxt-grafserv",
|
|
9
48
|
configKey: "grafserv"
|
|
10
49
|
},
|
|
11
|
-
defaults
|
|
12
|
-
|
|
13
|
-
resolvers: void 0,
|
|
14
|
-
// Optional - not needed for PostGraphile setups
|
|
15
|
-
url: "/graphql/",
|
|
16
|
-
graphiql: void 0,
|
|
17
|
-
// Will default based on dev mode
|
|
18
|
-
plugins: [],
|
|
19
|
-
preset: {
|
|
20
|
-
grafserv: {
|
|
21
|
-
websockets: false
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}),
|
|
50
|
+
// No defaults - user must provide complete config with type discriminator
|
|
51
|
+
// Use undefined instead of {} to ensure user config is passed as-is
|
|
25
52
|
setup(options, nuxt) {
|
|
53
|
+
if (Object.keys(options).length === 0) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
validateConfig(options);
|
|
26
57
|
const { resolve } = createResolver(import.meta.url);
|
|
27
58
|
const require = createRequire(import.meta.url);
|
|
28
59
|
nuxt.hook("nitro:config", (config) => {
|
|
@@ -44,36 +75,55 @@ const module$1 = defineNuxtModule({
|
|
|
44
75
|
logger.info(`Nuxt srcDir: ${nuxt.options.srcDir}`);
|
|
45
76
|
logger.info(`Nuxt rootDir: ${nuxt.options.rootDir}`);
|
|
46
77
|
logger.info(`Grafserv server alias: ${config.alias["#grafserv-server"]}`);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
} else {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
schema
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
78
|
+
if (options.type === "postgraphile") {
|
|
79
|
+
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)}`;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
config.runtimeConfig = config.runtimeConfig || {};
|
|
88
|
+
config.runtimeConfig.grafserv = {
|
|
89
|
+
type: "postgraphile",
|
|
90
|
+
url: options.url || "/graphql/",
|
|
91
|
+
graphiql: options.graphiql,
|
|
92
|
+
presetPath: template.dst
|
|
93
|
+
};
|
|
94
|
+
} else if (options.type === "schema") {
|
|
95
|
+
logger.info("Using schema configuration");
|
|
96
|
+
const resolverPath = options.resolvers ? resolveForVirtualModule(options.resolvers) : void 0;
|
|
97
|
+
if (resolverPath) {
|
|
98
|
+
logger.info(`Resolved resolver path: ${resolverPath}`);
|
|
99
|
+
} else {
|
|
100
|
+
logger.info("No resolvers configured");
|
|
101
|
+
}
|
|
102
|
+
let runtimeSchema;
|
|
103
|
+
if (typeof options.schema === "function") {
|
|
104
|
+
runtimeSchema = options.schema;
|
|
105
|
+
logger.info("Using schema provider function");
|
|
106
|
+
} else if (typeof options.schema === "string") {
|
|
107
|
+
runtimeSchema = resolveForSchema(options.schema);
|
|
108
|
+
logger.info(`Resolved schema path: ${runtimeSchema}`);
|
|
109
|
+
} else if (Array.isArray(options.schema)) {
|
|
110
|
+
runtimeSchema = options.schema.map((s) => resolveForSchema(s));
|
|
111
|
+
logger.info(`Resolved schema paths: ${runtimeSchema.join(", ")}`);
|
|
112
|
+
} else {
|
|
113
|
+
runtimeSchema = options.schema;
|
|
114
|
+
}
|
|
115
|
+
config.runtimeConfig = config.runtimeConfig || {};
|
|
116
|
+
config.runtimeConfig.grafserv = {
|
|
117
|
+
type: "schema",
|
|
118
|
+
schema: runtimeSchema,
|
|
119
|
+
resolversPath: resolverPath,
|
|
120
|
+
url: options.url || "/graphql/",
|
|
121
|
+
graphiql: options.graphiql
|
|
122
|
+
};
|
|
123
|
+
config.virtual = config.virtual || {};
|
|
124
|
+
if (resolverPath) {
|
|
125
|
+
config.virtual["#internal/grafserv/resolvers"] = `export { default } from '${resolverPath}'`;
|
|
126
|
+
}
|
|
77
127
|
}
|
|
78
128
|
config.externals = config.externals || {};
|
|
79
129
|
config.externals.external = config.externals.external || [];
|
|
@@ -119,7 +169,7 @@ const module$1 = defineNuxtModule({
|
|
|
119
169
|
let cacheClearing = false;
|
|
120
170
|
nuxt.hook("builder:watch", async (event, path) => {
|
|
121
171
|
const isSchemaFile = path.endsWith(".graphql");
|
|
122
|
-
const isResolverFile = options.resolvers && path.includes(options.resolvers.replace("./", ""));
|
|
172
|
+
const isResolverFile = options.type === "schema" && options.resolvers && path.includes(options.resolvers.replace("./", ""));
|
|
123
173
|
if (isSchemaFile || isResolverFile) {
|
|
124
174
|
if (!cacheClearing) {
|
|
125
175
|
cacheClearing = true;
|
package/dist/runtime/handler.js
CHANGED
|
@@ -13,69 +13,74 @@ async function loadTypeDefsFromFiles(schemaPath) {
|
|
|
13
13
|
});
|
|
14
14
|
return sources.map((source) => source.document).filter(Boolean);
|
|
15
15
|
}
|
|
16
|
-
function isPostGraphileInstance(value) {
|
|
17
|
-
return value !== null && typeof value === "object" && "getSchema" in value && typeof value.getSchema === "function";
|
|
18
|
-
}
|
|
19
16
|
async function getSchema(options) {
|
|
20
17
|
if (cachedSchema) {
|
|
21
18
|
return cachedSchema;
|
|
22
19
|
}
|
|
23
20
|
let schema;
|
|
24
|
-
if (
|
|
25
|
-
console.debug("[@stonecrop/nuxt-grafserv]
|
|
21
|
+
if (options.type === "postgraphile") {
|
|
22
|
+
console.debug("[@stonecrop/nuxt-grafserv] Creating schema from PostGraphile preset");
|
|
26
23
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
schema = await options.schema.getSchema();
|
|
24
|
+
const { makeSchema } = await import("postgraphile");
|
|
25
|
+
const config = useRuntimeConfig();
|
|
26
|
+
if (config.grafserv.type !== "postgraphile") {
|
|
27
|
+
throw new Error("Expected PostGraphile configuration");
|
|
32
28
|
}
|
|
33
|
-
|
|
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");
|
|
34
34
|
} catch (error) {
|
|
35
|
-
|
|
35
|
+
if (error instanceof Error && "code" in error && error.code === "MODULE_NOT_FOUND") {
|
|
36
|
+
throw new Error(
|
|
37
|
+
'[@stonecrop/nuxt-grafserv] PostGraphile preset provided but "postgraphile" package not found. Install it with: npm install postgraphile'
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
console.error("[@stonecrop/nuxt-grafserv] Error creating PostGraphile schema:", error);
|
|
36
41
|
throw error;
|
|
37
42
|
}
|
|
38
|
-
} else if (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
} else if (options.type === "schema") {
|
|
44
|
+
if (typeof options.schema === "function") {
|
|
45
|
+
console.debug("[@stonecrop/nuxt-grafserv] Using schema provider function");
|
|
46
|
+
schema = await options.schema();
|
|
47
|
+
} else {
|
|
48
|
+
console.debug("[@stonecrop/nuxt-grafserv] Loading schema from file(s)");
|
|
49
|
+
const typeDefDocs = await loadTypeDefsFromFiles(options.schema);
|
|
50
|
+
const objects = {};
|
|
51
|
+
if (options.resolversPath) {
|
|
52
|
+
try {
|
|
53
|
+
const resolverModule = await import("#internal/grafserv/resolvers");
|
|
54
|
+
const resolvers = resolverModule.default || resolverModule;
|
|
55
|
+
console.debug("[@stonecrop/nuxt-grafserv] Resolvers loaded:", Object.keys(resolvers));
|
|
56
|
+
for (const typeName of Object.keys(resolvers)) {
|
|
57
|
+
const typeResolvers = resolvers[typeName];
|
|
58
|
+
if (typeResolvers && typeof typeResolvers === "object" && "plans" in typeResolvers) {
|
|
59
|
+
objects[typeName] = typeResolvers;
|
|
60
|
+
} else {
|
|
61
|
+
objects[typeName] = { plans: typeResolvers };
|
|
62
|
+
}
|
|
54
63
|
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.error("[@stonecrop/nuxt-grafserv] Error loading resolvers:", e);
|
|
66
|
+
throw e;
|
|
55
67
|
}
|
|
56
|
-
}
|
|
57
|
-
console.
|
|
58
|
-
|
|
68
|
+
} else {
|
|
69
|
+
console.debug("[@stonecrop/nuxt-grafserv] No resolvers specified");
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
schema = makeGrafastSchema({
|
|
73
|
+
typeDefs: typeDefDocs,
|
|
74
|
+
objects
|
|
75
|
+
});
|
|
76
|
+
console.debug("[@stonecrop/nuxt-grafserv] Grafast schema created successfully");
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("[@stonecrop/nuxt-grafserv] Error creating Grafast schema:", error);
|
|
79
|
+
throw error;
|
|
59
80
|
}
|
|
60
|
-
} else {
|
|
61
|
-
console.debug(
|
|
62
|
-
"[@stonecrop/nuxt-grafserv] No resolvers specified - using schema-only mode (normal for PostGraphile)"
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
try {
|
|
66
|
-
schema = makeGrafastSchema({
|
|
67
|
-
typeDefs: typeDefDocs,
|
|
68
|
-
objects
|
|
69
|
-
});
|
|
70
|
-
console.debug("[@stonecrop/nuxt-grafserv] Grafast schema created successfully");
|
|
71
|
-
} catch (error) {
|
|
72
|
-
console.error("[@stonecrop/nuxt-grafserv] Error creating Grafast schema:", error);
|
|
73
|
-
throw error;
|
|
74
81
|
}
|
|
75
82
|
} else {
|
|
76
|
-
throw new Error(
|
|
77
|
-
"[@stonecrop/nuxt-grafserv] No schema provided. Configure schema path, provider function, or PostGraphile instance."
|
|
78
|
-
);
|
|
83
|
+
throw new Error(`[@stonecrop/nuxt-grafserv] Invalid configuration type: ${options.type}`);
|
|
79
84
|
}
|
|
80
85
|
cachedSchema = schema;
|
|
81
86
|
return schema;
|
|
@@ -86,7 +91,7 @@ export async function getGrafservInstance(options) {
|
|
|
86
91
|
return grafservInstance;
|
|
87
92
|
}
|
|
88
93
|
const schema = await getSchema(options);
|
|
89
|
-
grafservInstance = grafserv({ schema
|
|
94
|
+
grafservInstance = grafserv({ schema });
|
|
90
95
|
console.log("[@stonecrop/nuxt-grafserv] Grafserv instance created");
|
|
91
96
|
return grafservInstance;
|
|
92
97
|
}
|
package/dist/types.d.mts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stonecrop/nuxt-grafserv",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"description": "Pluggable Grafserv GraphQL server as Nuxt Module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -42,12 +42,10 @@
|
|
|
42
42
|
"@graphql-tools/wrap": "^11.1.4",
|
|
43
43
|
"grafast": "^1.0.0-rc.4",
|
|
44
44
|
"grafserv": "^1.0.0-rc.4",
|
|
45
|
-
"graphile-config": "^1.0.0-rc.3",
|
|
46
45
|
"graphql": "^16.12.0",
|
|
47
|
-
"@stonecrop/graphql-middleware": "0.7.
|
|
46
|
+
"@stonecrop/graphql-middleware": "0.7.8"
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
|
-
"@casl/ability": "^6.8.0",
|
|
51
49
|
"@eslint/js": "^9.39.2",
|
|
52
50
|
"@nuxt/devtools": "^3.1.1",
|
|
53
51
|
"@nuxt/eslint-config": "^1.12.1",
|
|
@@ -67,13 +65,13 @@
|
|
|
67
65
|
"typescript": "^5.9.3",
|
|
68
66
|
"vite": "^7.3.1",
|
|
69
67
|
"vitest": "^4.0.17",
|
|
70
|
-
"vue-tsc": "^3.2.2"
|
|
71
|
-
"@stonecrop/casl-middleware": "0.7.6",
|
|
72
|
-
"@stonecrop/rockfoil": "0.7.6"
|
|
68
|
+
"vue-tsc": "^3.2.2"
|
|
73
69
|
},
|
|
74
70
|
"peerDependencies": {
|
|
75
|
-
"@stonecrop/casl-middleware": "
|
|
76
|
-
"@stonecrop/rockfoil": "
|
|
71
|
+
"@stonecrop/casl-middleware": "*",
|
|
72
|
+
"@stonecrop/rockfoil": "*",
|
|
73
|
+
"postgraphile": "^5.0.0-rc.4",
|
|
74
|
+
"graphile-config": "^1.0.0-rc.3"
|
|
77
75
|
},
|
|
78
76
|
"peerDependenciesMeta": {
|
|
79
77
|
"@stonecrop/casl-middleware": {
|
|
@@ -81,6 +79,12 @@
|
|
|
81
79
|
},
|
|
82
80
|
"@stonecrop/rockfoil": {
|
|
83
81
|
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"postgraphile": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"graphile-config": {
|
|
87
|
+
"optional": true
|
|
84
88
|
}
|
|
85
89
|
},
|
|
86
90
|
"scripts": {
|