nuxt-graphql-middleware 5.2.3 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +2 -0
  2. package/dist/client/200.html +1 -1
  3. package/dist/client/404.html +1 -1
  4. package/dist/client/_nuxt/CqRv5mwS.js +2 -0
  5. package/dist/client/_nuxt/{gyQx9VSj.js → D95LLO0l.js} +1 -1
  6. package/dist/client/_nuxt/{DyBqp5hr.js → DZ-uq6Vd.js} +1 -1
  7. package/dist/client/_nuxt/DrXVleME.js +4 -0
  8. package/dist/client/_nuxt/{BPB7Y782.js → Dx-h1-qv.js} +1 -1
  9. package/dist/client/_nuxt/builds/latest.json +1 -1
  10. package/dist/client/_nuxt/builds/meta/efa6c0a0-833e-4e5a-bc2d-ba9d0d3e4562.json +1 -0
  11. package/dist/client/index.html +1 -1
  12. package/dist/module.d.mts +1 -1
  13. package/dist/module.json +3 -3
  14. package/dist/module.mjs +1526 -70
  15. package/dist/runtime/components/CodeFrame.d.vue.ts +8 -0
  16. package/dist/runtime/components/CodeFrame.vue.d.ts +2 -1
  17. package/dist/runtime/components/DevModeOverlay.d.vue.ts +4 -0
  18. package/dist/runtime/components/DevModeOverlay.vue.d.ts +2 -1
  19. package/dist/runtime/components/ErrorExtensions.d.vue.ts +6 -0
  20. package/dist/runtime/components/ErrorExtensions.vue.d.ts +2 -1
  21. package/dist/runtime/components/ErrorGroup.d.vue.ts +10 -0
  22. package/dist/runtime/components/ErrorGroup.vue.d.ts +2 -1
  23. package/dist/runtime/helpers/composables.d.ts +1 -40
  24. package/dist/runtime/helpers/composables.js +3 -12
  25. package/dist/runtime/helpers/shared-types.d.ts +40 -0
  26. package/dist/runtime/helpers/shared-types.js +12 -0
  27. package/dist/runtime/server/api/doRequest.d.ts +2 -0
  28. package/dist/runtime/server/api/doRequest.js +18 -0
  29. package/dist/runtime/server/helpers/index.js +1 -1
  30. package/dist/runtime/server/mcp/handler.d.ts +2 -0
  31. package/dist/runtime/server/mcp/handler.js +63 -0
  32. package/dist/runtime/server/mcp/resources/docs.d.ts +2 -0
  33. package/dist/runtime/server/mcp/resources/docs.js +36 -0
  34. package/dist/runtime/server/mcp/tools/fragments-get/index.d.ts +1 -0
  35. package/dist/runtime/server/mcp/tools/fragments-get/index.js +35 -0
  36. package/dist/runtime/server/mcp/tools/fragments-get/types.d.ts +20 -0
  37. package/dist/runtime/server/mcp/tools/fragments-get/types.js +13 -0
  38. package/dist/runtime/server/mcp/tools/fragments-get-source/index.d.ts +1 -0
  39. package/dist/runtime/server/mcp/tools/fragments-get-source/index.js +34 -0
  40. package/dist/runtime/server/mcp/tools/fragments-get-source/types.d.ts +10 -0
  41. package/dist/runtime/server/mcp/tools/fragments-get-source/types.js +9 -0
  42. package/dist/runtime/server/mcp/tools/fragments-list/index.d.ts +1 -0
  43. package/dist/runtime/server/mcp/tools/fragments-list/index.js +36 -0
  44. package/dist/runtime/server/mcp/tools/fragments-list/types.d.ts +20 -0
  45. package/dist/runtime/server/mcp/tools/fragments-list/types.js +14 -0
  46. package/dist/runtime/server/mcp/tools/fragments-list-for-type/index.d.ts +1 -0
  47. package/dist/runtime/server/mcp/tools/fragments-list-for-type/index.js +39 -0
  48. package/dist/runtime/server/mcp/tools/fragments-list-for-type/types.d.ts +31 -0
  49. package/dist/runtime/server/mcp/tools/fragments-list-for-type/types.js +23 -0
  50. package/dist/runtime/server/mcp/tools/graphql-execute/index.d.ts +1 -0
  51. package/dist/runtime/server/mcp/tools/graphql-execute/index.js +59 -0
  52. package/dist/runtime/server/mcp/tools/module-get-config/index.d.ts +1 -0
  53. package/dist/runtime/server/mcp/tools/module-get-config/index.js +23 -0
  54. package/dist/runtime/server/mcp/tools/module-get-config/types.d.ts +39 -0
  55. package/dist/runtime/server/mcp/tools/module-get-config/types.js +26 -0
  56. package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/index.d.ts +1 -0
  57. package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/index.js +36 -0
  58. package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/types.d.ts +49 -0
  59. package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/types.js +24 -0
  60. package/dist/runtime/server/mcp/tools/operations-execute/index.d.ts +1 -0
  61. package/dist/runtime/server/mcp/tools/operations-execute/index.js +63 -0
  62. package/dist/runtime/server/mcp/tools/operations-get/index.d.ts +1 -0
  63. package/dist/runtime/server/mcp/tools/operations-get/index.js +40 -0
  64. package/dist/runtime/server/mcp/tools/operations-get/types.d.ts +32 -0
  65. package/dist/runtime/server/mcp/tools/operations-get/types.js +18 -0
  66. package/dist/runtime/server/mcp/tools/operations-get-field-usage/index.d.ts +1 -0
  67. package/dist/runtime/server/mcp/tools/operations-get-field-usage/index.js +39 -0
  68. package/dist/runtime/server/mcp/tools/operations-get-field-usage/types.d.ts +38 -0
  69. package/dist/runtime/server/mcp/tools/operations-get-field-usage/types.js +19 -0
  70. package/dist/runtime/server/mcp/tools/operations-get-source/index.d.ts +1 -0
  71. package/dist/runtime/server/mcp/tools/operations-get-source/index.js +39 -0
  72. package/dist/runtime/server/mcp/tools/operations-get-source/types.d.ts +10 -0
  73. package/dist/runtime/server/mcp/tools/operations-get-source/types.js +9 -0
  74. package/dist/runtime/server/mcp/tools/operations-list/index.d.ts +1 -0
  75. package/dist/runtime/server/mcp/tools/operations-list/index.js +46 -0
  76. package/dist/runtime/server/mcp/tools/operations-list/types.d.ts +53 -0
  77. package/dist/runtime/server/mcp/tools/operations-list/types.js +33 -0
  78. package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/index.d.ts +1 -0
  79. package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/index.js +37 -0
  80. package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/types.d.ts +24 -0
  81. package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/types.js +16 -0
  82. package/dist/runtime/server/mcp/tools/schema-get-type/index.d.ts +1 -0
  83. package/dist/runtime/server/mcp/tools/schema-get-type/index.js +31 -0
  84. package/dist/runtime/server/mcp/tools/schema-get-type/types.d.ts +112 -0
  85. package/dist/runtime/server/mcp/tools/schema-get-type/types.js +45 -0
  86. package/dist/runtime/server/mcp/tools/schema-get-type-definition/index.d.ts +1 -0
  87. package/dist/runtime/server/mcp/tools/schema-get-type-definition/index.js +33 -0
  88. package/dist/runtime/server/mcp/tools/schema-get-type-definition/types.d.ts +10 -0
  89. package/dist/runtime/server/mcp/tools/schema-get-type-definition/types.js +9 -0
  90. package/dist/runtime/server/mcp/tools/schema-get-type-usage/index.d.ts +1 -0
  91. package/dist/runtime/server/mcp/tools/schema-get-type-usage/index.js +35 -0
  92. package/dist/runtime/server/mcp/tools/schema-get-type-usage/types.d.ts +39 -0
  93. package/dist/runtime/server/mcp/tools/schema-get-type-usage/types.js +17 -0
  94. package/dist/runtime/server/mcp/tools/schema-get-union-members/index.d.ts +1 -0
  95. package/dist/runtime/server/mcp/tools/schema-get-union-members/index.js +35 -0
  96. package/dist/runtime/server/mcp/tools/schema-get-union-members/types.d.ts +24 -0
  97. package/dist/runtime/server/mcp/tools/schema-get-union-members/types.js +16 -0
  98. package/dist/runtime/server/mcp/tools/schema-list-types/index.d.ts +1 -0
  99. package/dist/runtime/server/mcp/tools/schema-list-types/index.js +37 -0
  100. package/dist/runtime/server/mcp/tools/schema-list-types/types.d.ts +53 -0
  101. package/dist/runtime/server/mcp/tools/schema-list-types/types.js +21 -0
  102. package/dist/runtime/server/mcp/tools/schema-validate-document/index.d.ts +1 -0
  103. package/dist/runtime/server/mcp/tools/schema-validate-document/index.js +31 -0
  104. package/dist/runtime/server/mcp/tools/schema-validate-document/types.d.ts +26 -0
  105. package/dist/runtime/server/mcp/tools/schema-validate-document/types.js +21 -0
  106. package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/index.d.ts +1 -0
  107. package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/index.js +36 -0
  108. package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/types.d.ts +49 -0
  109. package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/types.js +24 -0
  110. package/dist/runtime/server/mcp/utils/index.d.ts +48 -0
  111. package/dist/runtime/server/mcp/utils/index.js +35 -0
  112. package/dist/runtime/server/utils/useGraphqlMutation.d.ts +1 -1
  113. package/dist/runtime/server/utils/useGraphqlMutation.js +1 -1
  114. package/dist/runtime/server/utils/useGraphqlQuery.d.ts +1 -1
  115. package/dist/runtime/server/utils/useGraphqlQuery.js +1 -1
  116. package/dist/shared/{nuxt-graphql-middleware.ct2xvPoD.d.mts → nuxt-graphql-middleware.COufMnWs.d.mts} +119 -2
  117. package/dist/utils.d.mts +1 -1
  118. package/docs/composables/useAsyncGraphqlQuery.md +313 -0
  119. package/docs/composables/useGraphqlMutation.md +29 -0
  120. package/docs/composables/useGraphqlQuery.md +73 -0
  121. package/docs/composables/useGraphqlState.md +58 -0
  122. package/docs/composables/useGraphqlUploadMutation.md +57 -0
  123. package/docs/configuration/client-options.md +121 -0
  124. package/docs/configuration/module-hooks.md +112 -0
  125. package/docs/configuration/module-utils.md +53 -0
  126. package/docs/configuration/module.md +415 -0
  127. package/docs/configuration/runtime-config.md +23 -0
  128. package/docs/configuration/server-options.md +230 -0
  129. package/package.json +101 -44
  130. package/dist/client/_nuxt/Bkyil6hz.js +0 -2
  131. package/dist/client/_nuxt/C9p-Va5c.js +0 -29
  132. package/dist/client/_nuxt/builds/meta/77b9a31d-6d5c-4e28-9320-cbd287a46883.json +0 -1
  133. package/dist/runtime/server/tsconfig.json +0 -3
