Skip to content

Commit

Permalink
fix: client context param merging (#46)
Browse files Browse the repository at this point in the history
* test client options for server routes

* properly merge client options and fetch options
  • Loading branch information
dulnan authored Nov 15, 2024
1 parent 5fc2e59 commit 37d8f64
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 30 deletions.
8 changes: 8 additions & 0 deletions cypress/e2e/clientOptions.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,25 @@ describe('The clientOptions', () => {
cy.visit('/de')
cy.get('#nuxt-language').first().should('have.text', 'de')
cy.get('#response-language').first().should('have.text', 'de')
cy.get('#server-route-language').first().should('have.text', 'de')

cy.visit('/fr')
cy.get('#nuxt-language').first().should('have.text', 'fr')
cy.get('#response-language').first().should('have.text', 'fr')
cy.get('#server-route-language').first().should('have.text', 'fr')
})

it('are working correctly with SPA', () => {
cy.visit('/')
cy.get('#link-client-options').click()
cy.get('#nuxt-language').first().should('have.text', 'de')
cy.get('#response-language').first().should('have.text', 'de')
cy.get('#server-route-language').first().should('have.text', 'de')

cy.get('#lang-switch-fr').click()

cy.get('#nuxt-language').first().should('have.text', 'fr')
cy.get('#response-language').first().should('have.text', 'fr')
cy.get('#server-route-language').first().should('have.text', 'fr')
})
})
18 changes: 17 additions & 1 deletion playground/app/pages/[lang]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
<span id="response-language">{{ responseLanguage }}</span>
</p>

<p>
Current language via server route:
<span id="server-route-language">{{ serverRouteLanguage }}</span>
</p>

<ul>
<li v-for="lang in languages" :key="lang">
<NuxtLink
Expand All @@ -27,7 +32,12 @@
</template>

<script lang="ts" setup>
import { useAsyncGraphqlQuery, useCurrentLanguage, useRoute } from '#imports'
import {
useAsyncGraphqlQuery,
useCurrentLanguage,
useFetch,
useRoute,
} from '#imports'
const language = useCurrentLanguage()
const route = useRoute()
Expand All @@ -45,4 +55,10 @@ const { data: responseLanguage } = await useAsyncGraphqlQuery(
},
},
)
const { data: serverRouteLanguage } = await useFetch('/api/client-options', {
params: {
language: language.value,
},
})
</script>
21 changes: 21 additions & 0 deletions playground/server/api/client-options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useGraphqlQuery } from '#imports'
import { defineEventHandler, getQuery } from 'h3'

/**
* Custom server route that performs a GraphQL query and returns the mapped
* data.
*/
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const language = query.language as string
const data = await useGraphqlQuery({
name: 'testClientOptions',
variables: {
path: '/' + language,
},
clientContext: {
language,
},
})
return data.data.testClientOptions?.language
})
14 changes: 7 additions & 7 deletions src/runtime/composables/useAsyncGraphqlQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,23 +110,23 @@ export function useAsyncGraphqlQuery<
key,
() => {
const globalClientContext = clientOptions.buildClientContext
? encodeContext(clientOptions.buildClientContext())
? clientOptions.buildClientContext()
: {}

const clientContext = {
...globalClientContext,
...(asyncDataOptions.clientContext || {}),
}
return performRequest<ResponseType>(
'query',
name,
'get',
{
...(fetchOptions as any),
params: {
...(fetchOptions?.params || {}),
...buildRequestParams(unref(variables)),
...clientContext,
...encodeContext({
...globalClientContext,
...(asyncDataOptions.clientContext || {}),
}),
},
...(fetchOptions as any),
},
asyncDataOptions.graphqlCaching,
)
Expand Down
15 changes: 7 additions & 8 deletions src/runtime/composables/useGraphqlMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,18 @@ export function useGraphqlMutation<
]

const globalClientContext = clientOptions.buildClientContext
? encodeContext(clientOptions.buildClientContext())
? clientOptions.buildClientContext()
: {}

const clientContext = {
...globalClientContext,
...overrideClientContext,
}

return performRequest<R>('mutation', name, 'post', {
...fetchOptions,
body,
params: {
...clientContext,
...(fetchOptions.params || {}),
...encodeContext({
...globalClientContext,
...overrideClientContext,
}),
},
...fetchOptions,
})
}
15 changes: 7 additions & 8 deletions src/runtime/composables/useGraphqlQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,23 @@ export function useGraphqlQuery<
]

const globalClientContext = clientOptions.buildClientContext
? encodeContext(clientOptions.buildClientContext())
? clientOptions.buildClientContext()
: {}

const clientContext = {
...globalClientContext,
...overrideClientContext,
}

