{
  "version": 3,
  "sources": ["../../src/formatModuleTransforms/reduceNodeWatchQueryTransform.ts"],
  "sourcesContent": ["import {\n  DocumentNode,\n  GraphQLSchema,\n  visit,\n  visitWithTypeInfo,\n  TypeInfo,\n  isObjectType,\n  isInterfaceType,\n  getNamedType,\n  FragmentSpreadNode,\n  FragmentDefinitionNode,\n} from \"graphql\";\nimport invariant from \"invariant\";\n\nconst ALLOWED_REFETCH_QUERY_FIELD_SELECTIONS = [\n  \"__fragments\",\n  \"__typename\",\n  \"id\",\n];\n\n/**\n * Given the execution query document, that is the fat query that is used to\n * actually fetch the data, this transform will reduce the operation to limit\n * it to just the first fragment (on either a `Node` type of the `Query` type).\n * This is the operation that the `use*Fragment` hooks will use to observe the\n * Apollo Client store for data changes.\n *\n * @param schema The schema that the operation executes on\n * @param document The execution query document\n * @returns The watch query document\n */\nexport function reduceNodeWatchQueryTransform(\n  schema: GraphQLSchema,\n  document: DocumentNode,\n): DocumentNode {\n  const nodeType = schema.getType(\"Node\");\n  invariant(\n    nodeType && isInterfaceType(nodeType),\n    \"Expected schema to define a Node interface in order to support narrow observables.\",\n  );\n\n  const typeInfo = new TypeInfo(schema);\n  let retainFragment: string;\n\n  const removeNonWatchQueryFragmentNodes = (\n    node: FragmentSpreadNode | FragmentDefinitionNode,\n  ) => {\n    if (retainFragment && node.name.value === retainFragment) {\n      return undefined;\n    }\n    const unnamedTypeConstraint = typeInfo.getType();\n    invariant(unnamedTypeConstraint, \"Expected a type constraint\");\n    const typeConstraint = getNamedType(unnamedTypeConstraint);\n    if (\n      typeConstraint === schema.getQueryType() ||\n      ((isObjectType(typeConstraint) || isInterfaceType(typeConstraint)) &&\n        typeConstraint.getInterfaces().includes(nodeType))\n    ) {\n      return null;\n      // TODO: Handle fragment on Node ?\n      // } else if (isInterfaceType(typeConstraint)) {\n    }\n    return undefined;\n  };\n\n  return visit(\n    document,\n    visitWithTypeInfo(typeInfo, {\n      OperationDefinition(operationDefinitionNode) {\n        const selections = operationDefinitionNode.selectionSet!.selections;\n        const fragmentSpreadNode = selections.find(\n          (sel) => sel.kind === \"FragmentSpread\",\n        ) as FragmentSpreadNode;\n        if (\n          selections.length === 2 &&\n          fragmentSpreadNode &&\n          selections.find(\n            (sel) => sel.kind === \"Field\" && sel.name.value === \"__fragments\",\n          )\n        ) {\n          retainFragment = fragmentSpreadNode.name.value;\n        }\n      },\n      Field(fieldNode) {\n        const parentType = typeInfo.getParentType();\n        if (\n          fieldNode.name.value === \"node\" &&\n          parentType &&\n          parentType.name === \"Query\"\n        ) {\n          const selections = fieldNode.selectionSet!.selections;\n          const fragmentSpreadSelections = selections.filter(\n            (sel) => sel.kind === \"FragmentSpread\",\n          ) as FragmentSpreadNode[];\n          // This is a refetch query only if...\n          if (\n            // ...there's one fragment spread...\n            fragmentSpreadSelections.length === 1 ||\n            // ...and no fields but id and __typename...\n            selections.filter(\n              (sel) =>\n                sel.kind === \"Field\" &&\n                !ALLOWED_REFETCH_QUERY_FIELD_SELECTIONS.includes(\n                  sel.name.value,\n                ),\n            ).length === 0 ||\n            // ...and no inline fragment.\n            selections.filter((sel) => sel.kind === \"InlineFragment\").length ===\n              0\n          ) {\n            const fragmentSpreadNode = fragmentSpreadSelections[0];\n            retainFragment = fragmentSpreadNode.name.value;\n          }\n        }\n      },\n      FragmentSpread: removeNonWatchQueryFragmentNodes,\n      FragmentDefinition: removeNonWatchQueryFragmentNodes,\n    }),\n  );\n}\n"],
  "mappings": ";AAAA;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,OAAO,eAAe;AAEtB,IAAM,yCAAyC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF;AAaO,SAAS,8BACd,QACA,UACc;AACd,QAAM,WAAW,OAAO,QAAQ,MAAM;AACtC;AAAA,IACE,YAAY,gBAAgB,QAAQ;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,SAAS,MAAM;AACpC,MAAI;AAEJ,QAAM,mCAAmC,CACvC,SACG;AACH,QAAI,kBAAkB,KAAK,KAAK,UAAU,gBAAgB;AACxD,aAAO;AAAA,IACT;AACA,UAAM,wBAAwB,SAAS,QAAQ;AAC/C,cAAU,uBAAuB,4BAA4B;AAC7D,UAAM,iBAAiB,aAAa,qBAAqB;AACzD,QACE,mBAAmB,OAAO,aAAa,MACrC,aAAa,cAAc,KAAK,gBAAgB,cAAc,MAC9D,eAAe,cAAc,EAAE,SAAS,QAAQ,GAClD;AACA,aAAO;AAAA,IAGT;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA,kBAAkB,UAAU;AAAA,MAC1B,oBAAoB,yBAAyB;AAC3C,cAAM,aAAa,wBAAwB,aAAc;AACzD,cAAM,qBAAqB,WAAW;AAAA,UACpC,CAAC,QAAQ,IAAI,SAAS;AAAA,QACxB;AACA,YACE,WAAW,WAAW,KACtB,sBACA,WAAW;AAAA,UACT,CAAC,QAAQ,IAAI,SAAS,WAAW,IAAI,KAAK,UAAU;AAAA,QACtD,GACA;AACA,2BAAiB,mBAAmB,KAAK;AAAA,QAC3C;AAAA,MACF;AAAA,MACA,MAAM,WAAW;AACf,cAAM,aAAa,SAAS,cAAc;AAC1C,YACE,UAAU,KAAK,UAAU,UACzB,cACA,WAAW,SAAS,SACpB;AACA,gBAAM,aAAa,UAAU,aAAc;AAC3C,gBAAM,2BAA2B,WAAW;AAAA,YAC1C,CAAC,QAAQ,IAAI,SAAS;AAAA,UACxB;AAEA;AAAA;AAAA,YAEE,yBAAyB,WAAW;AAAA,YAEpC,WAAW;AAAA,cACT,CAAC,QACC,IAAI,SAAS,WACb,CAAC,uCAAuC;AAAA,gBACtC,IAAI,KAAK;AAAA,cACX;AAAA,YACJ,EAAE,WAAW;AAAA,YAEb,WAAW,OAAO,CAAC,QAAQ,IAAI,SAAS,gBAAgB,EAAE,WACxD;AAAA,YACF;AACA,kBAAM,qBAAqB,yBAAyB,CAAC;AACrD,6BAAiB,mBAAmB,KAAK;AAAA,UAC3C;AAAA,QACF;AAAA,MACF;AAAA,MACA,gBAAgB;AAAA,MAChB,oBAAoB;AAAA,IACtB,CAAC;AAAA,EACH;AACF;",
  "names": []
}
