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.
- 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/{gyQx9VSj.js → D95LLO0l.js} +1 -1
- package/dist/client/_nuxt/{DyBqp5hr.js → DZ-uq6Vd.js} +1 -1
- package/dist/client/_nuxt/DrXVleME.js +4 -0
- package/dist/client/_nuxt/{BPB7Y782.js → Dx-h1-qv.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/efa6c0a0-833e-4e5a-bc2d-ba9d0d3e4562.json +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.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/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/handler.d.ts +2 -0
- package/dist/runtime/server/mcp/handler.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/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 +101 -44
- package/dist/client/_nuxt/Bkyil6hz.js +0 -2
- package/dist/client/_nuxt/C9p-Va5c.js +0 -29
- package/dist/client/_nuxt/builds/meta/77b9a31d-6d5c-4e28-9320-cbd287a46883.json +0 -1
- 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
|
+
:::
|