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

Configure Feed

Select the types of activity you want to include in your feed.

major(core|graphcache): remove deprected options/methods (#3520)

authored by

Jovi De Croock and committed by
GitHub
be9c72ab 50415140

+81 -280
+5
.changeset/giant-cheetahs-join.md
··· 1 + --- 2 + '@urql/core': major 3 + --- 4 + 5 + Remove deprecated `dedupExchange`
+5
.changeset/strange-steaks-grow.md
··· 1 + --- 2 + '@urql/exchange-graphcache': major 3 + --- 4 + 5 + Remove deprecated `resolveFieldByKey`, use `cache.resolve` instead
+5
.changeset/stupid-mice-judge.md
··· 1 + --- 2 + '@urql/core': major 3 + --- 4 + 5 + Remove deprecated `maskTypename`
+1 -2
docs/advanced/authentication.md
··· 346 346 The order is very important here: 347 347 348 348 ```js 349 - import { createClient, dedupExchange, cacheExchange, fetchExchange, errorExchange, mapExchange } from 'urql'; 349 + import { createClient, cacheExchange, fetchExchange, mapExchange } from 'urql'; 350 350 import { authExchange } from '@urql/exchange-auth'; 351 351 352 352 const client = createClient({ 353 353 url: 'http://localhost:3000/graphql', 354 354 exchanges: [ 355 - dedupExchange, 356 355 cacheExchange, 357 356 mapExchange({ 358 357 onError(error, _operation) {
+8 -10
docs/advanced/server-side-rendering.md
··· 385 385 you'll need to instead provide them in the `exchanges` property of the returned client object. 386 386 387 387 ```js 388 - import { dedupExchange, cacheExchange, fetchExchange } from '@urql/core'; 388 + import { cacheExchange, fetchExchange } from '@urql/core'; 389 389 390 390 import { withUrqlClient } from 'next-urql'; 391 391 392 392 export default withUrqlClient(ssrExchange => ({ 393 393 url: 'http://localhost:3000/graphql', 394 - exchanges: [dedupExchange, cacheExchange, ssrExchange, fetchExchange], 394 + exchanges: [cacheExchange, ssrExchange, fetchExchange], 395 395 }))(Index); 396 396 ``` 397 397 ··· 409 409 argument to `withUrqlClient`: 410 410 411 411 ```js 412 - import { dedupExchange, cacheExchange, fetchExchange } from '@urql/core'; 412 + import { cacheExchange, fetchExchange } from '@urql/core'; 413 413 414 414 import { withUrqlClient } from 'next-urql'; 415 415 416 416 export default withUrqlClient( 417 417 ssrExchange => ({ 418 418 url: 'http://localhost:3000/graphql', 419 - exchanges: [dedupExchange, cacheExchange, ssrExchange, fetchExchange], 419 + exchanges: [cacheExchange, ssrExchange, fetchExchange], 420 420 }), 421 421 { ssr: true } // Enables server-side rendering using `getInitialProps` 422 422 )(Index); ··· 440 440 441 441 ```js 442 442 import { withUrqlClient, initUrqlClient } from 'next-urql'; 443 - import { ssrExchange, dedupExchange, cacheExchange, fetchExchange, useQuery } from 'urql'; 443 + import { ssrExchange, cacheExchange, fetchExchange, useQuery } from 'urql'; 444 444 445 445 const TODOS_QUERY = ` 446 446 query { todos { id text } } ··· 464 464 const client = initUrqlClient( 465 465 { 466 466 url: 'your-url', 467 - exchanges: [dedupExchange, cacheExchange, ssrCache, fetchExchange], 467 + exchanges: [cacheExchange, ssrCache, fetchExchange], 468 468 }, 469 469 false 470 470 ); ··· 501 501 502 502 ```js 503 503 import { withUrqlClient, initUrqlClient } from 'next-urql'; 504 - import { ssrExchange, dedupExchange, cacheExchange, fetchExchange, useQuery } from 'urql'; 504 + import { ssrExchange, cacheExchange, fetchExchange, useQuery } from 'urql'; 505 505 import { executeExchange } from '@urql/exchange-execute'; 506 506 507 507 import { schema } from '@/server/graphql'; // our GraphQL server's executable schema ··· 529 529 { 530 530 url: '', // not needed without `fetchExchange` 531 531 exchanges: [ 532 - dedupExchange, 533 532 cacheExchange, 534 533 ssrCache, 535 534 executeExchange({ schema }), // replaces `fetchExchange` ··· 603 602 604 603 import urql, { 605 604 createClient, 606 - dedupExchange, 607 605 cacheExchange, 608 606 fetchExchange, 609 607 ssrExchange ··· 616 614 // NOTE: All we care about here is that the SSR Exchange is included 617 615 const ssr = ssrExchange({ isClient: false }); 618 616 app.use(urql, { 619 - exchanges: [dedupExchange, cacheExchange, ssr, fetchExchange] 617 + exchanges: [cacheExchange, ssr, fetchExchange] 620 618 }); 621 619 622 620 const markup = await renderToString(app);
+1 -2
docs/api/auth-exchange.md
··· 29 29 but after all other synchronous exchanges, like the `cacheExchange`. 30 30 31 31 ```js 32 - import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; 32 + import { createClient, cacheExchange, fetchExchange } from 'urql'; 33 33 import { authExchange } from '@urql/exchange-auth'; 34 34 35 35 const client = createClient({ 36 36 url: 'http://localhost:3000/graphql', 37 37 exchanges: [ 38 - dedupExchange, 39 38 cacheExchange, 40 39 authExchange(async utils => { 41 40 return {
+1 -21
docs/api/core.md
··· 34 34 | `suspense` | `?boolean` | Activates the experimental React suspense mode, which can be used during server-side rendering to prefetch data | 35 35 | `requestPolicy` | `?RequestPolicy` | Changes the default request policy that will be used. By default, this will be `cache-first`. | 36 36 | `preferGetMethod` | `?boolean \| 'force' \| 'within-url-limit'` | This is picked up by the `fetchExchange` and will force all queries (not mutations) to be sent using the HTTP GET method instead of POST if the length of the resulting URL doesn't exceed 2048 characters. When `'force'` is passed a GET request is always sent regardless of how long the resulting URL is. | 37 - | `maskTypename` | `?boolean` | Enables the `Client` to automatically apply the `maskTypename` utility to all `data` on [`OperationResult`s](#operationresult). This makes the `__typename` properties non-enumerable. | 38 37 39 38 ### client.executeQuery 40 39 ··· 251 250 An exchange is defined to be a function that receives [`ExchangeInput`](#exchangeinput) and returns 252 251 an `ExchangeIO` function. The `ExchangeIO` function in turn will receive a stream of operations, and 253 252 must return a stream of results. If the exchange is purely transforming data, like the 254 - `dedupExchange` for instance, it'll call `forward`, which is the next Exchange's `ExchangeIO` 253 + `mapExchange` for instance, it'll call `forward`, which is the next Exchange's `ExchangeIO` 255 254 function to get a stream of results. 256 255 257 256 ```js ··· 330 329 This exchange is disabled in production and is based on the `mapExchange`. 331 330 If you'd like to customise it, you can replace it with a custom `mapExchange`. 332 331 333 - ### dedupExchange 334 - 335 - An exchange that keeps track of ongoing `Operation`s that haven't returned had 336 - a corresponding `OperationResult` yet. Any duplicate `Operation` that it 337 - receives is filtered out if the same `Operation` has already been received 338 - and is still waiting for a result. 339 - 340 332 ### fetchExchange 341 333 342 334 The `fetchExchange` of type `Exchange` is responsible for sending operations of type `'query'` and ··· 515 507 516 508 This utility is used by the [`cacheExchange`](#cacheexchange) and by 517 509 [Graphcache](../graphcache/README.md) to add `__typename` fields to GraphQL `DocumentNode`s. 518 - 519 - ### maskTypename 520 - 521 - This utility accepts a GraphQL `data` object, like `data` on [`OperationResult`s](#operationresult) 522 - and marks every `__typename` property as non-enumerable. 523 - 524 - The [`formatDocument`](#formatdocument) is often used by `urql` automatically and adds `__typename` 525 - fields to all results. However, this means that data often cannot be passed back into variables or 526 - inputs on mutations, which is a common use-case. This utility hides these fields, which can solve 527 - this problem. 528 - 529 - It's used by the [`Client`](#client) when the `maskTypename` option is enabled. 530 510 531 511 ### composeExchanges 532 512
+1 -2
docs/api/execute-exchange.md
··· 29 29 since it'll handle operations and return results. 30 30 31 31 ```js 32 - import { createClient, dedupExchange, cacheExchange } from 'urql'; 32 + import { createClient, cacheExchange } from 'urql'; 33 33 import { executeExchange } from '@urql/exchange-execute'; 34 34 35 35 const client = createClient({ 36 36 url: 'http://localhost:3000/graphql', 37 37 exchanges: [ 38 - dedupExchange, 39 38 cacheExchange, 40 39 executeExchange({ 41 40 /* config */
+1 -3
docs/api/graphcache.md
··· 273 273 ``` 274 274 275 275 This specialized case is likely only going to be useful in combination with 276 - [`cache.inspectFields`](#inspectfields). Previously a specialised method existed for this 277 - case specifically and was called `cache.resolveFieldByKey`, which is now deprecated, since 278 - `cache.resolve` may be called with a field key and no extra arguments. 276 + [`cache.inspectFields`](#inspectfields). 279 277 280 278 ### inspectFields 281 279
+3 -4
docs/api/refocus-exchange.md
··· 23 23 npm install --save @urql/exchange-refocus 24 24 ``` 25 25 26 - Then add it to your `Client`, preferably after the `dedupExchange` but in front of any asynchronous 27 - exchanges, like the `fetchExchange`: 26 + Then add it to your `Client`, preferably in front of your `cacheExchange` 28 27 29 28 ```js 30 - import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; 29 + import { createClient, cacheExchange, fetchExchange } from 'urql'; 31 30 import { refocusExchange } from '@urql/exchange-refocus'; 32 31 33 32 const client = createClient({ 34 33 url: 'http://localhost:3000/graphql', 35 - exchanges: [dedupExchange, refocusExchange(), cacheExchange, fetchExchange], 34 + exchanges: [refocusExchange(), cacheExchange, fetchExchange], 36 35 }); 37 36 ```
+2 -3
docs/api/request-policy-exchange.md
··· 32 32 npm install --save @urql/exchange-request-policy 33 33 ``` 34 34 35 - Then add it to your `Client`, preferably after the `dedupExchange` but in front of any asynchronous 35 + Then add it to your `Client`, preferably in front of the `cacheExchange` and in front of any asynchronous 36 36 exchanges, like the `fetchExchange`: 37 37 38 38 ```js 39 - import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; 39 + import { createClient, cacheExchange, fetchExchange } from 'urql'; 40 40 import { requestPolicyExchange } from '@urql/exchange-request-policy'; 41 41 42 42 const client = createClient({ 43 43 url: 'http://localhost:3000/graphql', 44 44 exchanges: [ 45 - dedupExchange, 46 45 requestPolicyExchange({ 47 46 /* config */ 48 47 }),
+1 -2
exchanges/auth/README.md
··· 17 17 You'll then need to add the `authExchange`, that this package exposes to your `urql` Client 18 18 19 19 ```js 20 - import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; 20 + import { createClient, cacheExchange, fetchExchange } from 'urql'; 21 21 import { makeOperation } from '@urql/core'; 22 22 import { authExchange } from '@urql/exchange-auth'; 23 23 24 24 const client = createClient({ 25 25 url: 'http://localhost:1234/graphql', 26 26 exchanges: [ 27 - dedupExchange, 28 27 cacheExchange, 29 28 authExchange(async utils => { 30 29 // called on initial launch,
+1 -2
exchanges/context/README.md
··· 17 17 You'll then need to add the `contextExchange`, that this package exposes, to your `urql` Client, the positioning of this exchange depends on whether you set an async setter or not. If you set an async context-setter it's best placed after all the synchronous exchanges (in front of the fetchExchange). 18 18 19 19 ```js 20 - import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; 20 + import { createClient, cacheExchange, fetchExchange } from 'urql'; 21 21 import { contextExchange } from '@urql/exchange-context'; 22 22 23 23 const client = createClient({ 24 24 url: 'http://localhost:1234/graphql', 25 25 exchanges: [ 26 - dedupExchange, 27 26 cacheExchange, 28 27 contextExchange({ 29 28 getContext: async operation => {
+1 -2
exchanges/execute/README.md
··· 19 19 by replacing the default fetch exchange with it: 20 20 21 21 ```js 22 - import { createClient, dedupExchange, cacheExchange } from 'urql'; 22 + import { createClient, cacheExchange } from 'urql'; 23 23 import { executeExchange } from '@urql/exchange-execute'; 24 24 25 25 const client = createClient({ 26 26 url: 'http://localhost:1234/graphql', 27 27 exchanges: [ 28 - dedupExchange, 29 28 cacheExchange, 30 29 // Replace the default fetchExchange with the new one. 31 30 executeExchange({
+1 -2
exchanges/graphcache/README.md
··· 29 29 by replacing the default cache exchange with it: 30 30 31 31 ```js 32 - import { createClient, dedupExchange, fetchExchange } from 'urql'; 32 + import { createClient, fetchExchange } from 'urql'; 33 33 import { cacheExchange } from '@urql/exchange-graphcache'; 34 34 35 35 const client = createClient({ 36 36 url: 'http://localhost:1234/graphql', 37 37 exchanges: [ 38 - dedupExchange, 39 38 // Replace the default cacheExchange with the new one 40 39 cacheExchange({ 41 40 /* optional config */
+5 -6
exchanges/graphcache/benchmarks/urqlClient.js
··· 1 - import { createClient, dedupExchange } from '@urql/core'; 1 + import { createClient } from '@urql/core'; 2 2 import { cacheExchange } from '@urql/exchange-graphcache'; 3 3 import { executeExchange } from '@urql/exchange-execute'; 4 4 import { buildSchema } from 'graphql'; ··· 85 85 input NewTodosInput { 86 86 todos: [NewTodo]! 87 87 } 88 - 88 + 89 89 input NewWriter { 90 90 id: ID! 91 91 name: String ··· 139 139 book: NewBook! 140 140 } 141 141 142 - 142 + 143 143 input NewAuthorsInput { 144 144 authors: [NewAuthor]! 145 145 } 146 - 146 + 147 147 input NewReview { 148 148 id: ID! 149 149 score: Int! ··· 165 165 employees: [Employee]! 166 166 authors: [Author]! 167 167 } 168 - 168 + 169 169 type Mutation { 170 170 addTodo( text: String!, complete: Boolean! ): Todo! 171 171 updateTodo( id: ID!, complete: Boolean! ): Todo! ··· 251 251 const client = createClient({ 252 252 url: 'http://localhost:3000/graphql', 253 253 exchanges: [ 254 - dedupExchange, 255 254 cache, 256 255 // cacheExchange({}), 257 256 executeExchange({ schema, rootValue }),
+1 -9
exchanges/graphcache/e2e-tests/query.spec.tsx
··· 2 2 3 3 import * as React from 'react'; 4 4 import { mount } from '@cypress/react'; 5 - import { 6 - Provider, 7 - createClient, 8 - useQuery, 9 - dedupExchange, 10 - debugExchange, 11 - } from 'urql'; 5 + import { Provider, createClient, useQuery, debugExchange } from 'urql'; 12 6 import { executeExchange } from '@urql/exchange-execute'; 13 7 import { buildSchema, introspectionFromSchema } from 'graphql'; 14 8 ··· 48 42 const client = createClient({ 49 43 url: 'https://trygql.formidable.dev/graphql/basic-pokedex', 50 44 exchanges: [ 51 - dedupExchange, 52 45 cacheExchange({}), 53 46 debugExchange, 54 47 executeExchange({ schema, rootValue }), ··· 121 114 const client = createClient({ 122 115 url: 'https://trygql.formidable.dev/graphql/basic-pokedex', 123 116 exchanges: [ 124 - dedupExchange, 125 117 cacheExchange({ schema: introspectionFromSchema(schema) }), 126 118 debugExchange, 127 119 executeExchange({ schema, rootValue }),
-2
exchanges/graphcache/e2e-tests/updates.spec.tsx
··· 9 9 gql, 10 10 useQuery, 11 11 useMutation, 12 - dedupExchange, 13 12 debugExchange, 14 13 } from 'urql'; 15 14 ··· 52 51 client = createClient({ 53 52 url: 'https://trygql.formidable.dev/graphql/basic-pokedex', 54 53 exchanges: [ 55 - dedupExchange, 56 54 cacheExchange({}), 57 55 debugExchange, 58 56 executeExchange({ schema, rootValue }),
+21 -2
exchanges/graphcache/src/store/store.test.ts
··· 1 1 /* eslint-disable @typescript-eslint/no-var-requires */ 2 2 import { minifyIntrospectionQuery } from '@urql/introspection'; 3 - import { formatDocument, gql, maskTypename } from '@urql/core'; 3 + import { formatDocument, gql } from '@urql/core'; 4 4 import { vi, expect, it, beforeEach, describe } from 'vitest'; 5 5 6 6 import { ··· 102 102 write(store, { query: TodosWithoutTypename }, todosData); 103 103 const result = query(store, { query: TodosWithoutTypename }); 104 104 expect(result.data).toEqual({ 105 - ...maskTypename(todosData), 105 + todos: [ 106 + { 107 + id: '0', 108 + text: 'Go to the shops', 109 + complete: false, 110 + author: { id: '0', name: 'Jovi' }, 111 + }, 112 + { 113 + id: '1', 114 + text: 'Pick up the kids', 115 + complete: true, 116 + author: { id: '1', name: 'Phil' }, 117 + }, 118 + { 119 + id: '2', 120 + text: 'Install urql', 121 + complete: false, 122 + author: { id: '0', name: 'Jovi' }, 123 + }, 124 + ], 106 125 __typename: 'Query', 107 126 }); 108 127 });
-4
exchanges/graphcache/src/store/store.ts
··· 164 164 } 165 165 } 166 166 167 - resolveFieldByKey(entity: Entity, field: string, args?: FieldArgs) { 168 - return this.resolve(entity, field, args); 169 - } 170 - 171 167 invalidate(entity: Entity, field?: string, args?: FieldArgs) { 172 168 const entityKey = this.keyOfEntity(entity); 173 169 const shouldInvalidateType =
-10
exchanges/graphcache/src/types.ts
··· 333 333 args?: FieldArgs 334 334 ): DataField | undefined; 335 335 336 - /** Returns a cached value on a given entity’s field by its field key. 337 - * 338 - * @deprecated 339 - * Use {@link cache.resolve} instead. 340 - */ 341 - resolveFieldByKey( 342 - entity: Entity | undefined, 343 - fieldKey: string 344 - ): DataField | undefined; 345 - 346 336 /** Returns a list of cached fields for a given GraphQL object (“entity”). 347 337 * 348 338 * @param entity - a GraphQL object (“entity”) or an entity key.
+2 -4
exchanges/persisted/README.md
··· 17 17 to your `exchanges`. 18 18 19 19 ```js 20 - import { createClient, dedupExchange, fetchExchange, cacheExchange } from 'urql'; 20 + import { createClient, fetchExchange, cacheExchange } from 'urql'; 21 21 import { persistedExchange } from '@urql/exchange-persisted'; 22 22 23 23 const client = createClient({ 24 24 url: 'http://localhost:1234/graphql', 25 25 exchanges: [ 26 - dedupExchange, 27 26 cacheExchange, 28 27 persistedExchange({ 29 28 /* optional config */ ··· 46 45 when using this all you need to do in this exchange is the following: 47 46 48 47 ```js 49 - import { createClient, dedupExchange, fetchExchange, cacheExchange } from 'urql'; 48 + import { createClient, fetchExchange, cacheExchange } from 'urql'; 50 49 import { persistedExchange } from '@urql/exchange-persisted'; 51 50 52 51 const client = createClient({ 53 52 url: 'http://localhost:1234/graphql', 54 53 exchanges: [ 55 - dedupExchange, 56 54 cacheExchange, 57 55 persistedExchange({ 58 56 generateHash: (_, document) => document.documentId,
+2 -2
exchanges/populate/README.md
··· 17 17 You'll then need to add the `populateExchange`, that this package exposes. 18 18 19 19 ```js 20 - import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; 20 + import { createClient, cacheExchange, fetchExchange } from 'urql'; 21 21 import { populateExchange } from '@urql/exchange-populate'; 22 22 23 23 const client = createClient({ 24 24 url: 'http://localhost:1234/graphql', 25 - exchanges: [dedupExchange, populateExchange({ schema }), cacheExchange, fetchExchange], 25 + exchanges: [populateExchange({ schema }), cacheExchange, fetchExchange], 26 26 }); 27 27 ``` 28 28
+3 -3
exchanges/refocus/README.md
··· 13 13 npm install --save @urql/exchange-refocus 14 14 ``` 15 15 16 - Then add it to your `Client`, preferably after the `dedupExchange` but in front of any asynchronous 16 + Then add it to your `Client`, preferably before the `cacheExchange` and in front of any asynchronous 17 17 exchanges, like the `fetchExchange`: 18 18 19 19 ```js 20 - import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; 20 + import { createClient, cacheExchange, fetchExchange } from 'urql'; 21 21 import { refocusExchange } from '@urql/exchange-refocus'; 22 22 23 23 const client = createClient({ 24 24 url: 'http://localhost:3000/graphql', 25 - exchanges: [dedupExchange, refocusExchange(), cacheExchange, fetchExchange], 25 + exchanges: [refocusExchange(), cacheExchange, fetchExchange], 26 26 }); 27 27 ```
+1 -2
exchanges/request-policy/README.md
··· 16 16 Then add it to your client. 17 17 18 18 ```js 19 - import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; 19 + import { createClient, cacheExchange, fetchExchange } from 'urql'; 20 20 import { requestPolicyExchange } from '@urql/exchange-request-policy'; 21 21 22 22 const client = createClient({ 23 23 url: 'http://localhost:1234/graphql', 24 24 exchanges: [ 25 - dedupExchange, 26 25 requestPolicyExchange({ 27 26 // The amount of time in ms that has to go by before upgrading, default is 5 minutes. 28 27 ttl: 60 * 1000, // 1 minute.
+1 -32
packages/core/src/client.ts
··· 43 43 import { 44 44 createRequest, 45 45 withPromise, 46 - maskTypename, 47 46 noop, 48 47 makeOperation, 49 48 getOperationType, ··· 119 118 * This is the basis for how `urql` handles GraphQL operations, and exchanges handle the creation, execution, 120 119 * and control flow of exchanges for the `Client`. 121 120 * 122 - * To easily get started you should consider using the {@link dedupExchange}, {@link cacheExchange} and {@link fetchExchange} 121 + * To easily get started you should consider using the {@link cacheExchange} and {@link fetchExchange} 123 122 * these are all exported from the core package. 124 123 * 125 124 * @see {@link https://urql.dev/goto/docs/architecture/#the-client-and-exchanges} for more information ··· 168 167 * requests for queries. 169 168 */ 170 169 preferGetMethod?: boolean | 'force' | 'within-url-limit'; 171 - /** Instructs the `Client` to remove `__typename` properties on all results. 172 - * 173 - * @deprecated Not recommended over modelling inputs manually (See #3299) 174 - * 175 - * @remarks 176 - * By default, cache exchanges will alter your GraphQL documents to request `__typename` fields 177 - * for all selections. However, this means that your GraphQL data will now contain `__typename` fields you 178 - * didn't ask for. This is why the {@link Client} supports “masking” this field by marking it 179 - * as non-enumerable via this option. 180 - * 181 - * Only use this option if you absolutely have to. It's popular to model mutation inputs in 182 - * GraphQL schemas after the object types they modify, and if you're using this option to make 183 - * it possible to directly pass objects from results as inputs to your mutation variables, it's 184 - * more performant and idomatic to instead create a new input object. 185 - * 186 - * Hint: With `@urql/exchange-graphcache` you will never need this option, as it selects fields on 187 - * the client-side according to which fields you specified, rather than the fields it modified. 188 - * 189 - * @see {@link https://spec.graphql.org/October2021/#sec-Type-Name-Introspection} for more information 190 - * on typename introspection via the `__typename` field. 191 - */ 192 - maskTypename?: boolean; 193 170 } 194 171 195 172 /** The `Client` is the central hub for your GraphQL operations and holds `urql`'s state. ··· 629 606 ) 630 607 ) 631 608 ); 632 - 633 - // Mask typename properties if the option for it is turned on 634 - if (opts.maskTypename) { 635 - result$ = pipe( 636 - result$, 637 - map(res => ({ ...res, data: maskTypename(res.data, true) })) 638 - ); 639 - } 640 609 641 610 if (operation.kind !== 'query') { 642 611 // Interrupt subscriptions and mutations when they have no more results
-10
packages/core/src/exchanges/dedup.ts
··· 1 - import type { Exchange } from '../types'; 2 - 3 - /** Default deduplication exchange. 4 - * @deprecated 5 - * This exchange's functionality is now built into the {@link Client}. 6 - */ 7 - export const dedupExchange: Exchange = 8 - ({ forward }) => 9 - ops$ => 10 - forward(ops$);
-1
packages/core/src/exchanges/index.ts
··· 2 2 export { cacheExchange } from './cache'; 3 3 export { subscriptionExchange } from './subscription'; 4 4 export { debugExchange } from './debug'; 5 - export { dedupExchange } from './dedup'; 6 5 export { fetchExchange } from './fetch'; 7 6 export { composeExchanges } from './compose'; 8 7
-1
packages/core/src/index.ts
··· 13 13 makeErrorResult, 14 14 mergeResultPatch, 15 15 formatDocument, 16 - maskTypename, 17 16 makeOperation, 18 17 } from './utils';
-1
packages/core/src/utils/index.ts
··· 4 4 export * from './variables'; 5 5 export * from './collectTypenames'; 6 6 export * from './formatDocument'; 7 - export * from './maskTypename'; 8 7 export * from './streamUtils'; 9 8 export * from './operation'; 10 9
-86
packages/core/src/utils/maskTypename.test.ts
··· 1 - import { it, expect } from 'vitest'; 2 - import { maskTypename } from './maskTypename'; 3 - 4 - it('strips typename from flat objects', () => { 5 - expect(maskTypename({ __typename: 'Todo', id: 1 })).toEqual({ id: 1 }); 6 - }); 7 - 8 - it('strips typename from flat objects containing dates', () => { 9 - const date = new Date(); 10 - expect(maskTypename({ __typename: 'Todo', id: 1, date })).toEqual({ 11 - id: 1, 12 - date, 13 - }); 14 - }); 15 - 16 - it('strips typename from nested objects', () => { 17 - expect( 18 - maskTypename({ 19 - __typename: 'Todo', 20 - id: 1, 21 - author: { 22 - id: 2, 23 - __typename: 'Author', 24 - }, 25 - }) 26 - ).toEqual({ id: 1, author: { id: 2 } }); 27 - }); 28 - 29 - it('works with nested arrays', () => { 30 - expect( 31 - maskTypename({ 32 - __typename: 'Todo', 33 - id: 1, 34 - nodes: [[4, 5]], 35 - author: { 36 - id: 2, 37 - __typename: 'Author', 38 - }, 39 - }) 40 - ).toEqual({ id: 1, nodes: [[4, 5]], author: { id: 2 } }); 41 - }); 42 - 43 - it('strips typename from nested objects with arrays', () => { 44 - expect( 45 - maskTypename({ 46 - __typename: 'Todo', 47 - id: 1, 48 - author: { 49 - id: 2, 50 - __typename: 'Author', 51 - books: [ 52 - { 53 - id: 3, 54 - __typename: 'Book', 55 - review: { id: 8, __typename: 'Review' }, 56 - }, 57 - { id: 4, __typename: 'Book' }, 58 - { id: 5, __typename: 'Book' }, 59 - ], 60 - }, 61 - }) 62 - ).toEqual({ 63 - id: 1, 64 - author: { 65 - id: 2, 66 - books: [{ id: 3, review: { id: 8 } }, { id: 4 }, { id: 5 }], 67 - }, 68 - }); 69 - }); 70 - 71 - it('strips typename in nested object from root', () => { 72 - expect(maskTypename({ root: { __typename: 'Todo', id: 1 } }, true)).toEqual({ 73 - root: { 74 - id: 1, 75 - }, 76 - }); 77 - }); 78 - 79 - it('doesn’t strip typename in sub-object when there is no __typename field', () => { 80 - expect(maskTypename({ subObject: { __typename: 'Todo', id: 1 } })).toEqual({ 81 - subObject: { 82 - __typename: 'Todo', 83 - id: 1, 84 - }, 85 - }); 86 - });
-40
packages/core/src/utils/maskTypename.ts
··· 1 - /** Used to recursively mark `__typename` fields in data as non-enumerable. 2 - * 3 - * @deprecated Not recommended over modelling inputs manually (See #3299) 4 - * 5 - * @remarks 6 - * This utility can be used to recursively copy GraphQl response data and hide 7 - * all `__typename` fields present on it. 8 - * 9 - * Hint: It’s not recommended to do this, unless it's absolutely necessary as 10 - * cloning and modifying all data of a response can be unnecessarily slow, when 11 - * a manual and more specific copy/mask is more efficient. 12 - * 13 - * @see {@link ClientOptions.maskTypename} for a description of how the `Client` uses this utility. 14 - */ 15 - export const maskTypename = (data: any, isRoot?: boolean): any => { 16 - if (!data || typeof data !== 'object') { 17 - return data; 18 - } else if (Array.isArray(data)) { 19 - return data.map(d => maskTypename(d)); 20 - } else if ( 21 - data && 22 - typeof data === 'object' && 23 - (isRoot || '__typename' in data) 24 - ) { 25 - const acc = {}; 26 - for (const key in data) { 27 - if (key === '__typename') { 28 - Object.defineProperty(acc, '__typename', { 29 - enumerable: false, 30 - value: data.__typename, 31 - }); 32 - } else { 33 - acc[key] = maskTypename(data[key]); 34 - } 35 - } 36 - return acc; 37 - } else { 38 - return data; 39 - } 40 - };
+2 -2
packages/preact-urql/README.md
··· 29 29 small example: 30 30 31 31 ```jsx 32 - import { createClient, dedupExchange, cacheExchange, fetchExchange, Provider, useQuery } from '@urql/preact'; 32 + import { createClient, cacheExchange, fetchExchange, Provider, useQuery } from '@urql/preact'; 33 33 34 34 const client = createClient({ 35 35 url: 'https://myHost/graphql', 36 - exchanges: [dedupExchange, cacheExchange, fetchExchange], 36 + exchanges: [cacheExchange, fetchExchange], 37 37 }); 38 38 39 39 const App = () => (
+2 -3
packages/react-urql/e2e-tests/useQuery.spec.tsx
··· 9 9 createClient, 10 10 gql, 11 11 useQuery, 12 - dedupExchange, 13 12 cacheExchange, 14 13 fetchExchange, 15 14 Exchange, ··· 70 69 const client = createClient({ 71 70 url: 'https://trygql.formidable.dev/graphql/basic-pokedex', 72 71 suspense: true, 73 - exchanges: [dedupExchange, cacheExchange, delayExchange, fetchExchange], 72 + exchanges: [cacheExchange, delayExchange, fetchExchange], 74 73 }); 75 74 76 75 // eslint-disable-next-line ··· 200 199 const client = createClient({ 201 200 url: 'https://trygql.formidable.dev/graphql/basic-pokedex', 202 201 suspense: false, 203 - exchanges: [dedupExchange, cacheExchange, delayExchange, fetchExchange], 202 + exchanges: [cacheExchange, delayExchange, fetchExchange], 204 203 }); 205 204 206 205 // eslint-disable-next-line
+2 -3
packages/react-urql/src/test-utils/ssr.test.tsx
··· 7 7 gql, 8 8 Client, 9 9 Exchange, 10 - dedupExchange, 11 10 cacheExchange, 12 11 ssrExchange, 13 12 OperationContext, ··· 96 95 client = new Client({ 97 96 url, 98 97 // We include the SSR exchange after the cache 99 - exchanges: [dedupExchange, cacheExchange, ssr, fetchExchange], 98 + exchanges: [cacheExchange, ssr, fetchExchange], 100 99 suspense: true, 101 100 }); 102 101 }); ··· 136 135 client = new Client({ 137 136 url, 138 137 // We include the SSR exchange after the cache 139 - exchanges: [dedupExchange, cacheExchange, ssr, fetchExchange], 138 + exchanges: [cacheExchange, ssr, fetchExchange], 140 139 suspense: false, 141 140 }); 142 141 });
+2 -2
packages/storage-rn/README.md
··· 19 19 Then add it to the offline exchange: 20 20 21 21 ```js 22 - import { createClient, dedupExchange, fetchExchange } from 'urql'; 22 + import { createClient, fetchExchange } from 'urql'; 23 23 import { offlineExchange } from '@urql/exchange-graphcache'; 24 24 import { makeAsyncStorage } from '@urql/storage-rn'; 25 25 ··· 42 42 43 43 const client = createClient({ 44 44 url: 'http://localhost:3000/graphql', 45 - exchanges: [dedupExchange, cache, fetchExchange], 45 + exchanges: [cache, fetchExchange], 46 46 }); 47 47 ```