From a499abff92d812aeca0db54c079b93dd7e53d1bf Mon Sep 17 00:00:00 2001 From: jdecroock Date: Fri, 19 Jan 2024 10:31:45 +0100 Subject: [PATCH] allow for unmasking a fragment by means of a directive --- .../src/components/PokemonList.tsx | 3 ++- src/namespace.ts | 4 ++++ src/selection.ts | 23 ++++++++++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/examples/example-pokemon-api/src/components/PokemonList.tsx b/examples/example-pokemon-api/src/components/PokemonList.tsx index d06f4451..ff7dd016 100644 --- a/examples/example-pokemon-api/src/components/PokemonList.tsx +++ b/examples/example-pokemon-api/src/components/PokemonList.tsx @@ -7,6 +7,7 @@ const PokemonsQuery = graphql(` query Pokemons ($limit: Int = 10) { pokemons(limit: $limit) { id + ...PokemonItem @mask_disable ...PokemonItem } } @@ -27,7 +28,7 @@ const PokemonList = () => { } else if (fetching || !data) { return

Loading...

} - + return (
{data.pokemons ? ( diff --git a/src/namespace.ts b/src/namespace.ts index 43b0770f..0b7a56e3 100644 --- a/src/namespace.ts +++ b/src/namespace.ts @@ -26,6 +26,7 @@ interface FragmentDefDecorationLike { kind: Kind.FRAGMENT_DEFINITION; name: any; typeCondition: any; + selectionSet: any; } interface DocumentDefDecorationLike extends DocumentNode { @@ -36,12 +37,14 @@ type decorateFragmentDef = Document['definiti kind: Kind.FRAGMENT_DEFINITION; name: any; typeCondition: any; + selectionSet: any; } ? { // NOTE: This is a shortened definition for readability in LSP hovers kind: Kind.FRAGMENT_DEFINITION; name: Document['definitions'][0]['name']; typeCondition: Document['definitions'][0]['typeCondition']; + selectionSet: Document['definitions'][0]['selectionSet']; readonly [$tada.fragmentId]: unique symbol; } : never; @@ -55,6 +58,7 @@ type getFragmentsOfDocumentsRec = Documents extends readonly [ kind: Kind.FRAGMENT_DEFINITION; name: any; typeCondition: any; + selectionSet: any; } ? { [Name in FragmentDef['name']['value']]: FragmentDef } : {} diff --git a/src/selection.ts b/src/selection.ts index a2528901..289529f0 100644 --- a/src/selection.ts +++ b/src/selection.ts @@ -11,8 +11,9 @@ import type { DocumentNodeLike } from './parser'; import type { FragmentDefDecorationLike, - makeUndefinedFragmentRef, + //makeUndefinedFragmentRef, makeFragmentRef, + makeUndefinedFragmentRef, } from './namespace'; import type { @@ -69,6 +70,15 @@ type isOptionalRec = : isOptionalRec : false; +type isUnmaskedFragmentRec = + Directives extends readonly [infer Directive, ...infer Rest] + ? Directive extends { kind: Kind.DIRECTIVE; name: any } + ? Directive['name']['value'] extends 'mask_disable' + ? true + : isUnmaskedFragmentRec + : isUnmaskedFragmentRec + : false; + type getFieldAlias = Node['alias'] extends undefined ? Node['name']['value'] : Node['alias'] extends NameNode @@ -82,10 +92,17 @@ type getFragmentSelection< Fragments extends { [name: string]: any }, > = Node extends { kind: Kind.INLINE_FRAGMENT; selectionSet: any } ? getSelection - : Node extends { kind: Kind.FRAGMENT_SPREAD; name: any } + : Node extends { kind: Kind.FRAGMENT_SPREAD; name: any; directives: any[] } ? Node['name']['value'] extends keyof Fragments ? Fragments[Node['name']['value']] extends FragmentDefDecorationLike - ? makeFragmentRef + ? isUnmaskedFragmentRec extends true + ? getSelection< + Fragments[Node['name']['value']]['selectionSet']['selections'], + Type, + Introspection, + Fragments + > + : makeFragmentRef : getSelection< Fragments[Node['name']['value']]['selectionSet']['selections'], Type,