Repository: FormidableLabs/urql
Pull request #871 (2020-06-18 10:43:49)

(populate) - update docs
Updates the documentation for the populateExchange

Resolves https://github.com/FormidableLabs/urql/issues/867

changeset-bot[bot]: ###  💥  No Changeset

Latest commit: 546ff31dd1f7d1311feb141af1152ba7831ae4b2

Merging this PR will not cause any packages to be released. If these changes should not cause updates to packages in this repo, this is fine 🙂

**If these changes should be published to npm, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/FormidableLabs/urql/new/update-populate-docs?filename=.changeset/six-ducks-talk.md&value=---%0A%22%40urql%2Fexchange-populate%22%3A%20patch%0A---%0A%0A(populate)%20-%20update%20docs%0A)



Patch:
diff --git a/.changeset/green-lies-help.md b/.changeset/green-lies-help.md
new file mode 100644
index 00000000..9a63d3ea
--- /dev/null
+++ b/.changeset/green-lies-help.md
@@ -0,0 +1,5 @@
+---
+'@urql/exchange-persisted-fetch': minor
+---
+
+Adds support for custom hash functions by adding a `generateHash` option to the exchange.
diff --git a/docs/advanced/auto-populate-mutations.md b/docs/advanced/auto-populate-mutations.md
index 3b8706e8..ff484b0c 100644
--- a/docs/advanced/auto-populate-mutations.md
+++ b/docs/advanced/auto-populate-mutations.md
@@ -33,7 +33,7 @@ import { populateExchange } from '@urql/exchange-graphcache';
 
 const client = createClient({
   // ...
-  exchanges: [dedupExchange, populateExchange, cacheExchange, fetchExchange],
+  exchanges: [dedupExchange, populateExchange({ schema }), cacheExchange, fetchExchange],
 });
 ```
 
@@ -43,6 +43,9 @@ own. It should also be placed after the `dedupExchange` to avoid unnecessary wor
 
 Adding the `populateExchange` now enables us to use the `@populate` directive in our mutations.
 
+The `schema` option is the introspection result for your backend graphql schema, more information
+about how to get your schema can be found [in the "Schema Awareness" Page of the Graphcache documentation.](../graphcache/schema-awareness.md#getting-your-schema).
+
 ## Example usage
 
 Consider the following queries which have been requested in other parts of your application:
diff --git a/exchanges/persisted-fetch/README.md b/exchanges/persisted-fetch/README.md
index 1a5ec6b8..1c524f88 100644
--- a/exchanges/persisted-fetch/README.md
+++ b/exchanges/persisted-fetch/README.md
@@ -25,11 +25,18 @@ const client = createClient({
   exchanges: [
     dedupExchange,
     cacheExchange,
-    persistedFetchExchange,
+    persistedFetchExchange({
+      /* optional config */
+    }),
     fetchExchange
   ],
 });
 ```
 
+The `persistedQueryExchange` supports two configuration options:
+
+- `preferGetForPersistedQueries`: Use `GET` for fetches with persisted queries
+- `generateHash`: A function that takes a GraphQL query and returns the hashed result. This defaults to the `window.crypto` API in the browser and the `crypto` module in node.
+
 The `persistedFetchExchange` only handles queries, so for mutations we keep the
 `fetchExchange` around alongside of it.
diff --git a/exchanges/persisted-fetch/src/persistedFetchExchange.ts b/exchanges/persisted-fetch/src/persistedFetchExchange.ts
index c58a6a78..2191e088 100644
--- a/exchanges/persisted-fetch/src/persistedFetchExchange.ts
+++ b/exchanges/persisted-fetch/src/persistedFetchExchange.ts
@@ -32,6 +32,7 @@ import { hash } from './sha256';
 
 interface PersistedFetchExchangeOptions {
   preferGetForPersistedQueries?: boolean;
+  generateHash?: (query: string) => Promise<string>;
 }
 
 export const persistedFetchExchange = (
@@ -39,6 +40,7 @@ export const persistedFetchExchange = (
 ): Exchange => ({ forward, dispatchDebug }) => {
   if (!options) options = {};
 
+  const hashFn = options.generateHash || hash;
   let supportsPersistedQueries = true;
 
   return ops$ => {
@@ -66,7 +68,7 @@ export const persistedFetchExchange = (
 
         return pipe(
           // Hash the given GraphQL query
-          fromPromise(hash(query)),
+          fromPromise(hashFn(query)),
           mergeMap(sha256Hash => {
             // Attach SHA256 hash and remove query from body
             body.query = undefined;
diff --git a/exchanges/populate/README.md b/exchanges/populate/README.md
index edd063ca..a00dac74 100644
--- a/exchanges/populate/README.md
+++ b/exchanges/populate/README.md
@@ -22,10 +22,13 @@ import { populateExchange } from '@urql/exchange-populate';
 
 const client = createClient({
   url: 'http://localhost:1234/graphql',
-  exchanges: [dedupExchange, populateExchange, cacheExchange, fetchExchange],
+  exchanges: [dedupExchange, populateExchange({ schema }), cacheExchange, fetchExchange],
 });
 ```
 
+The `schema` option is the introspection result for your backend graphql schema, more information
+about how to get your schema can be found [in the "Schema Awareness" Page of the Graphcache documentation.](https://formidable.com/open-source/urql/docs/graphcache/schema-awareness/#getting-your-schema).
+
 ## Example usage
 
 Consider the following queries which have been requested in other parts of your application:


Test patch:
diff --git a/exchanges/persisted-fetch/src/persistedFetchExchange.test.ts b/exchanges/persisted-fetch/src/persistedFetchExchange.test.ts
index 79be2811..01ae9c0a 100644
--- a/exchanges/persisted-fetch/src/persistedFetchExchange.test.ts
+++ b/exchanges/persisted-fetch/src/persistedFetchExchange.test.ts
@@ -193,3 +193,36 @@ it('correctly generates an SHA256 hash', async () => {
     },
   });
 });
+
+it('supports a custom hash function', async () => {
+  const expected = {
+    data: {
+      test: true,
+    },
+  };
+
+  fetch.mockResolvedValueOnce({
+    json: () => expected,
+  });
+
+  const hashFn = () => Promise.resolve('hello');
+
+  await pipe(
+    fromValue(queryOperation),
+    persistedFetchExchange({ generateHash: hashFn })(exchangeArgs),
+    toPromise
+  );
+
+  expect(fetch).toHaveBeenCalledTimes(1);
+
+  const body = JSON.parse(fetch.mock.calls[0][1].body);
+
+  expect(body).toMatchObject({
+    extensions: {
+      persistedQuery: {
+        version: 1,
+        sha256Hash: 'hello',
+      },
+    },
+  });
+});