Skip to content

Commit a9b1940

Browse files
dfallingrenovate-botclaude
authored
Update Apollo GraphQL packages to v4 (#35)
* Update Apollo GraphQL packages to v4 * Migrate app code to Apollo Client v4 APIs Apollo Client v4 moved the React hooks/types out of the package root into @apollo/client/react and reworked error handling. Update imports and the generated types so the app type-checks against v4: - ApolloProvider, useReactiveVar, useApolloClient, and the generated query/ mutation hooks now import from @apollo/client/react. - errorLink/extractAuthErrorCode use CombinedGraphQLErrors (the v4 wrapper for GraphQL errors) instead of the removed graphQLErrors field. - client.query() data is now T | undefined in v4 — guard the upload-URL read. - Remap the generated MutationFunction/BaseMutationOptions references and @ts-ignore the unused, v4-incompatible generated *SuspenseQuery hooks, since typescript-react-apollo has no v4 support yet (documented in codegen.ts). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Renovate Bot <bot@renovateapp.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6262710 commit a9b1940

9 files changed

Lines changed: 48 additions & 48 deletions

File tree

App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @format
55
*/
66

7-
import {ApolloProvider} from '@apollo/client';
7+
import {ApolloProvider} from '@apollo/client/react';
88
import {
99
DarkTheme,
1010
DefaultTheme,

bun.lock

Lines changed: 2 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codegen.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ const config: CodegenConfig = {
2222
],
2323
config: {
2424
withHooks: true,
25+
// NOTE: @graphql-codegen/typescript-react-apollo has no Apollo Client
26+
// v4 support (latest is 4.x, still v3-oriented). After regenerating,
27+
// the output needs manual fixups to compile against @apollo/client v4:
28+
// - `import * as Apollo from '@apollo/client'` -> '@apollo/client/react'
29+
// - `Apollo.MutationFunction` -> `Apollo.useMutation.MutationFunction`
30+
// - `Apollo.BaseMutationOptions` -> `Apollo.MutationHookOptions`
31+
// - the generated *SuspenseQuery hooks need @ts-ignore (unused here)
32+
// Longer term, migrate to @graphql-codegen/client-preset.
2533
reactApolloVersion: 3,
2634
scalars: {
2735
// Map GraphQL scalars to TS types as you add them in the schema.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"postinstall": "git rev-parse --git-dir > /dev/null 2>&1 && git config core.hooksPath .githooks || true"
1414
},
1515
"dependencies": {
16-
"@apollo/client": "^3.11.0",
16+
"@apollo/client": "^4.0.0",
1717
"@bam.tech/react-native-image-resizer": "^3.0.11",
1818
"@maplibre/maplibre-react-native": "^11.2.1",
1919
"@react-native/new-app-screen": "0.85.3",

src/auth/authClient.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import {
77
InMemoryCache,
88
makeVar,
99
Observable,
10-
useReactiveVar,
1110
} from '@apollo/client';
11+
import {CombinedGraphQLErrors} from '@apollo/client/errors';
1212
import {setContext} from '@apollo/client/link/context';
1313
import {onError} from '@apollo/client/link/error';
14+
import {useReactiveVar} from '@apollo/client/react';
1415
import {config} from '../config';
1516
import {
1617
type LoginMutation,
@@ -108,13 +109,11 @@ async function doRefresh(): Promise<AuthState | null> {
108109
}
109110

110111
function extractAuthErrorCode(err: unknown): string | undefined {
111-
// Apollo wraps GraphQL errors in an ApolloError with a graphQLErrors array.
112-
const graphQLErrors =
113-
err && typeof err === 'object' && 'graphQLErrors' in err
114-
? (err as {graphQLErrors?: ReadonlyArray<{extensions?: {code?: string}}>})
115-
.graphQLErrors
116-
: undefined;
117-
return graphQLErrors?.[0]?.extensions?.code;
112+
// Apollo Client 4 wraps GraphQL errors thrown from an operation in a
113+
// CombinedGraphQLErrors instance, exposing them as an `errors` array.
114+
if (!CombinedGraphQLErrors.is(err)) return undefined;
115+
const code = err.errors[0]?.extensions?.code;
116+
return typeof code === 'string' ? code : undefined;
118117
}
119118

120119
function isAuthHousekeepingOperation(operation: Operation): boolean {
@@ -150,8 +149,10 @@ const authLink = setContext(async (request, prevContext) => {
150149
// 2. Handle auth-related GraphQL error codes. On TOKEN_EXPIRED, refresh and
151150
// replay the original operation once. On TOKEN_REUSE_DETECTED / REVOKED /
152151
// INVALID, clear tokens (and optionally raise a security warning).
153-
const errorLink = onError(({graphQLErrors, operation, forward}) => {
154-
if (!graphQLErrors || graphQLErrors.length === 0) return;
152+
const errorLink = onError(({error, operation, forward}) => {
153+
if (!CombinedGraphQLErrors.is(error)) return;
154+
const graphQLErrors = error.errors;
155+
if (graphQLErrors.length === 0) return;
155156
const code = graphQLErrors[0]?.extensions?.code;
156157
if (typeof code !== 'string') return;
157158

src/auth/deepLinks.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {makeVar, useReactiveVar} from '@apollo/client';
1+
import {makeVar} from '@apollo/client';
2+
import {useReactiveVar} from '@apollo/client/react';
23
import {useEffect} from 'react';
34
import {Linking} from 'react-native';
45

src/auth/tokenStore.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {makeVar, useReactiveVar} from '@apollo/client';
1+
import {makeVar} from '@apollo/client';
2+
import {useReactiveVar} from '@apollo/client/react';
23
import EncryptedStorage from 'react-native-encrypted-storage';
34

45
// Persistent auth store backed by EncryptedSharedPreferences (Android) /

0 commit comments

Comments
 (0)