@@ -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.
@@ -0,0 +1,121 @@
1
+ # Client Options
2
+
3
+ `nuxt-graphql-middleware` will look for a file called
4
+ `graphqlMiddleware.clientOptions.ts` in your app dir. This file can export so
5
+ called "client options" which are used when _making a request to the GraphQL
6
+ middleware_.
7
+
8
+ ::: warning
9
+
10
+ Note that the client options are only used in a **Nuxt app context** - they are
11
+ not used when using `useGraphqlQuery` or other utils in a **Nitro context** such
12
+ as event handlers.
13
+
14
+ :::
15
+
16
+ ## Defining Client Options
17
+
18
+ When using a composable such as `useGraphqlQuery`, behind the scenes it will use
19
+ `$fetch` to make a request to the GraphQL middleware server route. Sometimes
20
+ it's useful to pass some additional context with this request that can then be
21
+ used on the server.
22
+
23
+ Similar to [serverOptions](/configuration/server-options), you can create a file
24
+ called `graphqlMiddleware.clientOptions.ts` in your `app` directory (usually
25
+ `<rootDir>/app`).
26
+
27
+ ::: code-group
28
+
29
+ ```typescript [~/app/graphqlMiddleware.clientOptions.ts]
30
+ import { defineGraphqlClientOptions } from 'nuxt-graphql-middleware/client-options'
31
+
32
+ export default defineGraphqlClientOptions({})
33
+ ```
34
+
35
+ :::
36
+
37
+ ## Defining Client Context
38
+
39
+ Implement the `buildClientContext()` method to return an object with string
40
+ values.
41
+
42
+ ::: code-group
43
+
44
+ ```typescript [~/app/graphqlMiddleware.clientOptions.ts]
45
+ import { defineGraphqlClientOptions } from 'nuxt-graphql-middleware/client-options'
46
+
47
+ export default defineGraphqlClientOptions<{
48
+ language: string
49
+ country: string
50
+ }>({
51
+ buildClientContext() {
52
+ const language = useCurrentLanguage()
53
+ const country = useCurrentCountry()
54
+ return {
55
+ language: language.value,
56
+ country: country.value,
57
+ }
58
+ },
59
+ })
60
+ ```
61
+
62
+ :::
63
+
64
+ ::: info
65
+
66
+ By passing a generic in `defineGraphqlClientOptions` you can define the type of
67
+ your context object.
68
+
69
+ :::
70
+
71
+ Now everytime a request to the middleware is made with a composable such as
72
+ `useGraphqlQuery`, the composable will call the `buildClientContext` method to
73
+ get the current context. It then maps each property of the returned object to a
74
+ query parameter while prefixing the property to prevent collisions with
75
+ potential query parameters from GraphQL variables.
76
+
77
+ So for example, when making a GraphQL query like so:
78
+
79
+ ```typescript
80
+ const data = await useGraphqlQuery('loadProduct', {
81
+ id: '123',
82
+ })
83
+ ```
84
+
85
+ The composable will make a fetch request to this URL.
86
+
87
+ `/api/graphql_middleware/loadProduct?id=123&__gqlc_language=en&__gqlc_country=US`
88
+
89
+ Both the `language` and `country` properties we returned in the object in
90
+ `buildClientContext()` are appended as prefixed query parameters.
91
+
92
+ ## Using Client Context
93
+
94
+ On the server you can then access this client context from within all
95
+ [serverOptions](/configuration/server-options) methods:
96
+
97
+ ::: code-group
98
+
99
+ ```typescript [~/server/graphqlMiddleware.serverOptions.ts]
100
+ import { defineGraphqlServerOptions } from 'nuxt-graphql-middleware/server-options'
101
+
102
+ export default defineGraphqlServerOptions({
103
+ graphqlEndpoint(event, operation, operationName, context) {
104
+ // Use the language from the client context.
105
+ const language = context?.client?.language || 'en'
106
+ return `http://backend_server/${language}/graphql`
107
+ },
108
+
109
+ serverFetchOptions: function (event, _operation, operationName, context) {
110
+ // Pass the current country as a header when making a request to the
111
+ // GraphQL server.
112
+ return {
113
+ headers: {
114
+ 'x-current-country': context.client?.country || 'US',
115
+ },
116
+ }
117
+ },
118
+ })
119
+ ```
120
+
121
+ :::