Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
at main 99 lines 2.8 kB view raw
1import { Client, fetchExchange, gql } from 'urql'; 2import { authExchange } from '@urql/exchange-auth'; 3import { cacheExchange } from '@urql/exchange-graphcache'; 4 5const cache = cacheExchange({ 6 updates: { 7 Mutation: { 8 createLink(result, _args, cache, _info) { 9 const LinksList = gql` 10 query Links($first: Int!) { 11 links(first: $first) { 12 nodes { 13 id 14 } 15 } 16 } 17 `; 18 19 const linksPages = cache 20 .inspectFields('Query') 21 .filter(field => field.fieldName === 'links'); 22 23 if (linksPages.length > 0) { 24 const lastField = linksPages[linksPages.length - 1]; 25 26 cache.updateQuery( 27 { 28 query: LinksList, 29 variables: { first: lastField.arguments.first }, 30 }, 31 data => { 32 return { 33 ...data, 34 links: { 35 ...data.links, 36 nodes: [...data.links.nodes, result.createLink.node], 37 }, 38 }; 39 } 40 ); 41 } 42 }, 43 }, 44 }, 45}); 46 47const auth = authExchange(async utilities => { 48 let token = localStorage.getItem('authToken'); 49 50 return { 51 addAuthToOperation(operation) { 52 if (!token) return operation; 53 return token 54 ? utilities.appendHeaders(operation, { 55 Authorization: `Bearer ${token}`, 56 }) 57 : operation; 58 }, 59 didAuthError(error) { 60 return error.graphQLErrors.some( 61 e => e.extensions?.code === 'UNAUTHORIZED' 62 ); 63 }, 64 willAuthError(operation) { 65 if (!token) { 66 // Detect our login mutation and let this operation through: 67 return ( 68 operation.kind !== 'mutation' || 69 // Here we find any mutation definition with the "signin" field 70 !operation.query.definitions.some(definition => { 71 return ( 72 definition.kind === 'OperationDefinition' && 73 definition.selectionSet.selections.some(node => { 74 // The field name is just an example, since register may also be an exception 75 return node.kind === 'Field' && node.name.value === 'signin'; 76 }) 77 ); 78 }) 79 ); 80 } 81 return false; 82 }, 83 async refreshAuth() { 84 token = localStorage.getItem('authToken'); 85 if (!token) { 86 // This is where auth has gone wrong and we need to clean up and redirect to a login page 87 localStorage.clear(); 88 window.location.reload(); 89 } 90 }, 91 }; 92}); 93 94const client = new Client({ 95 url: 'https://trygql.formidable.dev/graphql/web-collections', 96 exchanges: [cache, auth, fetchExchange], 97}); 98 99export default client;