···11+---
22+'@urql/exchange-graphcache': minor
33+---
44+55+Add optional `logger` to the options, this allows you to filter out warnings or disable them all together
+1
docs/api/graphcache.md
···3232| `optimistic` | A mapping of mutation fields to resolvers that may be used to provide _Graphcache_ with an optimistic result for a given mutation field that should be applied to the cached data temporarily. |
3333| `schema` | A serialized GraphQL schema that is used by _Graphcache_ to resolve partial data, interfaces, and enums. The schema also used to provide helpful warnings for [schema awareness](../graphcache/schema-awareness.md). |
3434| `storage` | A persisted storage interface that may be provided to preserve cache data for [offline support](../graphcache/offline.md). |
3535+| `logger` | A function that will be invoked for warning/debug/... logs |
35363637The `@urql/exchange-graphcache` package also exports the `offlineExchange`; which is identical to
3738the `cacheExchange` but activates [offline support](../graphcache/offline.md) when the `storage` option is passed.
···235235 ' but could only find ' +
236236 Object.keys(fragments).join(', ') +
237237 '.',
238238- 6
238238+ 6,
239239+ store.logger
239240 );
240241241242 return null;
···247248 warn(
248249 'readFragment(...) was called with an empty fragment.\n' +
249250 'You have to call it with at least one fragment in your GraphQL document.',
250250- 6
251251+ 6,
252252+ store.logger
251253 );
252254253255 return null;
···264266 'You have to pass an `id` or `_id` field or create a custom `keys` config for `' +
265267 typename +
266268 '`.',
267267- 7
269269+ 7,
270270+ store.logger
268271 );
269272270273 return null;
···327330 if (fieldResolver && directiveResolver) {
328331 warn(
329332 `A resolver and directive is being used at "${typename}.${fieldName}" simultaneously. Only the directive will apply.`,
330330- 28
333333+ 28,
334334+ ctx.store.logger
331335 );
332336 }
333337···356360 ctx.store.rootFields.subscription +
357361 '` types are special ' +
358362 'Operation Root Types and cannot be read back from the cache.',
359359- 25
363363+ 25,
364364+ store.logger
360365 );
361366 }
362367···373378 entityKey +
374379 '` returned an ' +
375380 'invalid typename that could not be reconciled with the cache.',
376376- 8
381381+ 8,
382382+ store.logger
377383 );
378384379385 return;
···406412 const resultValue = result ? result[fieldName] : undefined;
407413408414 if (process.env.NODE_ENV !== 'production' && store.schema && typename) {
409409- isFieldAvailableOnType(store.schema, typename, fieldName);
415415+ isFieldAvailableOnType(
416416+ store.schema,
417417+ typename,
418418+ fieldName,
419419+ ctx.store.logger
420420+ );
410421 }
411422412423 // Add the current alias to the walked path before processing the field's value
···466477 if (
467478 store.schema &&
468479 dataFieldValue === null &&
469469- !isFieldNullable(store.schema, typename, fieldName)
480480+ !isFieldNullable(store.schema, typename, fieldName, ctx.store.logger)
470481 ) {
471482 // Special case for when null is not a valid value for the
472483 // current field
···519530 dataFieldValue === undefined &&
520531 (directives.optional ||
521532 !!getFieldError(ctx) ||
522522- (store.schema && isFieldNullable(store.schema, typename, fieldName)))
533533+ (store.schema &&
534534+ isFieldNullable(store.schema, typename, fieldName, ctx.store.logger)))
523535 ) {
524536 // The field is uncached or has errored, so it'll be set to null and skipped
525537 ctx.partial = true;
···570582 // Check whether values of the list may be null; for resolvers we assume
571583 // that they can be, since it's user-provided data
572584 const _isListNullable = store.schema
573573- ? isListNullable(store.schema, typename, fieldName)
585585+ ? isListNullable(store.schema, typename, fieldName, ctx.store.logger)
574586 : false;
575587 const hasPartials = ctx.partial;
576588 const data = InMemoryData.makeData(prevData, true);
···622634 key +
623635 '` is a scalar (number, boolean, etc)' +
624636 ', but the GraphQL query expects a selection set for this field.',
625625- 9
637637+ 9,
638638+ ctx.store.logger
626639 );
627640628641 return undefined;
···641654 if (Array.isArray(link)) {
642655 const { store } = ctx;
643656 const _isListNullable = store.schema
644644- ? isListNullable(store.schema, typename, fieldName)
657657+ ? isListNullable(store.schema, typename, fieldName, ctx.store.logger)
645658 : false;
646659 const newLink = InMemoryData.makeData(prevData, true);
647660 const hasPartials = ctx.partial;
+9-4
exchanges/graphcache/src/operations/shared.ts
···2525 Link,
2626 Entity,
2727 Data,
2828+ Logger,
2829} from '../types';
29303031export interface Context {
···117118 node: FormattedNode<InlineFragmentNode | FragmentDefinitionNode>,
118119 typename: void | string,
119120 entityKey: string,
120120- vars: Variables
121121+ vars: Variables,
122122+ logger?: Logger
121123) => {
122124 if (!typename) return false;
123125 const typeCondition = getTypeCondition(node);
···134136 '` may be an ' +
135137 'interface.\nA schema needs to be defined for this match to be deterministic, ' +
136138 'otherwise the fragment will be matched heuristically!',
137137- 16
139139+ 16,
140140+ logger
138141 );
139142140143 return (
···192195 fragment,
193196 typename,
194197 entityKey,
195195- ctx.variables
198198+ ctx.variables,
199199+ ctx.store.logger
196200 ));
197201 if (isMatching) {
198202 if (process.env.NODE_ENV !== 'production')
···234238 '\nYou have to pass an `id` or `_id` field or create a custom `keys` config for `' +
235239 ref.__typename +
236240 '`.',
237237- 12
241241+ 12,
242242+ store.logger
238243 );
239244 }
240245
+18-7
exchanges/graphcache/src/operations/write.ts
···147147 ' but could only find ' +
148148 Object.keys(fragments).join(', ') +
149149 '.',
150150- 11
150150+ 11,
151151+ store.logger
151152 );
152153153154 return null;
···159160 warn(
160161 'writeFragment(...) was called with an empty fragment.\n' +
161162 'You have to call it with at least one fragment in your GraphQL document.',
162162- 11
163163+ 11,
164164+ store.logger
163165 );
164166165167 return null;
···175177 'You have to pass an `id` or `_id` field or create a custom `keys` config for `' +
176178 typename +
177179 '`.',
178178- 12
180180+ 12,
181181+ store.logger
179182 );
180183 }
181184···223226 warn(
224227 "Couldn't find __typename when writing.\n" +
225228 "If you're writing to the cache manually have to pass a `__typename` property on each entity in your data.",
226226- 14
229229+ 14,
230230+ ctx.store.logger
227231 );
228232 return;
229233 } else if (!isRoot && entityKey) {
···260264261265 if (process.env.NODE_ENV !== 'production') {
262266 if (ctx.store.schema && typename && fieldName !== '__typename') {
263263- isFieldAvailableOnType(ctx.store.schema, typename, fieldName);
267267+ isFieldAvailableOnType(
268268+ ctx.store.schema,
269269+ typename,
270270+ fieldName,
271271+ ctx.store.logger
272272+ );
264273 }
265274 }
266275···309318 '` is `undefined`, but the GraphQL query expects a ' +
310319 expected +
311320 ' for this field.',
312312- 13
321321+ 13,
322322+ ctx.store.logger
313323 );
314324 }
315325 }
···426436 'If this is intentional, create a `keys` config for `' +
427437 typename +
428438 '` that always returns null.',
429429- 15
439439+ 15,
440440+ ctx.store.logger
430441 );
431442 }
432443
···541541 | null
542542 | undefined;
543543544544+export type Logger = (
545545+ severity: 'debug' | 'error' | 'warn',
546546+ message: string
547547+) => void;
548548+544549/** Input parameters for the {@link cacheExchange}. */
545550export type CacheExchangeOpts = {
551551+ /** Configure a custom-logger for graphcache, this function wll be called with a severity and a message.
552552+ *
553553+ * @remarks
554554+ * By default we will invoke `console.warn` for warnings during development, however you might want to opt
555555+ * out of this because you are re-using urql for a different library. This setting allows you to stub the logger
556556+ * function or filter to only logs you want.
557557+ */
558558+ logger?: Logger;
546559 /** Configures update functions which are called when the mapped fields are written to the cache.
547560 *
548561 * @remarks