{
  "version": 3,
  "sources": ["../../src/formatModuleTransforms/extractMetadataTransform.ts"],
  "sourcesContent": ["import {\n  ArgumentNode,\n  DocumentNode,\n  FieldNode,\n  FragmentDefinitionNode,\n  FragmentSpreadNode,\n  OperationDefinitionNode,\n  ValueNode,\n  parseValue,\n  visit,\n  valueFromAST,\n  valueFromASTUntyped,\n  DirectiveNode,\n} from \"graphql\";\nimport invariant from \"invariant\";\n\ninterface ConnectionMetadata {\n  forwardCountVariable?: string;\n  forwardCursorVariable?: string;\n  backwardCountVariable?: string;\n  backwardCursorVariable?: string;\n  filterVariableDefaults?: Record<string, any>;\n  selectionPath: string[];\n}\nexport interface Metadata {\n  rootSelection?: string;\n  mainFragment?: {\n    name: string;\n    typeCondition: string;\n  };\n  connection?: ConnectionMetadata;\n}\n\n/**\n * This transform extracts metadata needed at runtime for the `use*Fragment`\n * hooks to do their work efficiently. This includes:\n *\n * - Whether or not the observed data starts at the root of the operation or at\n *   the `node` root-field.\n * - The name and type-condition of the fragment.\n * - Connection metadata such as location of the connection inside the fragment\n *   and the names of the various connection variables.\n *\n * @param document The watch query document\n * @returns The metadata needed at runtime\n */\nexport function extractMetadataTransform(\n  document: DocumentNode,\n): Metadata | undefined {\n  const metadata: Metadata = {};\n  const nodeFieldSelection = extractNodeFieldSelection(document);\n  if (nodeFieldSelection) {\n    metadata.rootSelection = \"node\";\n  }\n  const mainFragment = getMainFragmentMetadata(\n    document,\n    nodeFieldSelection?.name.value,\n  );\n  if (mainFragment) {\n    metadata.mainFragment = mainFragment;\n  }\n  const connectionMetadata = extractConnectionMetadataTransform(document);\n  if (connectionMetadata) {\n    metadata.connection = connectionMetadata;\n  }\n  return Object.keys(metadata).length > 0 ? metadata : undefined;\n}\n\nfunction getMainFragmentMetadata(\n  document: DocumentNode,\n  rootSelection: string | undefined,\n):\n  | {\n      name: string;\n      typeCondition: string;\n    }\n  | undefined {\n  const [operationDefinition, ...fragmentDefinitions] =\n    document.definitions as [\n      OperationDefinitionNode,\n      ...FragmentDefinitionNode[],\n    ];\n  invariant(\n    operationDefinition.kind === \"OperationDefinition\" &&\n      fragmentDefinitions.every((node) => node.kind === \"FragmentDefinition\"),\n    \"Expected definition nodes in specific order\",\n  );\n  if (fragmentDefinitions.length === 0) {\n    return undefined;\n  }\n  let selectionSet = operationDefinition.selectionSet;\n  if (rootSelection) {\n    const field = selectionSet.selections.find(\n      (selection) =>\n        selection.kind === \"Field\" && selection.name.value === rootSelection,\n    ) as FieldNode | undefined;\n    invariant(\n      field?.selectionSet,\n      \"Expected root selection to exist in document\",\n    );\n    selectionSet = field.selectionSet;\n  }\n  const mainFragmentSpread = selectionSet.selections.find(\n    (selection) => selection.kind === \"FragmentSpread\",\n  ) as FragmentSpreadNode | undefined;\n  if (!mainFragmentSpread) {\n    return undefined;\n  }\n  const mainFragment = fragmentDefinitions.find(\n    (fragment) => fragment.name.value === mainFragmentSpread.name.value,\n  );\n  invariant(mainFragment, \"Expected a main fragment\");\n  return {\n    name: mainFragment.name.value,\n    typeCondition: mainFragment.typeCondition.name.value,\n  };\n}\n\nfunction extractNodeFieldSelection(document: DocumentNode) {\n  const operationDefinition = document.definitions.find(\n    (def) => def.kind === \"OperationDefinition\",\n  ) as OperationDefinitionNode | undefined;\n  invariant(operationDefinition, \"Expected an operation\");\n  const nodeFieldSelection = operationDefinition.selectionSet.selections.find(\n    (selection) =>\n      selection.kind === \"Field\" && selection.name.value === \"node\",\n  ) as FieldNode | undefined;\n  return nodeFieldSelection;\n}\n\nfunction extractConnectionMetadataTransform(\n  document: DocumentNode,\n): ConnectionMetadata | undefined {\n  let foundConnection = false;\n  const metadata: ConnectionMetadata = { selectionPath: [] };\n  const variableDefaults = new Map<string, ValueNode | undefined>();\n  visit(document, {\n    VariableDefinition: {\n      enter(variableNode) {\n        variableDefaults.set(\n          variableNode.variable.name.value,\n          variableNode.defaultValue,\n        );\n      },\n    },\n    Field: {\n      enter(fieldNode) {\n        if (!foundConnection) {\n          metadata.selectionPath.push(fieldNode.name.value);\n        }\n        const connectionDirective = fieldNode.directives?.find(\n          (directive) => directive.name.value === \"connection\",\n        );\n        if (connectionDirective) {\n          invariant(\n            !foundConnection,\n            \"Expected to find a single connection in one document\",\n          );\n          foundConnection = true;\n\n          const fieldArguments = new Map(\n            fieldNode.arguments?.map((arg) => [arg.name.value, arg]),\n          );\n\n          metadata.forwardCountVariable = getVariableValue(\n            fieldArguments.get(\"first\"),\n          );\n          metadata.forwardCursorVariable = getVariableValue(\n            fieldArguments.get(\"after\"),\n          );\n          metadata.backwardCountVariable = getVariableValue(\n            fieldArguments.get(\"last\"),\n          );\n          metadata.backwardCursorVariable = getVariableValue(\n            fieldArguments.get(\"before\"),\n          );\n\n          metadata.filterVariableDefaults = extractFilterVariableDefaults(\n            connectionDirective,\n            fieldArguments,\n            variableDefaults,\n          );\n        }\n      },\n      leave() {\n        if (!foundConnection) {\n          metadata.selectionPath.pop();\n        }\n      },\n    },\n  });\n  if (foundConnection) {\n    invariant(\n      (metadata.forwardCountVariable && metadata.forwardCursorVariable) ||\n        (metadata.backwardCountVariable && metadata.backwardCursorVariable),\n      \"Expected correct count and cursor variables combinations\",\n    );\n    return metadata;\n  } else {\n    return undefined;\n  }\n}\n\nfunction getVariableValue(arg: ArgumentNode | undefined) {\n  return arg && arg.value.kind === \"Variable\"\n    ? arg.value.name.value\n    : undefined;\n}\n\nfunction extractFilterVariableDefaults(\n  connectionDirective: DirectiveNode,\n  fieldArguments: Map<string, ArgumentNode>,\n  variableDefaults: Map<string, ValueNode | undefined>,\n) {\n  invariant(\n    connectionDirective.arguments !== undefined,\n    \"Expected connection directive to have arguments\",\n  );\n  const filterVariableDefaults = new Map<string, any>();\n  const filters = connectionDirective.arguments.find(\n    (arg) => arg.name.value === \"filter\" || arg.name.value === \"filters\",\n  );\n  if (filters) {\n    invariant(\n      filters.value.kind === \"ListValue\",\n      \"Expected filters argument to be a list of field arguments\",\n    );\n    const fieldArgumentNames = filters.value.values.map((value) => {\n      invariant(\n        value.kind === \"StringValue\",\n        \"Expected field argument to be a string\",\n      );\n      return value.value;\n    });\n    fieldArgumentNames.forEach((name) => {\n      const arg = fieldArguments.get(name);\n      invariant(\n        arg !== undefined,\n        \"Expected filter name to refer to a field argument\",\n      );\n      const variable = getVariableValue(arg);\n      if (variable) {\n        const defaultValue = variableDefaults.get(variable);\n        if (defaultValue) {\n          filterVariableDefaults.set(variable, {\n            ...valueFromASTUntyped(defaultValue),\n          });\n        }\n      }\n    });\n  }\n  return filterVariableDefaults.size > 0\n    ? Object.fromEntries(filterVariableDefaults)\n    : undefined;\n}\n"],
  "mappings": ";AAAA;AAAA,EASE;AAAA,EAEA;AAAA,OAEK;AACP,OAAO,eAAe;AAgCf,SAAS,yBACd,UACsB;AACtB,QAAM,WAAqB,CAAC;AAC5B,QAAM,qBAAqB,0BAA0B,QAAQ;AAC7D,MAAI,oBAAoB;AACtB,aAAS,gBAAgB;AAAA,EAC3B;AACA,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,yDAAoB,KAAK;AAAA,EAC3B;AACA,MAAI,cAAc;AAChB,aAAS,eAAe;AAAA,EAC1B;AACA,QAAM,qBAAqB,mCAAmC,QAAQ;AACtE,MAAI,oBAAoB;AACtB,aAAS,aAAa;AAAA,EACxB;AACA,SAAO,OAAO,KAAK,QAAQ,EAAE,SAAS,IAAI,WAAW;AACvD;AAEA,SAAS,wBACP,UACA,eAMY;AACZ,QAAM,CAAC,qBAAqB,GAAG,mBAAmB,IAChD,SAAS;AAIX;AAAA,IACE,oBAAoB,SAAS,yBAC3B,oBAAoB,MAAM,CAAC,SAAS,KAAK,SAAS,oBAAoB;AAAA,IACxE;AAAA,EACF;AACA,MAAI,oBAAoB,WAAW,GAAG;AACpC,WAAO;AAAA,EACT;AACA,MAAI,eAAe,oBAAoB;AACvC,MAAI,eAAe;AACjB,UAAM,QAAQ,aAAa,WAAW;AAAA,MACpC,CAAC,cACC,UAAU,SAAS,WAAW,UAAU,KAAK,UAAU;AAAA,IAC3D;AACA;AAAA,MACE,+BAAO;AAAA,MACP;AAAA,IACF;AACA,mBAAe,MAAM;AAAA,EACvB;AACA,QAAM,qBAAqB,aAAa,WAAW;AAAA,IACjD,CAAC,cAAc,UAAU,SAAS;AAAA,EACpC;AACA,MAAI,CAAC,oBAAoB;AACvB,WAAO;AAAA,EACT;AACA,QAAM,eAAe,oBAAoB;AAAA,IACvC,CAAC,aAAa,SAAS,KAAK,UAAU,mBAAmB,KAAK;AAAA,EAChE;AACA,YAAU,cAAc,0BAA0B;AAClD,SAAO;AAAA,IACL,MAAM,aAAa,KAAK;AAAA,IACxB,eAAe,aAAa,cAAc,KAAK;AAAA,EACjD;AACF;AAEA,SAAS,0BAA0B,UAAwB;AACzD,QAAM,sBAAsB,SAAS,YAAY;AAAA,IAC/C,CAAC,QAAQ,IAAI,SAAS;AAAA,EACxB;AACA,YAAU,qBAAqB,uBAAuB;AACtD,QAAM,qBAAqB,oBAAoB,aAAa,WAAW;AAAA,IACrE,CAAC,cACC,UAAU,SAAS,WAAW,UAAU,KAAK,UAAU;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,mCACP,UACgC;AAChC,MAAI,kBAAkB;AACtB,QAAM,WAA+B,EAAE,eAAe,CAAC,EAAE;AACzD,QAAM,mBAAmB,oBAAI,IAAmC;AAChE,QAAM,UAAU;AAAA,IACd,oBAAoB;AAAA,MAClB,MAAM,cAAc;AAClB,yBAAiB;AAAA,UACf,aAAa,SAAS,KAAK;AAAA,UAC3B,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,MAAM,WAAW;AAlJvB;AAmJQ,YAAI,CAAC,iBAAiB;AACpB,mBAAS,cAAc,KAAK,UAAU,KAAK,KAAK;AAAA,QAClD;AACA,cAAM,uBAAsB,eAAU,eAAV,mBAAsB;AAAA,UAChD,CAAC,cAAc,UAAU,KAAK,UAAU;AAAA;AAE1C,YAAI,qBAAqB;AACvB;AAAA,YACE,CAAC;AAAA,YACD;AAAA,UACF;AACA,4BAAkB;AAElB,gBAAM,iBAAiB,IAAI;AAAA,aACzB,eAAU,cAAV,mBAAqB,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,OAAO,GAAG;AAAA,UACxD;AAEA,mBAAS,uBAAuB;AAAA,YAC9B,eAAe,IAAI,OAAO;AAAA,UAC5B;AACA,mBAAS,wBAAwB;AAAA,YAC/B,eAAe,IAAI,OAAO;AAAA,UAC5B;AACA,mBAAS,wBAAwB;AAAA,YAC/B,eAAe,IAAI,MAAM;AAAA,UAC3B;AACA,mBAAS,yBAAyB;AAAA,YAChC,eAAe,IAAI,QAAQ;AAAA,UAC7B;AAEA,mBAAS,yBAAyB;AAAA,YAChC;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,QAAQ;AACN,YAAI,CAAC,iBAAiB;AACpB,mBAAS,cAAc,IAAI;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACD,MAAI,iBAAiB;AACnB;AAAA,MACG,SAAS,wBAAwB,SAAS,yBACxC,SAAS,yBAAyB,SAAS;AAAA,MAC9C;AAAA,IACF;AACA,WAAO;AAAA,EACT,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBAAiB,KAA+B;AACvD,SAAO,OAAO,IAAI,MAAM,SAAS,aAC7B,IAAI,MAAM,KAAK,QACf;AACN;AAEA,SAAS,8BACP,qBACA,gBACA,kBACA;AACA;AAAA,IACE,oBAAoB,cAAc;AAAA,IAClC;AAAA,EACF;AACA,QAAM,yBAAyB,oBAAI,IAAiB;AACpD,QAAM,UAAU,oBAAoB,UAAU;AAAA,IAC5C,CAAC,QAAQ,IAAI,KAAK,UAAU,YAAY,IAAI,KAAK,UAAU;AAAA,EAC7D;AACA,MAAI,SAAS;AACX;AAAA,MACE,QAAQ,MAAM,SAAS;AAAA,MACvB;AAAA,IACF;AACA,UAAM,qBAAqB,QAAQ,MAAM,OAAO,IAAI,CAAC,UAAU;AAC7D;AAAA,QACE,MAAM,SAAS;AAAA,QACf;AAAA,MACF;AACA,aAAO,MAAM;AAAA,IACf,CAAC;AACD,uBAAmB,QAAQ,CAAC,SAAS;AACnC,YAAM,MAAM,eAAe,IAAI,IAAI;AACnC;AAAA,QACE,QAAQ;AAAA,QACR;AAAA,MACF;AACA,YAAM,WAAW,iBAAiB,GAAG;AACrC,UAAI,UAAU;AACZ,cAAM,eAAe,iBAAiB,IAAI,QAAQ;AAClD,YAAI,cAAc;AAChB,iCAAuB,IAAI,UAAU;AAAA,YACnC,GAAG,oBAAoB,YAAY;AAAA,UACrC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO,uBAAuB,OAAO,IACjC,OAAO,YAAY,sBAAsB,IACzC;AACN;",
  "names": []
}
