From 7148e5f5bf83c252065d12535e66ac2f5fe6282e Mon Sep 17 00:00:00 2001 From: jdecroock Date: Wed, 19 Jul 2023 19:49:18 +0200 Subject: [PATCH] use underscored props --- docs/graphcache/local-directives.md | 31 ++++++++++++++++++- docs/graphcache/local-resolvers.md | 2 +- .../graphcache/src/cacheExchange.test.ts | 4 +-- exchanges/graphcache/src/cacheExchange.ts | 1 - .../src/extras/relayPagination.test.ts | 2 +- .../src/extras/simplePagination.test.ts | 2 +- exchanges/graphcache/src/operations/query.ts | 9 ++---- exchanges/graphcache/src/types.ts | 20 ++++++++++-- 8 files changed, 56 insertions(+), 15 deletions(-) diff --git a/docs/graphcache/local-directives.md b/docs/graphcache/local-directives.md index 568df7a69d..a92dacc5b6 100644 --- a/docs/graphcache/local-directives.md +++ b/docs/graphcache/local-directives.md @@ -1,4 +1,33 @@ --- title: Local Directives -order: 2 +order: 3 --- + +# Local Directives + +Graphcache supports adding directives to GraphQL Documents, when we prefix a +directive with an underscore (`_`) it will be stripped from the document and stored +on the `_directives` property on the AST-node. + +> Ensure you prefix directives with `_` if you only want to alter local behavior. + +By default graphcache will add two directives `@_optional` and `@_required` which +allow you to mark fields as being optional or mandatory. + +If you want to add directives yourself you can do so by performing + +```js +cacheExchange({ + directives: { + // If you now add `@_pagination` to your document we will execute this + pagination: () => {}, + }, +}); +``` + +The function signature of a directive is the same as the one of a [Resolver](./local-directives.md). In +case you need to access the arguments you have passed to a directive you can do so by checking `info.directiveArguments`. + +### Reading on + +[On the next page we'll learn about "Cache Updates".](./cache-updates.md) diff --git a/docs/graphcache/local-resolvers.md b/docs/graphcache/local-resolvers.md index 0c004d13d9..fdf19a4497 100644 --- a/docs/graphcache/local-resolvers.md +++ b/docs/graphcache/local-resolvers.md @@ -565,4 +565,4 @@ cannot be stiched together. ### Reading on -[On the next page we'll learn about "Cache Updates".](./cache-updates.md) +[On the next page we'll learn about "Cache Directives".](./local-directives.md) diff --git a/exchanges/graphcache/src/cacheExchange.test.ts b/exchanges/graphcache/src/cacheExchange.test.ts index 82777f224b..2dd212beba 100644 --- a/exchanges/graphcache/src/cacheExchange.test.ts +++ b/exchanges/graphcache/src/cacheExchange.test.ts @@ -691,7 +691,7 @@ describe('directives', () => { todos { id text - completed @optional + completed @_optional } } `; @@ -763,7 +763,7 @@ describe('directives', () => { todos { id text - completed @required + completed @_required } } `; diff --git a/exchanges/graphcache/src/cacheExchange.ts b/exchanges/graphcache/src/cacheExchange.ts index b17fbffb88..7d0594e135 100644 --- a/exchanges/graphcache/src/cacheExchange.ts +++ b/exchanges/graphcache/src/cacheExchange.ts @@ -237,7 +237,6 @@ export const cacheExchange = operations.set(operation.key, operation); updateDependencies(operation, result.dependencies); - // TODO: remove directives before sending it on return { outcome: cacheOutcome, operation, diff --git a/exchanges/graphcache/src/extras/relayPagination.test.ts b/exchanges/graphcache/src/extras/relayPagination.test.ts index 29a1486f42..8f45be42b6 100644 --- a/exchanges/graphcache/src/extras/relayPagination.test.ts +++ b/exchanges/graphcache/src/extras/relayPagination.test.ts @@ -1542,7 +1542,7 @@ describe('as directive', () => { const Pagination = gql` query ($cursor: String) { __typename - items(first: 1, after: $cursor) @relayPagination { + items(first: 1, after: $cursor) @_relayPagination { __typename edges { __typename diff --git a/exchanges/graphcache/src/extras/simplePagination.test.ts b/exchanges/graphcache/src/extras/simplePagination.test.ts index d1f1e6242b..a675f1115f 100644 --- a/exchanges/graphcache/src/extras/simplePagination.test.ts +++ b/exchanges/graphcache/src/extras/simplePagination.test.ts @@ -443,7 +443,7 @@ describe('as directive', () => { const Pagination = gql` query ($skip: Number, $limit: Number) { __typename - persons(skip: $skip, limit: $limit) @simplePagination { + persons(skip: $skip, limit: $limit) @_simplePagination { __typename id name diff --git a/exchanges/graphcache/src/operations/query.ts b/exchanges/graphcache/src/operations/query.ts index 6c30f19d79..d4d1d280e1 100644 --- a/exchanges/graphcache/src/operations/query.ts +++ b/exchanges/graphcache/src/operations/query.ts @@ -356,8 +356,8 @@ const readSelection = ( let node: FormattedNode | void; const output = InMemoryData.makeData(input); while ((node = iterate()) !== undefined) { - const fieldDirectives = node.directives?.map(x => x.name.value); - const storeDirective = fieldDirectives?.find(x => store.directives[x]); + const fieldDirectives = Object.keys(node._directives || {}).map(x => x); + const storeDirective = fieldDirectives.find(x => store.directives[x]); // Derive the needed data from our node. const fieldName = getName(node); @@ -415,9 +415,7 @@ const readSelection = ( } if (storeDirective) { - const fieldDirective = node.directives!.find( - x => x.name.value === storeDirective - )!; + const fieldDirective = node._directives![storeDirective]; const directiveArguments = getFieldArguments(fieldDirective, ctx.variables) || {}; dataFieldValue = store.directives[storeDirective]!( @@ -448,7 +446,6 @@ const readSelection = ( if ( store.schema && dataFieldValue === null && - // TODO: how would we inform this that we are indeed dealing with a nullable field !isFieldNullable(store.schema, typename, fieldName) ) { // Special case for when null is not a valid value for the diff --git a/exchanges/graphcache/src/types.ts b/exchanges/graphcache/src/types.ts index f528a8af15..4dfb126e53 100644 --- a/exchanges/graphcache/src/types.ts +++ b/exchanges/graphcache/src/types.ts @@ -555,7 +555,14 @@ export type CacheExchangeOpts = { * @see {@link https://urql.dev/goto/docs/graphcache/local-resolvers} for the full resolvers docs. */ resolvers?: ResolverConfig; - // TODO: docs + /** Configures directives which can perform custom logic on fields. + * + * @remarks + * `directives` is a map of a directive-name to a function which will be executed + * when graphcache encounters this directive. + * + * @see {@link https://urql.dev/goto/docs/graphcache/local-directives} for the full directives docs. + */ directives?: DirectivesConfig; /** Configures optimistic updates to react to mutations instantly before an API response. * @@ -678,6 +685,16 @@ export type Resolver< ): Result; }['bivarianceHack']; +/** Cache Directive, which may resolve or replace data during cache reads. + * + * @param parent - The GraphQL object that is currently being constructed from cache data. + * @param args - This field’s arguments. + * @param cache - {@link Cache} interface. + * @param info - {@link ResolveInfo} interface. + * @returns a {@link ResolverResult}, which is an updated value, partial entity, or entity key + * + * @see {@link https://urql.dev/goto/docs/graphcache/local-directives} for the full directives docs. + */ export type Directive< ParentData = DataFields, Args = Variables, @@ -708,7 +725,6 @@ export type ResolverConfig = { } | void; }; -// TODO: docs export type DirectivesConfig = { [directiveName: string]: Directive; };