nuxt-graphql-middleware 5.2.2 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/CqRv5mwS.js +2 -0
- package/dist/client/_nuxt/{DKGPmQRi.js → D95LLO0l.js} +1 -1
- package/dist/client/_nuxt/DZ-uq6Vd.js +1 -0
- package/dist/client/_nuxt/DrXVleME.js +4 -0
- package/dist/client/_nuxt/{CLvFsrJf.js → Dx-h1-qv.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/f3f3372e-493e-4c8e-9dbd-18d4c5406f44.json +1 -0
- package/dist/client/_nuxt/{entry.DUAtNXP_.css → entry.Cyocd7ae.css} +1 -1
- package/dist/client/_nuxt/error-404.BLrjNXsr.css +1 -0
- package/dist/client/_nuxt/error-500.DLkAwcfL.css +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.d.mts +1 -1
- package/dist/module.json +3 -3
- package/dist/module.mjs +1526 -70
- package/dist/runtime/components/CodeFrame.d.vue.ts +8 -0
- package/dist/runtime/components/CodeFrame.vue.d.ts +2 -1
- package/dist/runtime/components/DevModeOverlay.d.vue.ts +4 -0
- package/dist/runtime/components/DevModeOverlay.vue +1 -1
- package/dist/runtime/components/DevModeOverlay.vue.d.ts +2 -1
- package/dist/runtime/components/ErrorExtensions.d.vue.ts +6 -0
- package/dist/runtime/components/ErrorExtensions.vue.d.ts +2 -1
- package/dist/runtime/components/ErrorGroup.d.vue.ts +10 -0
- package/dist/runtime/components/ErrorGroup.vue.d.ts +2 -1
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/helpers/composables.d.ts +1 -40
- package/dist/runtime/helpers/composables.js +3 -12
- package/dist/runtime/helpers/shared-types.d.ts +40 -0
- package/dist/runtime/helpers/shared-types.js +12 -0
- package/dist/runtime/server/api/doRequest.d.ts +2 -0
- package/dist/runtime/server/api/doRequest.js +18 -0
- package/dist/runtime/server/helpers/index.js +1 -1
- package/dist/runtime/server/mcp/index.d.ts +2 -0
- package/dist/runtime/server/mcp/index.js +63 -0
- package/dist/runtime/server/mcp/resources/docs.d.ts +2 -0
- package/dist/runtime/server/mcp/resources/docs.js +36 -0
- package/dist/runtime/server/mcp/tools/fragments-get/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/fragments-get/index.js +35 -0
- package/dist/runtime/server/mcp/tools/fragments-get/types.d.ts +20 -0
- package/dist/runtime/server/mcp/tools/fragments-get/types.js +13 -0
- package/dist/runtime/server/mcp/tools/fragments-get-source/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/fragments-get-source/index.js +34 -0
- package/dist/runtime/server/mcp/tools/fragments-get-source/types.d.ts +10 -0
- package/dist/runtime/server/mcp/tools/fragments-get-source/types.js +9 -0
- package/dist/runtime/server/mcp/tools/fragments-list/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/fragments-list/index.js +36 -0
- package/dist/runtime/server/mcp/tools/fragments-list/types.d.ts +20 -0
- package/dist/runtime/server/mcp/tools/fragments-list/types.js +14 -0
- package/dist/runtime/server/mcp/tools/fragments-list-for-type/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/fragments-list-for-type/index.js +39 -0
- package/dist/runtime/server/mcp/tools/fragments-list-for-type/types.d.ts +31 -0
- package/dist/runtime/server/mcp/tools/fragments-list-for-type/types.js +23 -0
- package/dist/runtime/server/mcp/tools/graphql-execute/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/graphql-execute/index.js +59 -0
- package/dist/runtime/server/mcp/tools/module-get-config/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/module-get-config/index.js +23 -0
- package/dist/runtime/server/mcp/tools/module-get-config/types.d.ts +39 -0
- package/dist/runtime/server/mcp/tools/module-get-config/types.js +26 -0
- package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/index.js +36 -0
- package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/types.d.ts +49 -0
- package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/types.js +24 -0
- package/dist/runtime/server/mcp/tools/operations-execute/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/operations-execute/index.js +63 -0
- package/dist/runtime/server/mcp/tools/operations-get/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/operations-get/index.js +40 -0
- package/dist/runtime/server/mcp/tools/operations-get/types.d.ts +32 -0
- package/dist/runtime/server/mcp/tools/operations-get/types.js +18 -0
- package/dist/runtime/server/mcp/tools/operations-get-field-usage/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/operations-get-field-usage/index.js +39 -0
- package/dist/runtime/server/mcp/tools/operations-get-field-usage/types.d.ts +38 -0
- package/dist/runtime/server/mcp/tools/operations-get-field-usage/types.js +19 -0
- package/dist/runtime/server/mcp/tools/operations-get-source/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/operations-get-source/index.js +39 -0
- package/dist/runtime/server/mcp/tools/operations-get-source/types.d.ts +10 -0
- package/dist/runtime/server/mcp/tools/operations-get-source/types.js +9 -0
- package/dist/runtime/server/mcp/tools/operations-list/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/operations-list/index.js +46 -0
- package/dist/runtime/server/mcp/tools/operations-list/types.d.ts +53 -0
- package/dist/runtime/server/mcp/tools/operations-list/types.js +33 -0
- package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/index.js +37 -0
- package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/types.d.ts +24 -0
- package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/types.js +16 -0
- package/dist/runtime/server/mcp/tools/schema-get-type/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/schema-get-type/index.js +31 -0
- package/dist/runtime/server/mcp/tools/schema-get-type/types.d.ts +112 -0
- package/dist/runtime/server/mcp/tools/schema-get-type/types.js +45 -0
- package/dist/runtime/server/mcp/tools/schema-get-type-definition/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/schema-get-type-definition/index.js +33 -0
- package/dist/runtime/server/mcp/tools/schema-get-type-definition/types.d.ts +10 -0
- package/dist/runtime/server/mcp/tools/schema-get-type-definition/types.js +9 -0
- package/dist/runtime/server/mcp/tools/schema-get-type-usage/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/schema-get-type-usage/index.js +35 -0
- package/dist/runtime/server/mcp/tools/schema-get-type-usage/types.d.ts +39 -0
- package/dist/runtime/server/mcp/tools/schema-get-type-usage/types.js +17 -0
- package/dist/runtime/server/mcp/tools/schema-get-union-members/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/schema-get-union-members/index.js +35 -0
- package/dist/runtime/server/mcp/tools/schema-get-union-members/types.d.ts +24 -0
- package/dist/runtime/server/mcp/tools/schema-get-union-members/types.js +16 -0
- package/dist/runtime/server/mcp/tools/schema-list-types/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/schema-list-types/index.js +37 -0
- package/dist/runtime/server/mcp/tools/schema-list-types/types.d.ts +53 -0
- package/dist/runtime/server/mcp/tools/schema-list-types/types.js +21 -0
- package/dist/runtime/server/mcp/tools/schema-validate-document/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/schema-validate-document/index.js +31 -0
- package/dist/runtime/server/mcp/tools/schema-validate-document/types.d.ts +26 -0
- package/dist/runtime/server/mcp/tools/schema-validate-document/types.js +21 -0
- package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/index.d.ts +1 -0
- package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/index.js +36 -0
- package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/types.d.ts +49 -0
- package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/types.js +24 -0
- package/dist/runtime/server/mcp/utils/index.d.ts +48 -0
- package/dist/runtime/server/mcp/utils/index.js +35 -0
- package/dist/runtime/server/utils/useGraphqlMutation.d.ts +1 -1
- package/dist/runtime/server/utils/useGraphqlMutation.js +1 -1
- package/dist/runtime/server/utils/useGraphqlQuery.d.ts +1 -1
- package/dist/runtime/server/utils/useGraphqlQuery.js +1 -1
- package/dist/runtime/types.d.ts +1 -1
- package/dist/shared/{nuxt-graphql-middleware.ct2xvPoD.d.mts → nuxt-graphql-middleware.COufMnWs.d.mts} +119 -2
- package/dist/utils.d.mts +1 -1
- package/docs/composables/useAsyncGraphqlQuery.md +313 -0
- package/docs/composables/useGraphqlMutation.md +29 -0
- package/docs/composables/useGraphqlQuery.md +73 -0
- package/docs/composables/useGraphqlState.md +58 -0
- package/docs/composables/useGraphqlUploadMutation.md +57 -0
- package/docs/configuration/client-options.md +121 -0
- package/docs/configuration/module-hooks.md +112 -0
- package/docs/configuration/module-utils.md +53 -0
- package/docs/configuration/module.md +415 -0
- package/docs/configuration/runtime-config.md +23 -0
- package/docs/configuration/server-options.md +230 -0
- package/package.json +102 -44
- package/dist/client/_nuxt/CKZE-Gmz.js +0 -2
- package/dist/client/_nuxt/CYCWsMRt.js +0 -1
- package/dist/client/_nuxt/DPP_zJIh.js +0 -25
- package/dist/client/_nuxt/builds/meta/1a5c6b94-502b-4ab8-a5c9-f955b10f2b06.json +0 -1
- package/dist/client/_nuxt/error-404.DlVPZ4GE.css +0 -1
- package/dist/client/_nuxt/error-500.DjyirMQI.css +0 -1
- package/dist/runtime/server/tsconfig.json +0 -3
|
@@ -230,6 +230,21 @@ interface ModuleOptions {
|
|
|
230
230
|
*/
|
|
231
231
|
improvedQueryParamEncoding?: boolean;
|
|
232
232
|
};
|
|
233
|
+
/**
|
|
234
|
+
* Configuration for the @nuxtjs/mcp-toolkit integration.
|
|
235
|
+
*/
|
|
236
|
+
mcp?: {
|
|
237
|
+
/**
|
|
238
|
+
* Whether the MCP integration should be enabled.
|
|
239
|
+
*/
|
|
240
|
+
enabled: boolean;
|
|
241
|
+
/**
|
|
242
|
+
* The route of the MCP server.
|
|
243
|
+
*
|
|
244
|
+
* @default /mcp/nuxt-graphql-middleware
|
|
245
|
+
*/
|
|
246
|
+
route?: string;
|
|
247
|
+
};
|
|
233
248
|
}
|
|
234
249
|
|
|
235
250
|
declare const defaultOptions: ModuleOptions;
|
|
@@ -242,6 +257,7 @@ declare class ConsolePrompt {
|
|
|
242
257
|
|
|
243
258
|
type TemplateOptions = {
|
|
244
259
|
path: string;
|
|
260
|
+
context: 'nuxt' | 'nitro' | 'both';
|
|
245
261
|
virtual?: boolean;
|
|
246
262
|
isFullPath?: boolean;
|
|
247
263
|
};
|
|
@@ -262,6 +278,27 @@ type StaticTemplate = {
|
|
|
262
278
|
virtual?: boolean;
|
|
263
279
|
};
|
|
264
280
|
|
|
281
|
+
type BuildImport = {
|
|
282
|
+
name: string;
|
|
283
|
+
description: string;
|
|
284
|
+
docsUrl: string;
|
|
285
|
+
context: 'nuxt' | 'nitro';
|
|
286
|
+
};
|
|
287
|
+
declare const COMPOSABLES: {
|
|
288
|
+
useGraphqlQuery: BuildImport;
|
|
289
|
+
useGraphqlMutation: BuildImport;
|
|
290
|
+
useAsyncGraphqlQuery: BuildImport;
|
|
291
|
+
useGraphqlUploadMutation: BuildImport;
|
|
292
|
+
useGraphqlState: BuildImport;
|
|
293
|
+
};
|
|
294
|
+
type ComposableName = keyof typeof COMPOSABLES;
|
|
295
|
+
declare const SERVER_UTILS: {
|
|
296
|
+
useGraphqlQuery: BuildImport;
|
|
297
|
+
useGraphqlMutation: BuildImport;
|
|
298
|
+
doGraphqlRequest: BuildImport;
|
|
299
|
+
};
|
|
300
|
+
type ServerUtilName = keyof typeof SERVER_UTILS;
|
|
301
|
+
|
|
265
302
|
type WithRequired<T, K extends keyof T> = T & {
|
|
266
303
|
[P in K]-?: T[P];
|
|
267
304
|
};
|
|
@@ -306,6 +343,7 @@ declare class ModuleHelper {
|
|
|
306
343
|
readonly resolvers: ModuleHelperResolvers;
|
|
307
344
|
readonly paths: ModuleHelperPaths;
|
|
308
345
|
readonly isDev: boolean;
|
|
346
|
+
readonly isPrepare: boolean;
|
|
309
347
|
readonly options: RequiredModuleOptions;
|
|
310
348
|
readonly prompt: ConsolePrompt;
|
|
311
349
|
private nitroExternals;
|
|
@@ -343,12 +381,67 @@ declare class ModuleHelper {
|
|
|
343
381
|
applyBuildConfig(): void;
|
|
344
382
|
processTemplate(path: string, content: string): string;
|
|
345
383
|
addTemplate(template: StaticTemplate): void;
|
|
384
|
+
/**
|
|
385
|
+
* Register a type template without adding to globalTypeFiles.
|
|
386
|
+
*
|
|
387
|
+
* Uses addTemplate instead of addTypeTemplate to avoid Vue compiler-sfc
|
|
388
|
+
* issue where exported types from globalTypeFiles cannot be resolved.
|
|
389
|
+
* @see https://github.com/nuxt/nuxt/issues/33694
|
|
390
|
+
*/
|
|
391
|
+
registerTypeTemplate(filename: `${string}.d.ts`, getContents: () => string, context: 'nuxt' | 'nitro' | 'both'): void;
|
|
346
392
|
addPlugin(name: string): void;
|
|
347
393
|
addServerHandler(name: string, path: string, method: RouterMethod): void;
|
|
348
|
-
addComposable(name:
|
|
349
|
-
addServerUtil(name:
|
|
394
|
+
addComposable(name: ComposableName): void;
|
|
395
|
+
addServerUtil(name: ServerUtilName): void;
|
|
350
396
|
}
|
|
351
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Represents a collected GraphQL operation with metadata.
|
|
400
|
+
* Used internally by the Collector - decoupled from MCP tool schemas.
|
|
401
|
+
*/
|
|
402
|
+
type CollectorOperation = {
|
|
403
|
+
/** The GraphQL operation name */
|
|
404
|
+
name: string;
|
|
405
|
+
/** The type of operation */
|
|
406
|
+
type: 'query' | 'mutation';
|
|
407
|
+
/** Absolute path to the file containing the operation */
|
|
408
|
+
filePath: string;
|
|
409
|
+
/** Path to the file relative to the project root */
|
|
410
|
+
relativeFilePath: string;
|
|
411
|
+
/** Whether the operation has any variables */
|
|
412
|
+
hasVariables: boolean;
|
|
413
|
+
/** Whether the operation requires variables (has non-null variables) */
|
|
414
|
+
needsVariables: boolean;
|
|
415
|
+
/** TypeScript type name for the operation variables */
|
|
416
|
+
variablesTypeName: string;
|
|
417
|
+
/** TypeScript type name for the operation response */
|
|
418
|
+
responseTypeName: string;
|
|
419
|
+
/** The GraphQL source code of just this operation (no fragments) */
|
|
420
|
+
source: string;
|
|
421
|
+
/** The full GraphQL source including all fragment dependencies */
|
|
422
|
+
sourceFull: string;
|
|
423
|
+
};
|
|
424
|
+
/**
|
|
425
|
+
* Represents a collected GraphQL fragment with metadata.
|
|
426
|
+
* Used internally by the Collector - decoupled from MCP tool schemas.
|
|
427
|
+
*/
|
|
428
|
+
type CollectorFragment = {
|
|
429
|
+
/** The fragment name */
|
|
430
|
+
name: string;
|
|
431
|
+
/** The GraphQL type this fragment is defined on */
|
|
432
|
+
typeName: string;
|
|
433
|
+
/** Absolute path to the file containing the fragment */
|
|
434
|
+
filePath: string;
|
|
435
|
+
/** Path to the file relative to the project root */
|
|
436
|
+
relativeFilePath: string;
|
|
437
|
+
/** The GraphQL source code of just this fragment (no dependencies) */
|
|
438
|
+
source: string;
|
|
439
|
+
/** The full GraphQL source including all fragment dependencies */
|
|
440
|
+
sourceFull: string;
|
|
441
|
+
/** Names of other fragments this fragment depends on */
|
|
442
|
+
dependencies: string[];
|
|
443
|
+
};
|
|
444
|
+
|
|
352
445
|
type CollectorWatchEventResult = {
|
|
353
446
|
hasChanged: boolean;
|
|
354
447
|
affectedOperations: string[];
|
|
@@ -391,6 +484,14 @@ declare class Collector {
|
|
|
391
484
|
* The generated template contents.
|
|
392
485
|
*/
|
|
393
486
|
private templateResult;
|
|
487
|
+
/**
|
|
488
|
+
* Operations with full metadata for MCP tools.
|
|
489
|
+
*/
|
|
490
|
+
private operations;
|
|
491
|
+
/**
|
|
492
|
+
* Fragments with full metadata for MCP tools.
|
|
493
|
+
*/
|
|
494
|
+
private fragments;
|
|
394
495
|
private isInitialised;
|
|
395
496
|
constructor(schema: GraphQLSchema, helper: ModuleHelper);
|
|
396
497
|
reset(): Promise<void>;
|
|
@@ -457,6 +558,22 @@ declare class Collector {
|
|
|
457
558
|
* Get the hook documents.
|
|
458
559
|
*/
|
|
459
560
|
getHookFiles(): string[];
|
|
561
|
+
/**
|
|
562
|
+
* Get all operations with metadata (for MCP tools).
|
|
563
|
+
*/
|
|
564
|
+
getOperations(): CollectorOperation[];
|
|
565
|
+
/**
|
|
566
|
+
* Get all fragments for a specific GraphQL type (for MCP tools).
|
|
567
|
+
*/
|
|
568
|
+
getFragmentsForType(typeName: string): CollectorFragment[];
|
|
569
|
+
/**
|
|
570
|
+
* Get all fragments (for MCP tools).
|
|
571
|
+
*/
|
|
572
|
+
getFragments(): CollectorFragment[];
|
|
573
|
+
/**
|
|
574
|
+
* Get a fragment by name (for MCP tools).
|
|
575
|
+
*/
|
|
576
|
+
getFragment(name: string): CollectorFragment | undefined;
|
|
460
577
|
}
|
|
461
578
|
|
|
462
579
|
/**
|
package/dist/utils.d.mts
CHANGED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# useAsyncGraphqlQuery
|
|
2
|
+
|
|
3
|
+
This composable is a wrapper around Nuxt's
|
|
4
|
+
[useAsyncData](https://nuxt.com/docs/api/composables/use-async-data) that
|
|
5
|
+
executes a GraphQL query via the middleware. It provides SSR-compatible,
|
|
6
|
+
reactive data fetching with automatic refetching when variables change.
|
|
7
|
+
|
|
8
|
+
## Basic Usage
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
const { data } = await useAsyncGraphqlQuery('users')
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
This is equivalent to:
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
const { data } = await useAsyncData(() => useGraphqlQuery('users'))
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## With Variables
|
|
21
|
+
|
|
22
|
+
Pass variables as the second argument:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
const { data } = await useAsyncGraphqlQuery('filmById', { id: '123' })
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Reactive Variables
|
|
29
|
+
|
|
30
|
+
When variables are wrapped in a `computed` ref, the query automatically
|
|
31
|
+
refetches when variables change:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import type { UserByIdQueryVariables } from '#graphql-operations'
|
|
35
|
+
|
|
36
|
+
const route = useRoute()
|
|
37
|
+
|
|
38
|
+
const variables = computed<UserByIdQueryVariables>(() => {
|
|
39
|
+
return {
|
|
40
|
+
id: route.params.id.toString(),
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const { data } = await useAsyncGraphqlQuery('userById', variables)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The composable automatically adds reactive variables to the `watch` option of
|
|
48
|
+
`useAsyncData`, triggering a refetch whenever the variables change.
|
|
49
|
+
|
|
50
|
+
## Options
|
|
51
|
+
|
|
52
|
+
The third argument accepts options that extend
|
|
53
|
+
[AsyncDataOptions](https://nuxt.com/docs/api/composables/use-async-data#params)
|
|
54
|
+
with additional GraphQL-specific settings:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const { data } = await useAsyncGraphqlQuery('users', null, {
|
|
58
|
+
// All useAsyncData options are supported
|
|
59
|
+
transform: (response) => response.data.users,
|
|
60
|
+
default: () => [],
|
|
61
|
+
immediate: true,
|
|
62
|
+
server: true,
|
|
63
|
+
|
|
64
|
+
// GraphQL-specific options
|
|
65
|
+
graphqlCaching: { client: true },
|
|
66
|
+
fetchOptions: { headers: { 'x-custom': 'value' } },
|
|
67
|
+
clientContext: { language: 'en' },
|
|
68
|
+
})
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### transform
|
|
72
|
+
|
|
73
|
+
Transform the response before storing it in `data`. This is useful to extract
|
|
74
|
+
nested data or modify the response structure:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const { data: users } = await useAsyncGraphqlQuery('users', null, {
|
|
78
|
+
transform: (response) => {
|
|
79
|
+
// response.data is UsersQuery
|
|
80
|
+
return response.data.users
|
|
81
|
+
},
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
// users.value is now the users array directly
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### graphqlCaching
|
|
88
|
+
|
|
89
|
+
Enable client-side caching for this query. Requires `clientCache.enabled: true`
|
|
90
|
+
in module options. See [Caching](/features/caching) for more details.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const { data } = await useAsyncGraphqlQuery('users', null, {
|
|
94
|
+
graphqlCaching: {
|
|
95
|
+
client: true,
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
When enabled:
|
|
101
|
+
|
|
102
|
+
- Results are cached in memory using an LRU cache
|
|
103
|
+
- Subsequent calls with the same variables return cached data
|
|
104
|
+
- Cache survives client-side navigation
|
|
105
|
+
- SSR payload data is preserved during hydration
|
|
106
|
+
|
|
107
|
+
### fetchOptions
|
|
108
|
+
|
|
109
|
+
Pass options to the underlying `$fetch` call to the middleware endpoint:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
const { data } = await useAsyncGraphqlQuery('users', null, {
|
|
113
|
+
fetchOptions: {
|
|
114
|
+
headers: {
|
|
115
|
+
authorization: `Bearer ${token}`,
|
|
116
|
+
},
|
|
117
|
+
timeout: 5000,
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### clientContext
|
|
123
|
+
|
|
124
|
+
Override or extend the global client context for this specific request. Values
|
|
125
|
+
here take precedence over those defined in
|
|
126
|
+
[defineGraphqlClientOptions](/configuration/client-options):
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
const { data } = await useAsyncGraphqlQuery('users', null, {
|
|
130
|
+
clientContext: {
|
|
131
|
+
language: 'de', // Override the global language for this request
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Return Value
|
|
137
|
+
|
|
138
|
+
Returns the same object as
|
|
139
|
+
[useAsyncData](https://nuxt.com/docs/api/composables/use-async-data#return-values):
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
const {
|
|
143
|
+
data, // Ref<T | undefined> - The response data
|
|
144
|
+
pending, // Ref<boolean> - Loading state
|
|
145
|
+
error, // Ref<Error | undefined> - Error if request failed
|
|
146
|
+
status, // Ref<'idle' | 'pending' | 'success' | 'error'>
|
|
147
|
+
refresh, // () => Promise<void> - Manually refetch data
|
|
148
|
+
execute, // () => Promise<void> - Same as refresh
|
|
149
|
+
clear, // () => void - Clear data and error
|
|
150
|
+
} = await useAsyncGraphqlQuery('users')
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Type Safety
|
|
154
|
+
|
|
155
|
+
The composable is fully typed based on your GraphQL operations:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// Variables are type-checked
|
|
159
|
+
const { data } = await useAsyncGraphqlQuery('userById', {
|
|
160
|
+
id: '123', // ✅ Correct type
|
|
161
|
+
// id: 123 // ❌ Type error: expected string
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
// Response data is typed
|
|
165
|
+
if (data.value) {
|
|
166
|
+
console.log(data.value.data.userById?.name) // ✅ Autocomplete works
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Operations that require variables will show a type error if variables are
|
|
171
|
+
omitted:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// ❌ Type error: variables required
|
|
175
|
+
const { data } = await useAsyncGraphqlQuery('userById')
|
|
176
|
+
|
|
177
|
+
// ✅ Correct
|
|
178
|
+
const { data } = await useAsyncGraphqlQuery('userById', { id: '123' })
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Hot Module Reloading
|
|
182
|
+
|
|
183
|
+
During development, the composable automatically refetches data when the
|
|
184
|
+
underlying GraphQL document or any used fragments change. This provides instant
|
|
185
|
+
feedback when modifying queries.
|
|
186
|
+
|
|
187
|
+
## Important Considerations
|
|
188
|
+
|
|
189
|
+
### Execution Context
|
|
190
|
+
|
|
191
|
+
Like `useAsyncData`, this composable must be called in specific contexts:
|
|
192
|
+
|
|
193
|
+
- **Component setup function** - At the root level, not inside callbacks
|
|
194
|
+
- **Plugin setup** - During plugin initialization
|
|
195
|
+
- **Route middleware** - During navigation
|
|
196
|
+
- **Other composables** - When called from a composable that follows these rules
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// ✅ Correct - at root of setup
|
|
200
|
+
const { data } = await useAsyncGraphqlQuery('users')
|
|
201
|
+
|
|
202
|
+
// ❌ Wrong - inside a callback
|
|
203
|
+
const onClick = async () => {
|
|
204
|
+
// This won't work correctly with SSR
|
|
205
|
+
const { data } = await useAsyncGraphqlQuery('users')
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
For fetching data inside event handlers or callbacks, use
|
|
210
|
+
[useGraphqlQuery](/composables/useGraphqlQuery) instead.
|
|
211
|
+
|
|
212
|
+
### Unique Keys
|
|
213
|
+
|
|
214
|
+
The composable automatically generates a unique key for `useAsyncData` based on:
|
|
215
|
+
|
|
216
|
+
- The operation name
|
|
217
|
+
- A hash of the variables
|
|
218
|
+
|
|
219
|
+
This ensures that different variable combinations are cached separately and
|
|
220
|
+
multiple instances don't conflict.
|
|
221
|
+
|
|
222
|
+
## Examples
|
|
223
|
+
|
|
224
|
+
### Pagination
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import type { UsersPaginatedQueryVariables } from '#graphql-operations'
|
|
228
|
+
|
|
229
|
+
const page = ref(1)
|
|
230
|
+
const limit = 10
|
|
231
|
+
|
|
232
|
+
const variables = computed<UsersPaginatedQueryVariables>(() => ({
|
|
233
|
+
offset: (page.value - 1) * limit,
|
|
234
|
+
limit,
|
|
235
|
+
}))
|
|
236
|
+
|
|
237
|
+
const { data, pending } = await useAsyncGraphqlQuery(
|
|
238
|
+
'usersPaginated',
|
|
239
|
+
variables,
|
|
240
|
+
{
|
|
241
|
+
transform: (response) => response.data.users,
|
|
242
|
+
},
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
function nextPage() {
|
|
246
|
+
page.value++
|
|
247
|
+
// Query automatically refetches due to reactive variables
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Conditional Fetching
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
const userId = ref<string | null>(null)
|
|
255
|
+
|
|
256
|
+
const variables = computed(() => (userId.value ? { id: userId.value } : null))
|
|
257
|
+
|
|
258
|
+
const { data } = await useAsyncGraphqlQuery('userById', variables, {
|
|
259
|
+
// Don't fetch until we have a userId
|
|
260
|
+
immediate: false,
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
// Later, when userId is set:
|
|
264
|
+
userId.value = '123'
|
|
265
|
+
// The query will now execute
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Error Handling
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
const { data, error, refresh } = await useAsyncGraphqlQuery('users')
|
|
272
|
+
|
|
273
|
+
// Check for errors
|
|
274
|
+
if (error.value) {
|
|
275
|
+
console.error('Query failed:', error.value.message)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Retry on error
|
|
279
|
+
async function retry() {
|
|
280
|
+
await refresh()
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### With Default Value
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
interface User {
|
|
288
|
+
id: string
|
|
289
|
+
name: string
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const { data } = await useAsyncGraphqlQuery('users', null, {
|
|
293
|
+
transform: (response) => response.data.users ?? [],
|
|
294
|
+
default: () => [] as User[],
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
// data.value is never undefined, defaults to empty array
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Comparison with useGraphqlQuery
|
|
301
|
+
|
|
302
|
+
| Feature | useAsyncGraphqlQuery | useGraphqlQuery |
|
|
303
|
+
| ------------------ | -------------------- | ------------------------------- |
|
|
304
|
+
| SSR Support | ✅ Built-in | ✅ When wrapped in useAsyncData |
|
|
305
|
+
| Reactive Variables | ✅ Automatic refetch | ❌ Manual handling required |
|
|
306
|
+
| Returns | AsyncData object | Promise with response |
|
|
307
|
+
| Use in Callbacks | ❌ Not recommended | ✅ Works anywhere |
|
|
308
|
+
| Caching | ✅ With useAsyncData | ✅ With graphqlCaching option |
|
|
309
|
+
| HMR Refresh | ✅ Automatic | ❌ Manual |
|
|
310
|
+
|
|
311
|
+
Choose `useAsyncGraphqlQuery` for page-level data fetching with SSR support.
|
|
312
|
+
Choose `useGraphqlQuery` for imperative fetching in event handlers, plugins, or
|
|
313
|
+
when you need more control.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# useGraphqlMutation
|
|
2
|
+
|
|
3
|
+
Same usage like useGraphqlQuery, but for mutations:
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const { data } = await useGraphqlMutation('trackVisit')
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
const { data } = await useGraphqlMutation('addToCart', { id: '456' })
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Custom Fetch Options
|
|
14
|
+
|
|
15
|
+
In addition to the fetch options set when using
|
|
16
|
+
[/composables/useGraphqlState](useGraphqlState), you can also set fetch options
|
|
17
|
+
here (which will override properties set by the useGraphqlState composable):
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
const { data } = await useGraphqlMutation(
|
|
21
|
+
'addToCart',
|
|
22
|
+
{ id: '456' },
|
|
23
|
+
{
|
|
24
|
+
onRequest(options) {
|
|
25
|
+
options.headers['Custom-Special-Header'] = 'Foobar'
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
)
|
|
29
|
+
```
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# useGraphqlQuery
|
|
2
|
+
|
|
3
|
+
Executes a query using $fetch and returns the response.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const { data } = await useGraphqlQuery('films')
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Variables can be passed as the second argument:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
const { data } = await useGraphqlQuery('filmById', { id: '123' })
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Arguments are properly type checked:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// ✅ Everyting correct.
|
|
19
|
+
const { data } = await useGraphqlQuery('filmById', { id: '123' })
|
|
20
|
+
|
|
21
|
+
// ❌ Wrong variable type.
|
|
22
|
+
const { data } = await useGraphqlQuery('filmById', { id: 123 })
|
|
23
|
+
|
|
24
|
+
// ❌ Missing variables.
|
|
25
|
+
const { data } = await useGraphqlQuery('filmById')
|
|
26
|
+
|
|
27
|
+
// ❌ Wrong query name.
|
|
28
|
+
const { data } = await useGraphqlQuery('getFilmById', { id: '123' })
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The return value is also properly typed based on the query response:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
const { data } = await useGraphqlQuery('filmById', { id: '123' })
|
|
35
|
+
|
|
36
|
+
// ❌ Property does not exist.
|
|
37
|
+
console.log(data.films)
|
|
38
|
+
|
|
39
|
+
// ❌ Object is possibly null.
|
|
40
|
+
console.log(data.allFilms.films)
|
|
41
|
+
|
|
42
|
+
// ✅ Everyting correct.
|
|
43
|
+
console.log(data.allFilms?.films)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Object Syntax
|
|
47
|
+
|
|
48
|
+
You can also provide a single argument which is an object. One use case might be
|
|
49
|
+
to have different query names depending on some context.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
const { data } = await useGraphqlQuery({
|
|
53
|
+
name: 'filmById',
|
|
54
|
+
variables: { id: '123' },
|
|
55
|
+
})
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Fetch Options
|
|
59
|
+
|
|
60
|
+
You can also pass an object instead, which allows you to additionally provide
|
|
61
|
+
fetch options for the request:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
const { data } = await useGraphqlQuery({
|
|
65
|
+
name: 'filmById',
|
|
66
|
+
variables: { id: '123' },
|
|
67
|
+
fetchOptions: {
|
|
68
|
+
headers: {
|
|
69
|
+
authorization: 'foobar',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# useGraphqlState
|
|
2
|
+
|
|
3
|
+
This composable allows you to set fetch options for the useGraphqlQuery,
|
|
4
|
+
useAsyncGraphqlQuery and useGraphqlMutation composables. One common use case is
|
|
5
|
+
to pass custom request headers to the GraphQL middleware request.
|
|
6
|
+
|
|
7
|
+
::: warning
|
|
8
|
+
|
|
9
|
+
The state is only used for requests made from within a Nuxt app context (e.g.
|
|
10
|
+
pages, route middleware, etc.). Usually this is used to "pass" information from
|
|
11
|
+
the client/browser context to the middleware.
|
|
12
|
+
|
|
13
|
+
:::
|
|
14
|
+
|
|
15
|
+
::: code-group
|
|
16
|
+
|
|
17
|
+
```typescript [plugins/graphqlState.ts]
|
|
18
|
+
export default defineNuxtPlugin({
|
|
19
|
+
name: 'my-state-plugin',
|
|
20
|
+
// Makes sure that your plugin is executed after this plugin.
|
|
21
|
+
// If it were to run before, then `state` would be null.
|
|
22
|
+
dependsOn: ['nuxt-graphql-middleware-provide-state'],
|
|
23
|
+
setup() {
|
|
24
|
+
const state = useGraphqlState()
|
|
25
|
+
|
|
26
|
+
// This is nullable because it's injected by a plugin.
|
|
27
|
+
if (!state) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const token = useToken()
|
|
32
|
+
|
|
33
|
+
// Set fetch options for all GraphQL queries and mutations.
|
|
34
|
+
state.fetchOptions = {
|
|
35
|
+
// Static header that should be the same for all requests.
|
|
36
|
+
headers: {
|
|
37
|
+
CustomHeader: 'foobar',
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
// Header value is evaluated on every request.
|
|
41
|
+
onRequest({ options, request }) {
|
|
42
|
+
options.headers.set('x-auth-token', token.value)
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
// Handle headers sent from the middleware to the Nuxt app (client or server side).
|
|
46
|
+
onResponse(result) {
|
|
47
|
+
const headers = result.response?.headers
|
|
48
|
+
const newToken = headers.get('x-auth-token')
|
|
49
|
+
if (newToken) {
|
|
50
|
+
token.value = newToken
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
})
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
:::
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# useGraphqlUploadMutation
|
|
2
|
+
|
|
3
|
+
This composable is only available when setting `enableFileUploads` to `true` in
|
|
4
|
+
the module's configuration. It allows to upload files inside a mutation. The
|
|
5
|
+
implementation follows the
|
|
6
|
+
[GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec),
|
|
7
|
+
which is supported by a lot of GraphQL servers.
|
|
8
|
+
|
|
9
|
+
## Basic Usage
|
|
10
|
+
|
|
11
|
+
The composable handles the FormData part, so files can be directly provided
|
|
12
|
+
inside the mutation variables:
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
async function upload(image: File) {
|
|
16
|
+
const data = await useGraphqlUploadMutation('uploadImage', {
|
|
17
|
+
image,
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Multiple files are also supported, both in the same field or in deeply nested
|
|
23
|
+
fields:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
const files = ref<File[]>([])
|
|
27
|
+
|
|
28
|
+
const data = await useGraphqlUploadMutation('uploadFiles', {
|
|
29
|
+
elements: files.value.map((file) => {
|
|
30
|
+
return {
|
|
31
|
+
name: file.name,
|
|
32
|
+
file: file,
|
|
33
|
+
}
|
|
34
|
+
}),
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Server Route
|
|
39
|
+
|
|
40
|
+
To support file uploads, when the feature is enabled, an additional server route
|
|
41
|
+
is added:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
/api/graphql_middleware/upload/[name_of_mutation]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This route expects a `multipart/form-data` request. The
|
|
48
|
+
`useGraphqlUploadMutation` composable makes sure the data is sent in the correct
|
|
49
|
+
format.
|
|
50
|
+
|
|
51
|
+
The server route does not perform any validations on the provided data, for
|
|
52
|
+
example there is no file size limitation. This should be handled separately, for
|
|
53
|
+
example on the web server or by implementing a custom Nitro middleware.
|
|
54
|
+
|
|
55
|
+
In addition, the route does not save any of the files. It only validates that a
|
|
56
|
+
valid, existing mutation is used. It also makes sure that it's not possible to
|
|
57
|
+
send arbitrary operations.
|