Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.

chore(examples): Update package versions in examples and keep up-to-date (#3071)

+5
.gitignore
···
# TODO: Figure out how to remove these:
tmp/
dist/
+
examples/yarn.lock
+
examples/pnpm-lock.yaml
+
examples/package-lock.json
examples/*/public
examples/*/yarn.lock
+
examples/*/pnpm-lock.yaml
+
examples/*/package-lock.json
examples/*/ios/
examples/*/android/
examples/*/.watchmanconfig
+2
examples/pnpm-workspace.yaml
···
+
packages:
+
- '*'
+7 -6
examples/with-apq/package.json
···
"start": "vite"
},
"dependencies": {
+
"@urql/core": "^3.2.2",
"@urql/exchange-persisted-fetch": "^1.3.0",
-
"graphql": "^15.5.0",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"graphql": "^16.6.0",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.3",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-react": "^3.1.0",
+
"vite": "^4.2.0"
}
}
+4 -4
examples/with-apq/src/App.jsx
···
import React from 'react';
-
import { createClient, Provider, fetchExchange } from 'urql';
-
import { persistedFetchExchange } from '@urql/exchange-persisted-fetch';
+
import { Client, Provider, fetchExchange } from 'urql';
+
import { persistedExchange } from '@urql/exchange-persisted';
import LocationsList from './LocationsList';
-
const client = createClient({
+
const client = new Client({
url: 'https://trygql.formidable.dev/graphql/apq-weather',
exchanges: [
-
persistedFetchExchange({
+
persistedExchange({
preferGetForPersistedQueries: true,
}),
fetchExchange,
+2 -7
examples/with-apq/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-apq/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+16 -9
examples/with-defer-stream-directives/package.json
···
"client": "vite",
"start": "run-p client server:yoga"
},
+
"pnpm": {
+
"peerDependencyRules": {
+
"allowedVersions": {
+
"graphql": "17"
+
}
+
}
+
},
"dependencies": {
-
"@apollo/server": "^4.4.1",
"@graphql-yoga/plugin-defer-stream": "^1.7.1",
-
"@urql/core": "^3.1.1",
-
"@urql/exchange-graphcache": "^5.0.9",
+
"@urql/core": "^3.2.2",
+
"@urql/exchange-graphcache": "^5.2.0",
"graphql": "17.0.0-alpha.2",
-
"graphql-yoga": "^3.7.1",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^3.0.3"
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.6",
+
"@apollo/server": "^4.4.1",
+
"@vitejs/plugin-react": "^3.1.0",
"graphql-helix": "^1.13.0",
+
"graphql-yoga": "^3.7.1",
"npm-run-all": "^4.1.5",
-
"vite": "^2.9.15"
+
"vite": "^4.2.0"
}
}
+3 -9
examples/with-defer-stream-directives/src/App.jsx
···
import React from 'react';
-
import {
-
createClient,
-
Provider,
-
dedupExchange,
-
debugExchange,
-
fetchExchange,
-
} from 'urql';
+
import { Client, Provider, fetchExchange } from 'urql';
import { cacheExchange } from '@urql/exchange-graphcache';
···
},
});
-
const client = createClient({
+
const client = new Client({
url: 'http://localhost:3004/graphql',
-
exchanges: [dedupExchange, cache, debugExchange, fetchExchange],
+
exchanges: [cache, fetchExchange],
});
function App() {
+2 -7
examples/with-defer-stream-directives/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-defer-stream-directives/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+8 -7
examples/with-graphcache-pagination/package.json
···
"start": "vite"
},
"dependencies": {
-
"@urql/exchange-graphcache": "^4.0.0",
-
"graphql": "^15.5.0",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"@urql/exchange-graphcache": "^5.2.0",
+
"graphql": "^16.6.0",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.3",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-react": "^3.1.0",
+
"vite": "^4.2.0"
}
}
+2 -3
examples/with-graphcache-pagination/src/App.jsx
···
import React from 'react';
-
import { createClient, Provider, dedupExchange, fetchExchange } from 'urql';
+
import { Client, Provider, fetchExchange } from 'urql';
import { cacheExchange } from '@urql/exchange-graphcache';
import { relayPagination } from '@urql/exchange-graphcache/extras';
import PaginatedNpmSearch from './PaginatedNpmSearch';
-
const client = createClient({
+
const client = new Client({
url: 'https://trygql.formidable.dev/graphql/relay-npm',
exchanges: [
-
dedupExchange,
cacheExchange({
resolvers: {
Query: {
+2 -7
examples/with-graphcache-pagination/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-graphcache-pagination/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+9 -8
examples/with-graphcache-updates/package.json
···
"start": "vite"
},
"dependencies": {
-
"@urql/exchange-auth": "^0.1.2",
-
"@urql/exchange-graphcache": "^4.0.0",
-
"graphql": "^15.5.0",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"@urql/exchange-auth": "^2.0.0",
+
"@urql/exchange-graphcache": "^5.2.0",
+
"graphql": "^16.6.0",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.3",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-react": "^3.1.0",
+
"vite": "^4.2.0"
}
}
+46 -69
examples/with-graphcache-updates/src/client.js
···
-
import { createClient, dedupExchange, fetchExchange, gql } from 'urql';
-
import { makeOperation } from '@urql/core';
+
import { Client, fetchExchange, gql } from 'urql';
import { authExchange } from '@urql/exchange-auth';
import { cacheExchange } from '@urql/exchange-graphcache';
···
},
});
-
const client = createClient({
-
url: 'https://trygql.formidable.dev/graphql/web-collections',
-
exchanges: [
-
dedupExchange,
-
cache,
-
authExchange({
-
getAuth: async ({ authState }) => {
-
if (!authState) {
-
const token = localStorage.getItem('authToken');
-
-
if (token) {
-
return { token };
-
}
+
const auth = authExchange(async utilities => {
+
let token = localStorage.getItem('authToken');
-
return null;
-
}
-
+
return {
+
addAuthToOperation(operation) {
+
if (!token) return operation;
+
return token
+
? utilities.appendHeaders(operation, {
+
Authorization: `Bearer ${token}`,
+
})
+
: operation;
+
},
+
didAuthError(error) {
+
return error.graphQLErrors.some(
+
e => e.extensions?.code === 'UNAUTHORIZED'
+
);
+
},
+
willAuthError(operation) {
+
if (!token) {
+
// Detect our login mutation and let this operation through:
+
return (
+
operation.kind !== 'mutation' ||
+
// Here we find any mutation definition with the "signin" field
+
!operation.query.definitions.some(definition => {
+
return (
+
definition.kind === 'OperationDefinition' &&
+
definition.selectionSet.selections.some(node => {
+
// The field name is just an example, since register may also be an exception
+
return node.kind === 'Field' && node.name.value === 'signin';
+
})
+
);
+
})
+
);
+
}
+
return false;
+
},
+
async refreshAuth() {
+
token = localStorage.getItem('authToken');
+
if (!token) {
// This is where auth has gone wrong and we need to clean up and redirect to a login page
localStorage.clear();
window.location.reload();
+
}
+
},
+
};
+
});
-
return null;
-
},
-
addAuthToOperation: ({ authState, operation }) => {
-
if (!authState || !authState.token) {
-
return operation;
-
}
-
-
const fetchOptions =
-
typeof operation.context.fetchOptions === 'function'
-
? operation.context.fetchOptions()
-
: operation.context.fetchOptions || {};
-
-
return makeOperation(operation.kind, operation, {
-
...operation.context,
-
fetchOptions: {
-
...fetchOptions,
-
headers: {
-
...fetchOptions.headers,
-
Authorization: `Bearer ${authState.token}`,
-
},
-
},
-
});
-
},
-
didAuthError: ({ error }) => {
-
return error.graphQLErrors.some(
-
e => e.extensions?.code === 'UNAUTHORIZED'
-
);
-
},
-
willAuthError: ({ operation, authState }) => {
-
if (!authState) {
-
// Detect our login mutation and let this operation through:
-
return (
-
operation.kind !== 'mutation' ||
-
// Here we find any mutation definition with the "signin" field
-
!operation.query.definitions.some(definition => {
-
return (
-
definition.kind === 'OperationDefinition' &&
-
definition.selectionSet.selections.some(node => {
-
// The field name is just an example, since register may also be an exception
-
return node.kind === 'Field' && node.name.value === 'signin';
-
})
-
);
-
})
-
);
-
}
-
-
return false;
-
},
-
}),
-
fetchExchange,
-
],
+
const client = new Client({
+
url: 'https://trygql.formidable.dev/graphql/web-collections',
+
exchanges: [cache, auth, fetchExchange],
});
export default client;
+2 -7
examples/with-graphcache-updates/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-graphcache-updates/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+7 -7
examples/with-multipart/package.json
···
"start": "vite"
},
"dependencies": {
-
"@urql/exchange-multipart-fetch": "^0.1.11",
-
"graphql": "^15.5.0",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"graphql": "^16.6.0",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.3",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-react": "^3.1.0",
+
"vite": "^4.2.0"
}
}
+3 -4
examples/with-multipart/src/App.jsx
···
import React from 'react';
-
import { createClient, Provider } from 'urql';
-
import { multipartFetchExchange } from '@urql/exchange-multipart-fetch';
+
import { Client, Provider, fetchExchange } from 'urql';
import FileUpload from './FileUpload';
-
const client = createClient({
+
const client = new Client({
url: 'https://trygql.formidable.dev/graphql/uploads-mock',
-
exchanges: [multipartFetchExchange],
+
exchanges: [fetchExchange],
});
function App() {
+2 -7
examples/with-multipart/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-multipart/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+7 -6
examples/with-next/package.json
···
"version": "0.0.0",
"private": true,
"dependencies": {
-
"graphql": "^15.5.0",
-
"next": "10.1.2",
-
"next-urql": "^3.0.1",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"graphql": "^16.6.0",
+
"next": "13.2.4",
+
"next-urql": "^4.0.3",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"scripts": {
"dev": "next dev",
+3 -1
examples/with-next/pages/_app.js
···
import { withUrqlClient } from 'next-urql';
+
import { cacheExchange, fetchExchange } from 'urql';
const App = ({ Component, pageProps }) => <Component {...pageProps} />;
export default withUrqlClient(
-
() => ({
+
ssrExchange => ({
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
+
exchanges: [cacheExchange, ssrExchange, fetchExchange],
}),
{ ssr: false }
)(App);
+3 -2
examples/with-next/pages/index.js
···
import { withUrqlClient } from 'next-urql';
-
import { useQuery, gql } from 'urql';
+
import { useQuery, cacheExchange, fetchExchange, gql } from 'urql';
const POKEMONS_QUERY = gql`
query {
···
}
export default withUrqlClient(
-
() => ({
+
ssrExchange => ({
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
+
exchanges: [cacheExchange, ssrExchange, fetchExchange],
}),
{ ssr: true }
)(Index);
+3 -9
examples/with-next/pages/server.js
···
import { initUrqlClient } from 'next-urql';
-
import {
-
ssrExchange,
-
dedupExchange,
-
cacheExchange,
-
fetchExchange,
-
useQuery,
-
gql,
-
} from 'urql';
+
+
import { ssrExchange, cacheExchange, fetchExchange, useQuery, gql } from 'urql';
const POKEMONS_QUERY = gql`
query {
···
const client = initUrqlClient(
{
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
-
exchanges: [dedupExchange, cacheExchange, ssrCache, fetchExchange],
+
exchanges: [cacheExchange, ssrCache, fetchExchange],
},
false
);
+3 -9
examples/with-next/pages/static.js
···
import { initUrqlClient } from 'next-urql';
-
import {
-
ssrExchange,
-
dedupExchange,
-
cacheExchange,
-
fetchExchange,
-
useQuery,
-
gql,
-
} from 'urql';
+
+
import { ssrExchange, cacheExchange, fetchExchange, useQuery, gql } from 'urql';
const POKEMONS_QUERY = gql`
query {
···
const client = initUrqlClient(
{
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
-
exchanges: [dedupExchange, cacheExchange, ssrCache, fetchExchange],
+
exchanges: [cacheExchange, ssrCache, fetchExchange],
},
false
);
+7 -6
examples/with-pagination/package.json
···
"start": "vite"
},
"dependencies": {
-
"graphql": "^15.5.0",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"graphql": "^16.6.0",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.3",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-react": "^3.1.0",
+
"vite": "^4.2.0"
}
}
+3 -2
examples/with-pagination/src/App.jsx
···
import React from 'react';
-
import { createClient, Provider } from 'urql';
+
import { Client, Provider, cacheExchange, fetchExchange } from 'urql';
import PaginatedNpmSearch from './PaginatedNpmSearch';
-
const client = createClient({
+
const client = new Client({
url: 'https://trygql.formidable.dev/graphql/relay-npm',
+
exchanges: [cacheExchange, fetchExchange],
});
function App() {
+2 -7
examples/with-pagination/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-pagination/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+3 -2
examples/with-react-native/App.js
···
import React from 'react';
-
import { createClient, Provider } from 'urql';
+
import { Client, Provider, cacheExchange, fetchExchange } from 'urql';
import PokemonList from './src/screens/PokemonList';
-
const client = createClient({
+
const client = new Client({
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
+
exchanges: [cacheExchange, fetchExchange],
});
const App = () => {
+7 -6
examples/with-react-native/package.json
···
"start": "react-native start"
},
"dependencies": {
-
"graphql": "^15.5.0",
-
"react": "17.0.1",
-
"react-native": "0.64.0",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"graphql": "^16.6.0",
+
"react": "18.2.0",
+
"react-native": "0.71.4",
+
"urql": "^3.0.4"
},
"devDependencies": {
"@babel/core": "^7.12.9",
+
"@babel/preset-env": "^7.20.2",
"@babel/runtime": "^7.12.5",
-
"babel-jest": "^26.6.3",
-
"metro-react-native-babel-preset": "^0.64.0"
+
"metro-react-native-babel-preset": "^0.76.0"
}
}
+7 -6
examples/with-react/package.json
···
"start": "vite"
},
"dependencies": {
-
"graphql": "^15.5.0",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"graphql": "^16.6.0",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.3",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-react": "^3.1.0",
+
"vite": "^4.2.0"
}
}
+3 -2
examples/with-react/src/App.jsx
···
import React from 'react';
-
import { createClient, Provider } from 'urql';
+
import { Client, Provider, cacheExchange, fetchExchange } from 'urql';
import PokemonList from './PokemonList';
-
const client = createClient({
+
const client = new Client({
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
+
exchanges: [cacheExchange, fetchExchange],
});
function App() {
+2 -7
examples/with-react/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-react/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+8 -7
examples/with-refresh-auth/package.json
···
"start": "vite"
},
"dependencies": {
-
"@urql/exchange-auth": "^0.1.2",
-
"graphql": "^15.5.0",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"@urql/exchange-auth": "^2.0.0",
+
"graphql": "^16.6.0",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.3",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-react": "^3.1.0",
+
"vite": "^4.2.0"
}
}
+57 -87
examples/with-refresh-auth/src/client.js
···
-
import {
-
makeOperation,
-
createClient,
-
dedupExchange,
-
fetchExchange,
-
cacheExchange,
-
gql,
-
} from 'urql';
-
+
import { Client, fetchExchange, cacheExchange, gql } from 'urql';
import { authExchange } from '@urql/exchange-auth';
import {
···
}
`;
-
const client = createClient({
-
url: 'https://trygql.formidable.dev/graphql/web-collections',
-
exchanges: [
-
dedupExchange,
-
cacheExchange,
-
authExchange({
-
async getAuth({ authState, mutate }) {
-
if (!authState) {
-
const token = getToken();
-
const refreshToken = getRefreshToken();
-
-
if (token && refreshToken) {
-
return { token, refreshToken };
-
}
+
const auth = authExchange(async utilities => {
+
let token = getToken();
+
let refreshToken = getRefreshToken();
-
return null;
-
}
+
return {
+
addAuthToOperation(operation) {
+
return token
+
? utilities.appendHeaders(operation, {
+
Authorization: `Bearer ${token}`,
+
})
+
: operation;
+
},
+
didAuthError(error) {
+
return error.graphQLErrors.some(
+
e => e.extensions?.code === 'UNAUTHORIZED'
+
);
+
},
+
willAuthError(operation) {
+
// Sync tokens on every operation
+
token = getToken();
+
refreshToken = getRefreshToken();
-
const result = await mutate(REFRESH_TOKEN_MUTATION, {
-
refreshToken: authState.refreshToken,
+
if (!token) {
+
// Detect our login mutation and let this operation through:
+
return (
+
operation.kind !== 'mutation' ||
+
// Here we find any mutation definition with the "signin" field
+
!operation.query.definitions.some(definition => {
+
return (
+
definition.kind === 'OperationDefinition' &&
+
definition.selectionSet.selections.some(node => {
+
// The field name is just an example, since register may also be an exception
+
return node.kind === 'Field' && node.name.value === 'signin';
+
})
+
);
+
})
+
);
+
}
+
return false;
+
},
+
async refreshAuth() {
+
if (refreshToken) {
+
const result = await utilities.mutate(REFRESH_TOKEN_MUTATION, {
+
refreshToken,
});
if (result.data?.refreshCredentials) {
-
saveAuthData(result.data.refreshCredentials);
-
-
return result.data.refreshCredentials;
-
}
-
-
// This is where auth has gone wrong and we need to clean up and redirect to a login page
-
clearStorage();
-
window.location.reload();
-
-
return null;
-
},
-
-
addAuthToOperation({ authState, operation }) {
-
if (!authState || !authState.token) {
-
return operation;
+
token = result.data.refreshCredentials.token;
+
refreshToken = result.data.refreshCredentials.refreshToken;
+
saveAuthData({ token, refreshToken });
+
return;
}
-
-
const fetchOptions =
-
typeof operation.context.fetchOptions === 'function'
-
? operation.context.fetchOptions()
-
: operation.context.fetchOptions || {};
-
-
return makeOperation(operation.kind, operation, {
-
...operation.context,
-
fetchOptions: {
-
...fetchOptions,
-
headers: {
-
...fetchOptions.headers,
-
Authorization: `Bearer ${authState.token}`,
-
},
-
},
-
});
-
},
-
-
didAuthError({ error }) {
-
return error.graphQLErrors.some(
-
e => e.extensions?.code === 'UNAUTHORIZED'
-
);
-
},
+
}
-
willAuthError({ operation, authState }) {
-
if (!authState) {
-
// Detect our login mutation and let this operation through:
-
return (
-
operation.kind !== 'mutation' ||
-
// Here we find any mutation definition with the "signin" field
-
!operation.query.definitions.some(definition => {
-
return (
-
definition.kind === 'OperationDefinition' &&
-
definition.selectionSet.selections.some(node => {
-
// The field name is just an example, since register may also be an exception
-
return node.kind === 'Field' && node.name.value === 'signin';
-
})
-
);
-
})
-
);
-
}
+
// This is where auth has gone wrong and we need to clean up and redirect to a login page
+
clearStorage();
+
window.location.reload();
+
},
+
};
+
});
-
return false;
-
},
-
}),
-
fetchExchange,
-
],
+
const client = new Client({
+
url: 'https://trygql.formidable.dev/graphql/web-collections',
+
exchanges: [cacheExchange, auth, fetchExchange],
});
export default client;
+2 -7
examples/with-refresh-auth/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-refresh-auth/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+8 -7
examples/with-retry/package.json
···
"start": "vite"
},
"dependencies": {
-
"@urql/exchange-retry": "^0.2.0",
-
"graphql": "^15.5.0",
-
"react": "^17.0.2",
-
"react-dom": "^17.0.2",
-
"urql": "^2.0.2"
+
"@urql/core": "^3.2.2",
+
"@urql/exchange-retry": "^1.0.0",
+
"graphql": "^16.6.0",
+
"react": "^18.2.0",
+
"react-dom": "^18.2.0",
+
"urql": "^3.0.4"
},
"devDependencies": {
-
"@vitejs/plugin-react-refresh": "^1.3.3",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-react": "^3.1.0",
+
"vite": "^4.2.0"
}
}
+4 -3
examples/with-retry/src/App.jsx
···
import React from 'react';
-
import { createClient, fetchExchange, Provider } from 'urql';
+
import { Client, fetchExchange, Provider } from 'urql';
import { retryExchange } from '@urql/exchange-retry';
import Color from './Color';
-
const client = createClient({
+
const client = new Client({
url: 'https://trygql.formidable.dev/graphql/intermittent-colors',
exchanges: [
retryExchange({
-
maxNumberAttempts: 5,
+
maxNumberAttempts: 10,
+
maxDelayMs: 500,
retryIf: error => {
// NOTE: With this deemo schema we have a specific random error to look out for:
return (
+2 -2
examples/with-retry/src/Color.jsx
···
{result.operation && (
<p>
-
We retried {result.operation.context.retryCount} times to get a result
-
without an error.
+
To get a result, the retry exchange retried:{' '}
+
{result.operation.context.retryCount || 0} times.
</p>
)}
</div>
+2 -7
examples/with-retry/src/index.jsx
···
import React from 'react';
-
import { render } from 'react-dom';
+
import { createRoot } from 'react-dom/client';
import App from './App';
-
render(
-
<React.StrictMode>
-
<App />
-
</React.StrictMode>,
-
document.getElementById('root')
-
);
+
createRoot(document.getElementById('root')).render(<App />);
+2 -2
examples/with-retry/vite.config.js
···
import { defineConfig } from 'vite';
-
import reactRefresh from '@vitejs/plugin-react-refresh';
+
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
-
plugins: [reactRefresh()],
+
plugins: [react()],
});
+8 -6
examples/with-svelte/package.json
···
"build": "vite build",
"serve": "vite preview"
},
-
"devDependencies": {
-
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.44",
-
"vite": "^2.2.4"
-
},
"dependencies": {
-
"@urql/svelte": "^2.0.0",
-
"svelte": "^3.48.0"
+
"@urql/core": "^3.2.2",
+
"@urql/svelte": "^3.0.4",
+
"graphql": "^16.6.0",
+
"svelte": "^3.57.0"
+
},
+
"devDependencies": {
+
"@sveltejs/vite-plugin-svelte": "^2.0.3",
+
"vite": "^4.2.0"
}
}
+4 -3
examples/with-svelte/src/App.svelte
···
<script>
-
import { setContextClient, createClient } from "@urql/svelte";
+
import { setContextClient, Client, cacheExchange, fetchExchange } from "@urql/svelte";
import PokemonList from "./PokemonList.svelte";
-
setContextClient(createClient({
-
url: "https://trygql.formidable.dev/graphql/basic-pokedex"
+
setContextClient(new Client({
+
url: "https://trygql.formidable.dev/graphql/basic-pokedex",
+
exchanges: [cacheExchange, fetchExchange],
}));
</script>
+6 -5
examples/with-vue3/package.json
···
"serve": "vite preview"
},
"dependencies": {
-
"@urql/vue": "0.3.0",
-
"vue": "^3.0.11"
+
"@urql/core": "^3.2.2",
+
"@urql/vue": "^1.0.5",
+
"graphql": "^16.6.0",
+
"vue": "^3.2.47"
},
"devDependencies": {
-
"@vitejs/plugin-vue": "^1.2.2",
-
"@vue/compiler-sfc": "^3.0.11",
-
"vite": "^2.2.4"
+
"@vitejs/plugin-vue": "^4.1.0",
+
"vite": "^4.2.0"
}
}
+2 -1
examples/with-vue3/src/App.vue
···
</template>
<script>
-
import { provideClient } from '@urql/vue';
+
import { provideClient, cacheExchange, fetchExchange } from '@urql/vue';
import PokemonList from './PokemonList.vue'
export default {
···
setup() {
provideClient({
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
+
exchanges: [cacheExchange, fetchExchange],
});
},
components: {
+1 -1
package.json
···
"build": "node ./scripts/actions/build-all.mjs",
"postinstall": "node ./scripts/prepare/postinstall.js",
"pack": "node ./scripts/actions/pack-all.mjs",
-
"changeset:version": "changeset version && pnpm install --lockfile-only",
+
"changeset:version": "node ./scripts/changesets/version.mjs",
"changeset:publish": "changeset publish"
},
"eslintConfig": {
+1
pnpm-workspace.yaml
···
packages:
- 'packages/*'
- 'exchanges/*'
+
- '!examples/*'
+26
scripts/actions/lib/packages.mjs
···
import * as path from 'path';
+
import * as fs from 'fs/promises';
import glob from 'glob';
import { workspaceRoot, workspaces, require } from './constants.mjs';
const getPackageManifest = (cwd) =>
require(path.resolve(cwd, 'package.json'));
+
+
const updatePackageManifest = async (cwd, manifest) => {
+
const sortDependencies = (dependencies) => {
+
if (dependencies == null)
+
return undefined;
+
return Object.keys(dependencies).sort().reduce((acc, key) => {
+
acc[key] = dependencies[key];
+
return acc;
+
}, {});
+
};
+
+
try {
+
if (!!getPackageManifest(cwd)) {
+
manifest.dependencies = sortDependencies(manifest.dependencies);
+
manifest.devDependencies = sortDependencies(manifest.devDependencies);
+
await fs.writeFile(
+
path.resolve(cwd, 'package.json'),
+
JSON.stringify(manifest, null, 2) + '\n',
+
);
+
}
+
} catch (_error) {
+
throw new Error('package.json does not exist in: ' + cwd);
+
}
+
};
const getPackageArtifact = (cwd) => {
const pkg = getPackageManifest(cwd);
···
export {
getPackageManifest,
+
updatePackageManifest,
getPackageArtifact,
listPackages,
listArtifacts,
+62
scripts/changesets/version.mjs
···
+
#!/usr/bin/env node
+
+
import glob from 'glob';
+
import { execa } from 'execa';
+
+
import {
+
getPackageManifest,
+
updatePackageManifest,
+
listPackages
+
} from '../actions/lib/packages.mjs';
+
+
const versionRe = /^\d+\.\d+\.\d+/i;
+
const execaOpts = { stdio: 'inherit' };
+
+
await execa('changeset', ['changeset', 'version'], execaOpts);
+
await execa('pnpm', ['install', '--lockfile-only'], execaOpts);
+
+
const packages = (await listPackages()).reduce((map, dir) => {
+
const manifest = getPackageManifest(dir);
+
const versionMatch = manifest.version.match(versionRe);
+
if (versionMatch) {
+
const { name } = manifest;
+
const version = `^${versionMatch[0]}`;
+
map[name] = version;
+
}
+
return map;
+
}, {});
+
+
const examples = (await glob('./examples/*/')).filter(x => !/node_modules$/.test(x));
+
console.log(`Scope: updating ${examples.length} examples`)
+
for (const example of examples) {
+
let hadMatch = false;
+
+
const manifest = getPackageManifest(example);
+
+
if (manifest.dependencies) {
+
for (const name in manifest.dependencies) {
+
hadMatch = hadMatch || !!packages[name];
+
if (packages[name] && packages[name] !== manifest.dependencies)
+
manifest.dependencies[name] = packages[name];
+
}
+
}
+
+
if (manifest.devDependencies) {
+
for (const name in manifest.devDependencies) {
+
hadMatch = hadMatch || !!packages[name];
+
if (packages[name] && packages[name] !== manifest.devDependencies)
+
manifest.devDependencies[name] = packages[name];
+
}
+
}
+
+
if (
+
hadMatch &&
+
!(manifest.devDependencies || {})['@urql/core'] &&
+
!(manifest.dependencies || {})['@urql/core']
+
) {
+
(manifest.dependencies || manifest.devDependencies || {})['@urql/core']
+
= packages['@urql/core'];
+
}
+
+
await updatePackageManifest(example, manifest);
+
}