return performRequest<R>(
'query',
name,
'get',
{
...fetchOptions,
params: {
...(fetchOptions.params || {}),
...buildRequestParams(variables),
...clientContext,
...encodeContext({
...globalClientContext,
...overrideClientContext,
}),
},
...fetchOptions,
},
graphqlCaching,
)
Expand Down
8 changes: 5 additions & 3 deletions src/runtime/composables/useGraphqlUploadMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,20 @@ export function useGraphqlUploadMutation<
const formData = createFormData(variables)

const globalClientContext = clientOptions.buildClientContext
? encodeContext(clientOptions.buildClientContext())
? clientOptions.buildClientContext()
: {}

const clientContext = {
const clientContext = encodeContext({
...globalClientContext,
...overrideClientContext,
}
})

return $fetch<GraphqlResponse<R>>(getEndpoint('upload', name), {
...(state && state.fetchOptions ? (state.fetchOptions as any) : {}),
...(fetchOptions || {}),
params: {
...clientContext,
...(fetchOptions.params || {}),
},
method: 'POST',
body: formData,
Expand Down
7 changes: 5 additions & 2 deletions src/runtime/server/utils/useGraphqlMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ export function useGraphqlMutation<
]

return performRequest<R>('mutation', name, 'post', {
body,
params: encodeContext(clientContext),
...fetchOptions,
body,
params: {
...encodeContext(clientContext),
...(fetchOptions.params || {}),
},
})
}
3 changes: 2 additions & 1 deletion src/runtime/server/utils/useGraphqlQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ export function useGraphqlQuery<
]

return performRequest<R>('query', name, 'get', {
...fetchOptions,
params: {
...(fetchOptions.params || {}),
...buildRequestParams(variables),
...encodeContext(clientContext),
},
...fetchOptions,
})
}
116 changes: 116 additions & 0 deletions test/runtime/composables/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { describe, expect, test, vi } from 'vitest'
import { useGraphqlState } from './../../../src/runtime/composables/useGraphqlState'
import { useGraphqlMutation } from './../../../src/runtime/composables/useGraphqlMutation'
import { useGraphqlQuery } from './../../../src/runtime/composables/useGraphqlQuery'
import { useGraphqlUploadMutation } from './../../../src/runtime/composables/useGraphqlUploadMutation'

const useNuxtApp = function () {
return {
Expand Down Expand Up @@ -39,6 +40,11 @@ vi.mock('#imports', () => {
graphqlMiddleware: {},
}
},
useGraphqlState: () => {
return {
fetchOptions: {},
}
},
}
})

Expand Down Expand Up @@ -83,6 +89,39 @@ describe('useGraphqlQuery', () => {
const result = await useGraphqlQuery(123).catch((e) => e)
expect(result).toMatchSnapshot()
})

test('takes options into account', async () => {
expect(
await useGraphqlQuery(
'foobar',
{ stringVar: 'foobar' },
{
fetchOptions: {
params: {
customParam: 'yes',
},
},
clientContext: {
language: 'fr',
},
},
),
).toMatchInlineSnapshot(`
{
"data": undefined,
"endpoint": "/nuxt-graphql-middleware/query/foobar",
"errors": [],
"options": {
"method": "get",
"params": {
"__gqlc_language": "fr",
"customParam": "yes",
"stringVar": "foobar",
},
},
}
`)
})
})

describe('useGraphqlMutation', () => {
Expand All @@ -100,6 +139,83 @@ describe('useGraphqlMutation', () => {
const result = await useGraphqlMutation(123).catch((e) => e)
expect(result).toMatchSnapshot()
})

test('takes options into account', async () => {
const result = await useGraphqlMutation(
'foobar',
{ stringVar: 'foobar' },
{
fetchOptions: {
params: {
customParam: 'yes',
},
},
clientContext: {
language: 'fr',
},
},
)
expect(result.options.body).toMatchInlineSnapshot(`
{
"stringVar": "foobar",
}
`)
expect(result.options.params).toMatchInlineSnapshot(`
{
"__gqlc_language": "fr",
"customParam": "yes",
}
`)
})
})

describe('useGraphqlUploadMutation', () => {
test('takes options into account', async () => {
const result = await useGraphqlUploadMutation(
'foobar',
{ stringVar: 'foobar' },
{
fetchOptions: {
params: {
customParam: 'yes',
},
},
clientContext: {
language: 'fr',
},
},
)
expect(result).toMatchInlineSnapshot(`
{
"data": undefined,
"endpoint": "/nuxt-graphql-middleware/upload/foobar",
"errors": [],
"options": {
"body": FormData {
Symbol(state): [
{
"name": "operations",
"value": "{}",
},
{
"name": "variables",
"value": "{"stringVar":"foobar"}",
},
{
"name": "map",
"value": "{}",
},
],
},
"method": "POST",
"params": {
"__gqlc_language": "fr",
"customParam": "yes",
},
},
}
`)
})
})

describe('useGraphqlState', () => {
Expand Down

0 comments on commit 37d8f64

Please sign in to comment.