Skip to content

Commit

Permalink
Replace all remaining operation spreads with makeOperation
Browse files Browse the repository at this point in the history
  • Loading branch information
kitten committed Oct 28, 2020
1 parent 687bfa4 commit f452a19
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 78 deletions.
50 changes: 21 additions & 29 deletions docs/advanced/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const getAuth = async ({ authState }) => {
}

return null;
}
};
```

We check that the `authState` doesn't already exist (this indicates that it is the first time this exchange is executed and not an auth failure) and fetch the auth state from
Expand All @@ -104,7 +104,7 @@ const getAuth = async ({ authState, mutate }) => {
}

return null;
}
};
```

### Configuring `addAuthToOperation`
Expand All @@ -113,10 +113,9 @@ The purpose of `addAuthToOperation` is to take apply your auth state to each req
you've returned from `getAuth` and not at all constrained by the exchange:

```js
const addAuthToOperation = ({
authState,
operation,
}) => {
import { makeOperation } from '@urql/core';

const addAuthToOperation = ({ authState, operation }) => {
if (!authState || !authState.token) {
return operation;
}
Expand All @@ -126,20 +125,17 @@ const addAuthToOperation = ({
? operation.context.fetchOptions()
: operation.context.fetchOptions || {};

return {
...operation,
context: {
...operation.context,
fetchOptions: {
...fetchOptions,
headers: {
...fetchOptions.headers,
"Authorization": authState.token,
},
return makeOperation(operation.kind, operation, {
...operation.context,
fetchOptions: {
...fetchOptions,
headers: {
...fetchOptions.headers,
Authorization: authState.token,
},
},
};
}
});
};
```

First we check that we have an `authState` and a `token`. Then we apply it to the request `fetchOptions` as an `Authorization` header.
Expand Down Expand Up @@ -174,10 +170,8 @@ is the recommended approach. We'll be able to determine whether any of the Graph
```js
const didAuthError = ({ error }) => {
return error.graphQLErrors.some(
e => e.extensions?.code === 'FORBIDDEN',
);
}
return error.graphQLErrors.some(e => e.extensions?.code === 'FORBIDDEN');
};
```
For some GraphQL APIs, the auth error is communicated via an 401 HTTP response as is common in RESTful APIs:
Expand Down Expand Up @@ -225,7 +219,7 @@ const getAuth = async ({ authState }) => {
logout();

return null;
}
};
```
Here, `logout()` is a placeholder that is called when we got an error, so that we can redirect to a login page again and clear our tokens from local storage or otherwise.
Expand Down Expand Up @@ -299,14 +293,12 @@ const client = createClient({
cacheExchange,
errorExchange({
onError: error => {
const isAuthError = error.graphQLErrors.some(
e => e.extensions?.code === 'FORBIDDEN',
);
const isAuthError = error.graphQLErrors.some(e => e.extensions?.code === 'FORBIDDEN');

if (isAuthError) {
logout();
}
}
},
}),
authExchange({
/* config */
Expand All @@ -331,14 +323,14 @@ const App = ({ isLoggedIn }: { isLoggedIn: boolean | null }) => {
if (isLoggedIn === null) {
return null;
}

return createClient({ /* config */ });
}, [isLoggedIn]);

if (!client) {
return null;
}

return {
<GraphQLProvider value={client}>
{/* app content */}
Expand Down
12 changes: 8 additions & 4 deletions docs/common-questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ order: 6
If you need `async fetchOptions` you can add an exchange that looks like this:

```js
import { makeOperation } from '@urql/core';

