From 43bde4e223dbbf5d400218cf6b59fbe3c74eb733 Mon Sep 17 00:00:00 2001 From: Subin Ahn <51507260+anxiubin@users.noreply.github.com> Date: Fri, 15 Dec 2023 17:57:05 +0900 Subject: [PATCH] :art: Rollback fragment-masking --- src/lib/graphql/fragment-masking.ts | 85 +++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/lib/graphql/fragment-masking.ts diff --git a/src/lib/graphql/fragment-masking.ts b/src/lib/graphql/fragment-masking.ts new file mode 100644 index 0000000..373a5ce --- /dev/null +++ b/src/lib/graphql/fragment-masking.ts @@ -0,0 +1,85 @@ +import { + ResultOf, + DocumentTypeDecoration, + TypedDocumentNode, +} from "@graphql-typed-document-node/core"; +import { FragmentDefinitionNode } from "graphql"; +import { Incremental } from "./graphql"; + +export type FragmentType< + TDocumentType extends DocumentTypeDecoration, +> = TDocumentType extends DocumentTypeDecoration + ? [TType] extends [{ " $fragmentName"?: infer TKey }] + ? TKey extends string + ? { " $fragmentRefs"?: { [key in TKey]: TType } } + : never + : never + : never; + +// return non-nullable if `fragmentType` is non-nullable +export function useFragment( + _documentNode: DocumentTypeDecoration, + fragmentType: FragmentType>, +): TType; +// return nullable if `fragmentType` is nullable +export function useFragment( + _documentNode: DocumentTypeDecoration, + fragmentType: + | FragmentType> + | null + | undefined, +): TType | null | undefined; +// return array of non-nullable if `fragmentType` is array of non-nullable +export function useFragment( + _documentNode: DocumentTypeDecoration, + fragmentType: ReadonlyArray>>, +): ReadonlyArray; +// return array of nullable if `fragmentType` is array of nullable +export function useFragment( + _documentNode: DocumentTypeDecoration, + fragmentType: + | ReadonlyArray>> + | null + | undefined, +): ReadonlyArray | null | undefined; +export function useFragment( + _documentNode: DocumentTypeDecoration, + fragmentType: + | FragmentType> + | ReadonlyArray>> + | null + | undefined, +): TType | ReadonlyArray | null | undefined { + return fragmentType as any; +} + +export function makeFragmentData< + F extends DocumentTypeDecoration, + FT extends ResultOf, +>(data: FT, _fragment: F): FragmentType { + return data as FragmentType; +} +export function isFragmentReady( + queryNode: DocumentTypeDecoration, + fragmentNode: TypedDocumentNode, + data: + | FragmentType, any>> + | null + | undefined, +): data is FragmentType { + const deferredFields = ( + queryNode as { + __meta__?: { deferredFields: Record }; + } + ).__meta__?.deferredFields; + + if (!deferredFields) return true; + + const fragDef = fragmentNode.definitions[0] as + | FragmentDefinitionNode + | undefined; + const fragName = fragDef?.name?.value; + + const fields = (fragName && deferredFields[fragName]) || []; + return fields.length > 0 && fields.every((field) => data && field in data); +}