diff --git a/docs/content/1.getting-started/2.configuration.md b/docs/content/1.getting-started/2.configuration.md index 55bc27c0..32324848 100644 --- a/docs/content/1.getting-started/2.configuration.md +++ b/docs/content/1.getting-started/2.configuration.md @@ -16,7 +16,8 @@ export default defineNuxtConfig({ authHeader: 'Authorization', tokenStorage: 'cookie', proxyCookies: true, - clients: {} + clients: {}, + useApolloUploadLink: true } }) ``` @@ -76,7 +77,8 @@ export default defineNuxtConfig({ tokenName: 'apollo:.token', tokenStorage: 'cookie', authType: 'Bearer', - authHeader: 'Authorization' + authHeader: 'Authorization', + useApolloUploadLink: true }, other: './apollo/other.ts' } @@ -100,7 +102,8 @@ export default defineApolloClient({ tokenName: 'apollo:.token', tokenStorage: 'cookie', authType: 'Bearer', - authHeader: 'Authorization' + authHeader: 'Authorization', + useApolloUploadLink: true }) ``` :: @@ -166,3 +169,10 @@ Specify the Authentication scheme. - Default: `Authorization` Name of the Authentication token header. + +- ### `useApolloUploadLink` + + - Default: `true` + +Specify if the client should use `apollo-upload-client` for file uploads. This is required for file uploads. + diff --git a/package.json b/package.json index fbbccaec..4ce50e6b 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@rollup/plugin-graphql": "^2.0.5", "@vue/apollo-composable": "^4.2.2", "@vue/apollo-option": "^4.2.2", + "apollo-upload-client": "^18.0.1", "defu": "^6.1.4", "destr": "^2.0.5", "graphql": "^16.11.0", diff --git a/playground/apollo/default.ts b/playground/apollo/default.ts index 869d8643..be1e4a1a 100644 --- a/playground/apollo/default.ts +++ b/playground/apollo/default.ts @@ -27,5 +27,8 @@ export default defineApolloClient({ // Specify if the client should solely use WebSocket. // requires `wsEndpoint`. - websocketsOnly: false + websocketsOnly: false, + + // Specify if the client should use `apollo-upload-client` for file uploads. + useApolloUploadLink: true }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8cc73fe7..21a4dc40 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: '@vue/apollo-option': specifier: ^4.2.2 version: 4.2.2(@apollo/client@3.13.9(graphql-ws@6.0.6(crossws@0.3.5)(graphql@16.11.0)(ws@8.18.3))(graphql@16.11.0))(vue@3.5.18(typescript@5.8.3)) + apollo-upload-client: + specifier: ^18.0.1 + version: 18.0.1(@apollo/client@3.13.9(graphql-ws@6.0.6(crossws@0.3.5)(graphql@16.11.0)(ws@8.18.3))(graphql@16.11.0))(graphql@16.11.0) defu: specifier: ^6.1.4 version: 6.1.4 @@ -2551,6 +2554,13 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + apollo-upload-client@18.0.1: + resolution: {integrity: sha512-OQvZg1rK05VNI79D658FUmMdoI2oB/KJKb6QGMa2Si25QXOaAvLMBFUEwJct7wf+19U8vk9ILhidBOU1ZWv6QA==} + engines: {node: ^18.15.0 || >=20.4.0} + peerDependencies: + '@apollo/client': ^3.8.0 + graphql: 14 - 16 + archiver-utils@5.0.2: resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} engines: {node: '>= 14'} @@ -3582,6 +3592,10 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + extract-files@13.0.0: + resolution: {integrity: sha512-FXD+2Tsr8Iqtm3QZy1Zmwscca7Jx3mMC5Crr+sEP1I303Jy1CYMuYCm7hRTplFNg3XdUavErkxnTzpaqdSoi6g==} + engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0} + extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -9511,6 +9525,12 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + apollo-upload-client@18.0.1(@apollo/client@3.13.9(graphql-ws@6.0.6(crossws@0.3.5)(graphql@16.11.0)(ws@8.18.3))(graphql@16.11.0))(graphql@16.11.0): + dependencies: + '@apollo/client': 3.13.9(graphql-ws@6.0.6(crossws@0.3.5)(graphql@16.11.0)(ws@8.18.3))(graphql@16.11.0) + extract-files: 13.0.0 + graphql: 16.11.0 + archiver-utils@5.0.2: dependencies: glob: 10.4.5 @@ -10688,6 +10708,10 @@ snapshots: extend@3.0.2: {} + extract-files@13.0.0: + dependencies: + is-plain-obj: 4.1.0 + extract-zip@2.0.1: dependencies: debug: 4.4.1 diff --git a/src/module.ts b/src/module.ts index e1beb738..ddf41e94 100644 --- a/src/module.ts +++ b/src/module.ts @@ -39,7 +39,8 @@ export default defineNuxtModule({ secure: process.env.NODE_ENV === 'production', sameSite: 'lax' }, - clientAwareness: false + clientAwareness: false, + useApolloUploadLink: true }, async setup(options, nuxt) { if (!options.clients || !Object.keys(options.clients).length) { @@ -84,6 +85,7 @@ export default defineNuxtModule({ v.authHeader = v?.authHeader || options.authHeader v.tokenName = v?.tokenName || `apollo:${k}.token` v.tokenStorage = v?.tokenStorage || options.tokenStorage + v.useApolloUploadLink = v?.useApolloUploadLink || options.useApolloUploadLink if (v.cookieAttributes) { v.cookieAttributes = defu(v?.cookieAttributes, options.cookieAttributes) } diff --git a/src/runtime/plugin.ts b/src/runtime/plugin.ts index f937af1d..75e0a322 100644 --- a/src/runtime/plugin.ts +++ b/src/runtime/plugin.ts @@ -4,6 +4,7 @@ import { getMainDefinition } from '@apollo/client/utilities' import { createApolloProvider } from '@vue/apollo-option' import { ApolloClients, provideApolloClients } from '@vue/apollo-composable' import { ApolloClient, ApolloLink, createHttpLink, InMemoryCache, split } from '@apollo/client/core' +import uploadHttpLink from 'apollo-upload-client/createUploadLink.mjs' import { GraphQLWsLink } from '@apollo/client/link/subscriptions' import { setContext } from '@apollo/client/link/context' import type { ClientConfig, ErrorResponse } from '../types' @@ -73,11 +74,14 @@ export default defineNuxtPlugin((nuxtApp) => { } }) - const httpLink = authLink.concat(createHttpLink({ + const httpLinkOptions = { ...(clientConfig?.httpLinkOptions && clientConfig.httpLinkOptions), uri: (import.meta.client && clientConfig.browserHttpEndpoint) || clientConfig.httpEndpoint, headers: { ...(clientConfig?.httpLinkOptions?.headers || {}) } - })) + } + + // Apollo Http Client + const httpLink = clientConfig.useApolloUploadLink ? authLink.concat(uploadHttpLink(httpLinkOptions)) : authLink.concat(createHttpLink(httpLinkOptions)) let wsLink: GraphQLWsLink | null = null diff --git a/src/types.d.ts b/src/types.d.ts index 28959e40..2bf51b3f 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -101,6 +101,13 @@ export type ClientConfig = { * Configuration for the auth cookie. */ cookieAttributes?: CookieAttributes + + /** + * Use 'apollo-upload-client' for file uploads, instead of the standard apollo HttpLink. + * @type {boolean} + * @default true + */ + useApolloUploadLink?: boolean } export interface NuxtApolloConfig { @@ -165,4 +172,11 @@ export interface NuxtApolloConfig { * @default false */ clientAwareness?: boolean + + /** + * Use 'apollo-upload-client' for file uploads, instead of the standard apollo HttpLink. + * @type {boolean} + * @default true + */ + useApolloUploadLink?: boolean }