export const fetchOptionsExchange = (fn: any): Exchange => ({ forward }) => ops$ => {
return pipe(
ops$,
mergeMap((operation: Operation) => {
const result = fn(operation.context.fetchOptions);
return pipe(
typeof result.then === 'function' ? fromPromise(result) : fromValue(result),
map((fetchOptions: RequestInit | (() => RequestInit)) => ({
...operation,
context: { ...operation.context, fetchOptions },
}))
map((fetchOptions: RequestInit | (() => RequestInit)) => {
return makeOperation(operation.kind, operation, {
...operation.context,
fetchOptions,
});
})
);
}),
forward
Expand Down
10 changes: 6 additions & 4 deletions exchanges/auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ You'll then need to add the `authExchange`, that this package exposes to your `u

```js
import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql';
import { makeOperation } from '@urql/core';
import { authExchange } from '@urql/exchange-auth';

const client = createClient({
Expand All @@ -41,9 +42,10 @@ const client = createClient({
? operation.context.fetchOptions()
: operation.context.fetchOptions || {};

return {
...operation,
context: {
return makeOperation(
operation.kind,
operation,
{
...operation.context,
fetchOptions: {
...fetchOptions,
Expand All @@ -53,7 +55,7 @@ const client = createClient({
},
},
},
};
);
},
willAuthError: ({ authState }) => {
if (!authState) return true;
Expand Down
8 changes: 3 additions & 5 deletions exchanges/auth/src/authExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,11 @@ export interface AuthConfig<T> {
const addAuthAttemptToOperation = (
operation: Operation,
hasAttempted: boolean
) => ({
...operation,
context: {
) =>
makeOperation(operation.kind, operation, {
...operation.context,
authAttempt: hasAttempted,
},
});
});

export function authExchange<T>({
addAuthToOperation,
Expand Down
3 changes: 2 additions & 1 deletion exchanges/graphcache/src/offlineExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ExchangeIO,
CombinedError,
createRequest,
makeOperation,
} from '@urql/core';

import {
Expand Down Expand Up @@ -99,7 +100,7 @@ export const offlineExchange = (opts: CacheExchangeOpts): Exchange => input => {
for (let i = 0; i < failedQueue.length; i++) {
const operation = failedQueue[i];
if (operation.kind === 'mutation') {
next({ ...operation, operationName: 'teardown' });
next(makeOperation('teardown', operation));
}
}

Expand Down
14 changes: 7 additions & 7 deletions exchanges/persisted-fetch/src/persistedFetchExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from 'wonka';

import {
makeOperation,
CombinedError,
ExchangeInput,
Exchange,
Expand Down Expand Up @@ -139,17 +140,16 @@ const makePersistedFetchSource = (
dispatchDebug: ExchangeInput['dispatchDebug'],
useGet: boolean
): Source<OperationResult> => {
const newOperation = {
...operation,
context: {
...operation.context,
preferGetMethod: useGet || operation.context.preferGetMethod,
},
};
const newOperation = makeOperation(operation.kind, operation, {
...operation.context,
preferGetMethod: useGet || operation.context.preferGetMethod,
});

const url = makeFetchURL(
newOperation,
body.query ? body : { ...body, query: '' }
);

const fetchOptions = makeFetchOptions(newOperation, body);

dispatchDebug({
Expand Down
20 changes: 10 additions & 10 deletions exchanges/populate/src/populateExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
SelectionNode,
} from 'graphql';
import { pipe, tap, map } from 'wonka';
import { Exchange, Operation } from '@urql/core';
import { makeOperation, Exchange, Operation } from '@urql/core';

import { warn } from './helpers/help';
import {
Expand Down Expand Up @@ -61,15 +61,15 @@ export const populateExchange = ({
);
}

return {
...op,
query: addFragmentsToQuery(
schema,
op.query,
activeSelections,
userFragments
),
};
const newOperation = makeOperation(op.kind, op);
newOperation.query = addFragmentsToQuery(
schema,
op.query,
activeSelections,
userFragments
);

return newOperation;
};

/** Handle query and extract fragments. */
Expand Down
13 changes: 5 additions & 8 deletions exchanges/request-policy/src/requestPolicyExchange.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Operation, Exchange } from '@urql/core';
import { makeOperation, Operation, Exchange } from '@urql/core';
import { pipe, map } from 'wonka';

const defaultTTL = 5 * 60 * 1000;
Expand Down Expand Up @@ -33,13 +33,10 @@ export const requestPolicyExchange = (options: Options): Exchange => ({
(options.shouldUpgrade ? options.shouldUpgrade(operation) : true)
) {
operations.set(operation.key, new Date());
return {
...operation,
context: {
...operation.context,
requestPolicy: 'cache-and-network',
},
};
return makeOperation(operation.kind, operation, {
...operation.context,
requestPolicy: 'cache-and-network',
});
}

return operation;
Expand Down
10 changes: 5 additions & 5 deletions exchanges/retry/src/retryExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
takeUntil,
} from 'wonka';
import {
makeOperation,
Exchange,
Operation,
CombinedError,
Expand Down Expand Up @@ -84,14 +85,13 @@ export const retryExchange = ({

// Add new retryDelay and retryCount to operation
return pipe(
fromValue({
...op,
context: {
fromValue(
makeOperation(op.kind, op, {
...op.context,
retryDelay: delayAmount,
retryCount,
},
}),
})
),
delay(delayAmount),
// Stop retry if a teardown comes in
takeUntil(teardown$)
Expand Down
9 changes: 4 additions & 5 deletions packages/core/src/exchanges/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,12 @@ export const cacheExchange: Exchange = ({ forward, client, dispatchDebug }) => {

// Reexecutes a given operation with the default requestPolicy
const reexecuteOperation = (client: Client, operation: Operation) => {
return client.reexecuteOperation({
...operation,
context: {
return client.reexecuteOperation(
makeOperation(operation.kind, operation, {
...operation.context,
requestPolicy: 'network-only',
},
});
})
);
};

// Invalidates the cache given a mutation's response
Expand Down

0 comments on commit f452a19

Please sign in to comment.