{"version":3,"file":"template-extraction.cjs","names":["content: string | undefined","templates: ExtractedTemplate[]","kind: string","elementName: string | undefined","typeName: string | undefined","typeNameSpan: { start: number; end: number } | undefined","expressionRanges: { start: number; end: number }[]","parts: string[]","template: ExtractedTemplate","trees: ExtractedFieldTree[]","bodyExpr: { type: string } | undefined","children: FieldCallNode[]","branches: UnionBranchNode[]","prefix","prefixPattern","edits: TemplateFormatEdit[]","formatted: string"],"sources":["../src/template-extraction/extract.ts","../src/template-extraction/format.ts"],"sourcesContent":["/**\n * Template extraction from TypeScript source using SWC AST.\n *\n * Based on the typegen extractor (superset): supports both bare-tag\n * (`query\\`...\\``) and curried (`query(\"Name\")\\`...\\``) syntax.\n *\n * Position tracking is optional — pass spanOffset + converter to\n * populate contentRange on extracted templates.\n *\n * @module\n */\n\n// Re-export for convenience — SWC types are type-only imports\nimport type {\n  ArrowFunctionExpression,\n  CallExpression,\n  MemberExpression,\n  Node,\n  ObjectExpression,\n  TaggedTemplateExpression,\n} from \"@swc/types\";\nimport type { SwcSpanConverter } from \"../utils/swc-span\";\nimport type {\n  ExtractedFieldTree,\n  ExtractedTemplate,\n  ExtractedTemplateWithPosition,\n  FieldCallNested,\n  FieldCallNode,\n  OperationKind,\n  UnionBranchNode,\n} from \"./types\";\n\nexport const OPERATION_KINDS = new Set<string>([\"query\", \"mutation\", \"subscription\", \"fragment\"]);\n\nexport const isOperationKind = (value: string): value is OperationKind => OPERATION_KINDS.has(value);\n\n/** Optional position tracking context for extraction. */\nexport type PositionTrackingContext = {\n  readonly spanOffset: number;\n  readonly converter: SwcSpanConverter;\n};\n\n/**\n * Check if a call expression is a gql.{schemaName}(...) call.\n * Returns the schema name if it is, null otherwise.\n */\nexport const getGqlCallSchemaName = (identifiers: ReadonlySet<string>, call: CallExpression): string | null => {\n  const callee = call.callee;\n  if (callee.type !== \"MemberExpression\") {\n    return null;\n  }\n\n  const member = callee as MemberExpression;\n  if (member.object.type !== \"Identifier\" || !identifiers.has(member.object.value)) {\n    return null;\n  }\n\n  if (member.property.type !== \"Identifier\") {\n    return null;\n  }\n\n  const firstArg = call.arguments[0];\n  if (!firstArg?.expression || firstArg.expression.type !== \"ArrowFunctionExpression\") {\n    return null;\n  }\n\n  return member.property.value;\n};\n\n/**\n * Find the curried name call (e.g., `query(\"Name\")`) from a callback builder expression.\n * Unwraps trailing call expressions like `({})` or `({ metadata: ... })`.\n *\n * Returns `{ curriedCall, configCall }` where:\n * - curriedCall: the `query(\"Name\")` CallExpression\n * - configCall: the `({ variables, fields })` CallExpression\n *\n * Returns null if the expression doesn't match the callback builder pattern.\n */\nconst findCallbackBuilderCalls = (expr: Node): { curriedCall: CallExpression; configCall: CallExpression } | null => {\n  if (expr.type !== \"CallExpression\") return null;\n  const call = expr as unknown as CallExpression;\n\n  // Unwrap trailing call: query(\"Name\")({ ... })({}) → get to query(\"Name\")({ ... })\n  // The trailing call's callee is the config call, whose callee is the curried name call.\n  // We need to find the config call that has an ObjectExpression argument\n  // and whose callee is a curried name call (CallExpression with Identifier callee).\n\n  // Try current level as config call first (no trailing call case)\n  if (call.callee.type === \"CallExpression\") {\n    const maybeConfigCall = call;\n    const maybeCurriedCall = call.callee as CallExpression;\n\n    // Check if maybeCurriedCall is a curried name call: query(\"Name\")\n    if (maybeCurriedCall.callee.type === \"Identifier\" && isOperationKind(maybeCurriedCall.callee.value)) {\n      // This is: curriedCall({ ... }) — no trailing call, expr IS the config call\n      const configArg = maybeConfigCall.arguments[0]?.expression;\n      if (configArg?.type === \"ObjectExpression\") {\n        return { curriedCall: maybeCurriedCall, configCall: maybeConfigCall };\n      }\n    }\n\n    // Check if maybeCurriedCall is the config call (trailing call case)\n    // expr is: trailing({}) where trailing.callee = configCall\n    if (maybeCurriedCall.callee.type === \"CallExpression\") {\n      const innerCurriedCall = maybeCurriedCall.callee as CallExpression;\n      if (innerCurriedCall.callee.type === \"Identifier\" && isOperationKind(innerCurriedCall.callee.value)) {\n        const configArg = maybeCurriedCall.arguments[0]?.expression;\n        if (configArg?.type === \"ObjectExpression\") {\n          return { curriedCall: innerCurriedCall, configCall: maybeCurriedCall };\n        }\n      }\n    }\n  }\n\n  return null;\n};\n\n/**\n * Extract variables template from a callback builder options object.\n * Handles patterns like:\n * - `query(\"Name\")({ variables: \\`($id: ID!)\\`, fields: ... })({})`\n * - `query(\"Name\")({ variables: \"($id: ID!)\", fields: ... })`\n *\n * Returns true if a callback builder pattern was detected (even if no variables property found).\n */\nexport const extractVariablesFromCallbackBuilder = (\n  expr: Node,\n  schemaName: string,\n  templates: ExtractedTemplate[],\n  positionCtx?: PositionTrackingContext,\n): boolean => {\n  const result = findCallbackBuilderCalls(expr);\n  if (!result) return false;\n\n  const { curriedCall, configCall } = result;\n\n  // Extract elementName from curried call\n  const nameArg = curriedCall.arguments[0]?.expression;\n  const elementName = nameArg?.type === \"StringLiteral\" ? (nameArg as { value: string }).value : undefined;\n\n  // Extract kind from curried call\n  const kind = (curriedCall.callee as { value: string }).value;\n\n  // Find variables property in config object\n  const configObj = configCall.arguments[0]?.expression as ObjectExpression;\n  for (const prop of configObj.properties) {\n    if (prop.type !== \"KeyValueProperty\") continue;\n    if (prop.key.type !== \"Identifier\" || (prop.key as { value: string }).value !== \"variables\") continue;\n\n    const value = prop.value;\n    let content: string | undefined;\n    let contentStart = -1;\n    let contentEnd = -1;\n\n    if (value.type === \"TemplateLiteral\") {\n      // Template literal: `($id: ID!)`\n      const tpl = value as unknown as { quasis: { raw: string; cooked?: string; span: { start: number; end: number } }[] };\n      if (tpl.quasis.length > 0) {\n        content = tpl.quasis[0]!.cooked ?? tpl.quasis[0]!.raw;\n        if (positionCtx) {\n          contentStart = positionCtx.converter.byteOffsetToCharIndex(tpl.quasis[0]!.span.start - positionCtx.spanOffset);\n          contentEnd = positionCtx.converter.byteOffsetToCharIndex(tpl.quasis[0]!.span.end - positionCtx.spanOffset);\n        }\n      }\n    } else if (value.type === \"StringLiteral\") {\n      // StringLiteral span is in byte space and includes quote delimiters.\n      // Adjust in byte space before byteOffsetToCharIndex conversion.\n      // Safe because quote characters (\", ') are ASCII (1 byte in UTF-8).\n      const strLit = value as unknown as { value: string; span: { start: number; end: number } };\n      content = strLit.value;\n      if (positionCtx) {\n        contentStart = positionCtx.converter.byteOffsetToCharIndex(strLit.span.start + 1 - positionCtx.spanOffset);\n        contentEnd = positionCtx.converter.byteOffsetToCharIndex(strLit.span.end - 1 - positionCtx.spanOffset);\n      }\n    }\n\n    if (content !== undefined) {\n      templates.push({\n        schemaName,\n        kind: kind as OperationKind,\n        content,\n        source: \"callback-variables\",\n        ...(elementName !== undefined ? { elementName } : {}),\n        ...(positionCtx && contentStart !== -1 && contentEnd !== -1\n          ? { contentRange: { start: contentStart, end: contentEnd } }\n          : {}),\n      });\n    }\n\n    break;\n  }\n\n  return true;\n};\n\n/**\n * Extract templates from a gql callback's arrow function body.\n * Handles tagged templates, metadata chaining, and callback builder variables.\n */\nexport const extractTemplatesFromCallback = (\n  arrow: ArrowFunctionExpression,\n  schemaName: string,\n  positionCtx?: PositionTrackingContext,\n): ExtractedTemplate[] => {\n  const templates: ExtractedTemplate[] = [];\n\n  const processExpression = (expr: Node): void => {\n    // Direct tagged template: query(\"Name\")`...`\n    if (expr.type === \"TaggedTemplateExpression\") {\n      const tagged = expr as unknown as TaggedTemplateExpression;\n      extractFromTaggedTemplate(tagged, schemaName, templates, positionCtx);\n      return;\n    }\n\n    // CallExpression paths: metadata chaining or callback builder\n    if (expr.type === \"CallExpression\") {\n      const call = expr as unknown as CallExpression;\n\n      // Metadata chaining: query(\"Name\")`...`({ metadata: {} })\n      if (call.callee.type === \"TaggedTemplateExpression\") {\n        extractFromTaggedTemplate(call.callee as TaggedTemplateExpression, schemaName, templates, positionCtx);\n        return;\n      }\n\n      // Callback builder: query(\"Name\")({ variables: `...`, fields: ... })({})\n      extractVariablesFromCallbackBuilder(expr, schemaName, templates, positionCtx);\n    }\n  };\n\n  // Expression body: ({ query }) => query(\"Name\")`...`\n  if (arrow.body.type !== \"BlockStatement\") {\n    processExpression(arrow.body);\n    return templates;\n  }\n\n  // Block body: ({ query }) => { return query(\"Name\")`...`; }\n  for (const stmt of arrow.body.stmts) {\n    if (stmt.type === \"ReturnStatement\" && stmt.argument) {\n      processExpression(stmt.argument);\n    }\n  }\n\n  return templates;\n};\n\n/**\n * Extract a single template from a tagged template expression.\n * Supports both bare-tag (Identifier) and curried (CallExpression) tag forms.\n */\nexport const extractFromTaggedTemplate = (\n  tagged: TaggedTemplateExpression,\n  schemaName: string,\n  templates: ExtractedTemplate[],\n  positionCtx?: PositionTrackingContext,\n): void => {\n  // Tag can be:\n  // - CallExpression: query(\"name\")`...` or fragment(\"name\", \"type\")`...` (curried syntax)\n  // - Identifier: legacy bare-tag form (skipped if it contains interpolations)\n  let kind: string;\n  let elementName: string | undefined;\n  let typeName: string | undefined;\n  let typeNameSpan: { start: number; end: number } | undefined;\n\n  if (tagged.tag.type === \"Identifier\") {\n    kind = tagged.tag.value;\n  } else if (tagged.tag.type === \"CallExpression\") {\n    const tagCall = tagged.tag as CallExpression;\n    if (tagCall.callee.type === \"Identifier\") {\n      kind = tagCall.callee.value;\n    } else {\n      return;\n    }\n    // Extract elementName and typeName from call arguments\n    const firstArg = tagCall.arguments[0]?.expression;\n    if (firstArg?.type === \"StringLiteral\") {\n      elementName = (firstArg as { value: string }).value;\n    }\n    const secondArg = tagCall.arguments[1]?.expression;\n    if (secondArg?.type === \"StringLiteral\") {\n      typeName = (secondArg as { value: string }).value;\n      if (positionCtx) {\n        typeNameSpan = {\n          start: positionCtx.converter.byteOffsetToCharIndex(secondArg.span.start + 1 - positionCtx.spanOffset),\n          end: positionCtx.converter.byteOffsetToCharIndex(secondArg.span.end - 1 - positionCtx.spanOffset),\n        };\n      }\n    }\n  } else {\n    return;\n  }\n\n  if (!isOperationKind(kind)) {\n    return;\n  }\n\n  const { quasis, expressions } = tagged.template;\n\n  // For legacy Identifier tag, skip templates with interpolations\n  if (tagged.tag.type === \"Identifier\" && expressions.length > 0) {\n    return;\n  }\n\n  if (quasis.length === 0) {\n    return;\n  }\n\n  // Build content and optionally track position\n  let contentStart = -1;\n  let contentEnd = -1;\n  const expressionRanges: { start: number; end: number }[] = [];\n\n  const parts: string[] = [];\n  for (let i = 0; i < quasis.length; i++) {\n    const quasi = quasis[i];\n    if (!quasi) continue;\n\n    if (positionCtx) {\n      const quasiStart = positionCtx.converter.byteOffsetToCharIndex(quasi.span.start - positionCtx.spanOffset);\n      const quasiEnd = positionCtx.converter.byteOffsetToCharIndex(quasi.span.end - positionCtx.spanOffset);\n      if (contentStart === -1) contentStart = quasiStart;\n      contentEnd = quasiEnd;\n    }\n\n    parts.push(quasi.cooked ?? quasi.raw);\n    if (i < expressions.length) {\n      parts.push(`__FRAG_SPREAD_${i}__`);\n      if (positionCtx) {\n        // All SWC AST nodes have span; cast needed because Expression union type doesn't expose it uniformly\n        const expr = expressions[i] as unknown as { span: { start: number; end: number } };\n        const exprStart = positionCtx.converter.byteOffsetToCharIndex(expr.span.start - positionCtx.spanOffset);\n        const exprEnd = positionCtx.converter.byteOffsetToCharIndex(expr.span.end - positionCtx.spanOffset);\n        expressionRanges.push({ start: exprStart, end: exprEnd });\n      }\n    }\n  }\n  const content = parts.join(\"\");\n\n  const template: ExtractedTemplate = {\n    schemaName,\n    kind,\n    content,\n    ...(elementName !== undefined ? { elementName } : {}),\n    ...(typeName !== undefined ? { typeName } : {}),\n    ...(typeNameSpan !== undefined ? { typeNameSpan } : {}),\n    ...(positionCtx && contentStart !== -1 && contentEnd !== -1\n      ? { contentRange: { start: contentStart, end: contentEnd } }\n      : {}),\n    ...(expressionRanges.length > 0 ? { expressionRanges } : {}),\n  };\n\n  templates.push(template);\n};\n\n/**\n * Find the innermost gql call, unwrapping method chains like .attach().\n */\nexport const findGqlCall = (identifiers: ReadonlySet<string>, node: Node): CallExpression | null => {\n  if (!node || node.type !== \"CallExpression\") {\n    return null;\n  }\n\n  const call = node as unknown as CallExpression;\n  if (getGqlCallSchemaName(identifiers, call) !== null) {\n    return call;\n  }\n\n  const callee = call.callee;\n  if (callee.type !== \"MemberExpression\") {\n    return null;\n  }\n\n  return findGqlCall(identifiers, callee.object as unknown as Node);\n};\n\n/**\n * Walk AST to find gql calls and extract templates.\n */\nexport function walkAndExtract(\n  node: Node,\n  identifiers: ReadonlySet<string>,\n  positionCtx: PositionTrackingContext,\n): ExtractedTemplateWithPosition[];\nexport function walkAndExtract(\n  node: Node,\n  identifiers: ReadonlySet<string>,\n  positionCtx?: PositionTrackingContext,\n): ExtractedTemplate[];\nexport function walkAndExtract(\n  node: Node,\n  identifiers: ReadonlySet<string>,\n  positionCtx?: PositionTrackingContext,\n): ExtractedTemplate[] {\n  const templates: ExtractedTemplate[] = [];\n\n  const visit = (n: Node | ReadonlyArray<Node> | Record<string, unknown>): void => {\n    if (!n || typeof n !== \"object\") {\n      return;\n    }\n\n    if (\"type\" in n && n.type === \"CallExpression\") {\n      const gqlCall = findGqlCall(identifiers, n as Node);\n      if (gqlCall) {\n        const schemaName = getGqlCallSchemaName(identifiers, gqlCall);\n        if (schemaName) {\n          const arrow = gqlCall.arguments[0]?.expression as ArrowFunctionExpression;\n          templates.push(...extractTemplatesFromCallback(arrow, schemaName, positionCtx));\n        }\n        return; // Don't recurse into gql calls\n      }\n    }\n\n    // Recurse into all array and object properties\n    if (Array.isArray(n)) {\n      for (const item of n) {\n        visit(item as Node);\n      }\n      return;\n    }\n\n    for (const key of Object.keys(n)) {\n      if (key === \"span\" || key === \"type\") {\n        continue;\n      }\n      const value = (n as Record<string, unknown>)[key];\n      if (value && typeof value === \"object\") {\n        visit(value as Node);\n      }\n    }\n  };\n\n  visit(node);\n  return templates;\n}\n\n/**\n * Walk AST to find gql callback builder calls and extract field call trees.\n * Companion to walkAndExtract — collects ExtractedFieldTree instead of ExtractedTemplate.\n */\nexport const walkAndExtractFieldTrees = (\n  node: Node,\n  identifiers: ReadonlySet<string>,\n  positionCtx?: PositionTrackingContext,\n): ExtractedFieldTree[] => {\n  const trees: ExtractedFieldTree[] = [];\n\n  const visit = (n: Node | ReadonlyArray<Node> | Record<string, unknown>): void => {\n    if (!n || typeof n !== \"object\") return;\n\n    if (\"type\" in n && n.type === \"CallExpression\") {\n      const gqlCall = findGqlCall(identifiers, n as Node);\n      if (gqlCall) {\n        const schemaName = getGqlCallSchemaName(identifiers, gqlCall);\n        if (schemaName) {\n          const arrow = gqlCall.arguments[0]?.expression as ArrowFunctionExpression;\n          // Process each expression in the arrow body for field trees\n          const processExpr = (expr: Node): void => {\n            if (expr.type === \"CallExpression\") {\n              const tree = extractFieldCallTree(expr, schemaName, positionCtx);\n              if (tree) trees.push(tree);\n            }\n          };\n          if (arrow.body.type !== \"BlockStatement\") {\n            processExpr(arrow.body as Node);\n          } else {\n            for (const stmt of arrow.body.stmts) {\n              if (stmt.type === \"ReturnStatement\" && stmt.argument) {\n                processExpr(stmt.argument as Node);\n              }\n            }\n          }\n        }\n        return;\n      }\n    }\n\n    if (Array.isArray(n)) {\n      for (const item of n) visit(item as Node);\n      return;\n    }\n\n    for (const key of Object.keys(n)) {\n      if (key === \"span\" || key === \"type\") continue;\n      const value = (n as Record<string, unknown>)[key];\n      if (value && typeof value === \"object\") visit(value as Node);\n    }\n  };\n\n  visit(node);\n  return trees;\n};\n\n/**\n * Convert a byte-space span to a character-index span using a position context.\n * Used for tracking field name and call positions within a callback builder.\n */\nconst convertSpan = (\n  span: { start: number; end: number },\n  positionCtx: PositionTrackingContext,\n): { start: number; end: number } => ({\n  start: positionCtx.converter.byteOffsetToCharIndex(span.start - positionCtx.spanOffset),\n  end: positionCtx.converter.byteOffsetToCharIndex(span.end - positionCtx.spanOffset),\n});\n\n/**\n * Walk an arrow function body to extract FieldCallNode children.\n * The arrow body should return an ObjectExpression where each property\n * is a SpreadElement wrapping an outer CallExpression:\n *   `({ f }) => ({ ...f(\"fieldName\")(...) })`\n */\nconst extractFieldCallChildren = (\n  arrow: ArrowFunctionExpression,\n  positionCtx?: PositionTrackingContext,\n): readonly FieldCallNode[] => {\n  // Unwrap the body to get the ObjectExpression\n  let bodyExpr: { type: string } | undefined;\n\n  if (arrow.body.type === \"BlockStatement\") {\n    for (const stmt of (arrow.body as { stmts: { type: string; argument?: { type: string } }[] }).stmts) {\n      if (stmt.type === \"ReturnStatement\" && stmt.argument) {\n        bodyExpr = stmt.argument as { type: string };\n        break;\n      }\n    }\n  } else {\n    bodyExpr = arrow.body as { type: string };\n  }\n\n  // Unwrap ParenthesisExpression wrapping ObjectExpression\n  if (bodyExpr?.type === \"ParenthesisExpression\") {\n    bodyExpr = (bodyExpr as unknown as { expression: { type: string } }).expression;\n  }\n\n  if (!bodyExpr || bodyExpr.type !== \"ObjectExpression\") {\n    return [];\n  }\n\n  const objExpr = bodyExpr as unknown as ObjectExpression;\n  const children: FieldCallNode[] = [];\n\n  for (const prop of objExpr.properties) {\n    if (prop.type !== \"SpreadElement\") continue;\n\n    // SpreadElement.arguments is the spread expression: f(\"fieldName\")(...)\n    const outerCall = (prop as unknown as { arguments: { type: string } }).arguments;\n    if (!outerCall || outerCall.type !== \"CallExpression\") continue;\n\n    const outer = outerCall as unknown as CallExpression;\n\n    // The callee of the outer call should itself be a CallExpression: f(\"fieldName\")\n    if (outer.callee.type !== \"CallExpression\") continue;\n    const innerCall = outer.callee as CallExpression;\n\n    // innerCall.callee should be Identifier (the \"f\" function)\n    if (innerCall.callee.type !== \"Identifier\") continue;\n\n    // innerCall.arguments[0] should be a StringLiteral — the field name\n    const fieldNameArg = innerCall.arguments[0]?.expression;\n    if (!fieldNameArg || fieldNameArg.type !== \"StringLiteral\") continue;\n\n    const strLit = fieldNameArg as unknown as { value: string; span: { start: number; end: number } };\n    const fieldName = strLit.value;\n\n    // Compute spans\n    const outerCallSpan = (outer as unknown as { span: { start: number; end: number } }).span;\n    const strLitSpan = strLit.span;\n\n    // callSpan covers the full outer expression; fieldNameSpan is inside quotes (adjust by +1/-1 for ASCII quote)\n    const callSpan = positionCtx\n      ? convertSpan(outerCallSpan, positionCtx)\n      : { start: outerCallSpan.start, end: outerCallSpan.end };\n    const fieldNameSpan = positionCtx\n      ? {\n          start: positionCtx.converter.byteOffsetToCharIndex(strLitSpan.start + 1 - positionCtx.spanOffset),\n          end: positionCtx.converter.byteOffsetToCharIndex(strLitSpan.end - 1 - positionCtx.spanOffset),\n        }\n      : { start: strLitSpan.start + 1, end: strLitSpan.end - 1 };\n\n    // Discriminate nested kind based on outer call arguments\n    const nested = extractFieldCallNested(outer, positionCtx);\n\n    children.push({ fieldName, fieldNameSpan, callSpan, nested });\n  }\n\n  return children;\n};\n\n/**\n * Extract the nested structure from an outer field call.\n * The outer call is: f(\"fieldName\")(arg) where arg determines nesting.\n */\nconst extractFieldCallNested = (outer: CallExpression, positionCtx?: PositionTrackingContext): FieldCallNested | null => {\n  const outerArg = outer.arguments[0]?.expression;\n\n  // No argument or absent argument → scalar field\n  if (!outerArg) return null;\n\n  // Arrow function argument → object field (recurse into nested callback body)\n  if (outerArg.type === \"ArrowFunctionExpression\") {\n    const nestedArrow = outerArg as unknown as ArrowFunctionExpression;\n    const argSpan = (outerArg as unknown as { span: { start: number; end: number } }).span;\n    const span = positionCtx ? convertSpan(argSpan, positionCtx) : { start: argSpan.start, end: argSpan.end };\n    const children = extractFieldCallChildren(nestedArrow, positionCtx);\n    return { kind: \"object\", span, children };\n  }\n\n  // Object argument → union field\n  if (outerArg.type === \"ObjectExpression\") {\n    const unionObj = outerArg as unknown as ObjectExpression;\n    const argSpan = (outerArg as unknown as { span: { start: number; end: number } }).span;\n    const span = positionCtx ? convertSpan(argSpan, positionCtx) : { start: argSpan.start, end: argSpan.end };\n    const branches: UnionBranchNode[] = [];\n\n    for (const prop of unionObj.properties) {\n      if (prop.type !== \"KeyValueProperty\") continue;\n\n      const kvProp = prop as unknown as {\n        key: { type: string; value: string; span: { start: number; end: number } };\n        value: { type: string; span: { start: number; end: number } };\n      };\n\n      // Skip __typename: true (BooleanLiteral value)\n      if (kvProp.key.value === \"__typename\" && kvProp.value.type === \"BooleanLiteral\") continue;\n\n      // Key must be Identifier (type name)\n      if (kvProp.key.type !== \"Identifier\") continue;\n\n      // Value must be ArrowFunctionExpression\n      if (kvProp.value.type !== \"ArrowFunctionExpression\") continue;\n\n      const typeName = kvProp.key.value;\n      const typeNameSpan = positionCtx\n        ? convertSpan(kvProp.key.span, positionCtx)\n        : { start: kvProp.key.span.start, end: kvProp.key.span.end };\n      const branchSpan = positionCtx\n        ? convertSpan(kvProp.value.span, positionCtx)\n        : { start: kvProp.value.span.start, end: kvProp.value.span.end };\n\n      const branchArrow = kvProp.value as unknown as ArrowFunctionExpression;\n      const children = extractFieldCallChildren(branchArrow, positionCtx);\n\n      branches.push({ typeName, typeNameSpan, branchSpan, children });\n    }\n\n    return { kind: \"union\", span, branches };\n  }\n\n  return null;\n};\n\n/**\n * Extract a field call tree from a callback builder expression.\n *\n * Expects a top-level expression of the callback builder pattern:\n *   `query(\"Name\")({ fields: ({ f }) => ({ ...f(\"id\")(), ...f(\"name\")() }) })({})`\n *\n * Returns an `ExtractedFieldTree` describing the root children (fields on the root selection set),\n * or `null` if the expression is not a callback builder or has no `fields` property.\n *\n * The `positionCtx` is optional — when provided, all span values will be character offsets\n * in the original TypeScript source. When omitted, spans are raw SWC byte positions.\n */\nexport const extractFieldCallTree = (\n  expr: Node,\n  schemaName: string,\n  positionCtx?: PositionTrackingContext,\n): ExtractedFieldTree | null => {\n  const result = findCallbackBuilderCalls(expr);\n  if (!result) return null;\n\n  const { curriedCall, configCall } = result;\n\n  // Extract kind and elementName from the curried call: query(\"Name\")\n  const kind = (curriedCall.callee as { value: string }).value as OperationKind;\n  const nameArg = curriedCall.arguments[0]?.expression;\n  const elementName = nameArg?.type === \"StringLiteral\" ? (nameArg as { value: string }).value : undefined;\n\n  // Find the `fields` property in the config object\n  const configObj = configCall.arguments[0]?.expression as ObjectExpression;\n  for (const prop of configObj.properties) {\n    if (prop.type !== \"KeyValueProperty\") continue;\n\n    const kvProp = prop as unknown as {\n      key: { type: string; value: string };\n      value: { type: string; span: { start: number; end: number } };\n    };\n    if (kvProp.key.type !== \"Identifier\" || kvProp.key.value !== \"fields\") continue;\n    if (kvProp.value.type !== \"ArrowFunctionExpression\") continue;\n\n    const fieldsArrow = kvProp.value as unknown as ArrowFunctionExpression;\n    const fieldsSpan = kvProp.value.span;\n    const rootSpan = positionCtx ? convertSpan(fieldsSpan, positionCtx) : { start: fieldsSpan.start, end: fieldsSpan.end };\n\n    const children = extractFieldCallChildren(fieldsArrow, positionCtx);\n\n    return {\n      schemaName,\n      kind,\n      ...(elementName !== undefined ? { elementName } : {}),\n      rootSpan,\n      children,\n    };\n  }\n\n  return null;\n};\n","/**\n * GraphQL template formatting utilities.\n *\n * Pure string operations — no dependency on `graphql` package.\n * Consumers provide their own format function (e.g., graphql-js parse/print).\n *\n * @module\n */\n\nimport type { ExtractedTemplate, TemplateFormatEdit } from \"./types\";\n\n/** A function that formats GraphQL source text. */\nexport type FormatGraphqlFn = (source: string) => string;\n\n/**\n * Detect the base indentation for a template by looking at the line\n * containing the opening backtick.\n */\nexport const detectBaseIndent = (tsSource: string, contentStartOffset: number): string => {\n  // Find the start of the line containing contentStartOffset\n  let lineStart = contentStartOffset;\n  while (lineStart > 0 && tsSource.charCodeAt(lineStart - 1) !== 10) {\n    lineStart--;\n  }\n\n  // Extract leading whitespace from that line\n  let i = lineStart;\n  while (i < tsSource.length && (tsSource.charCodeAt(i) === 32 || tsSource.charCodeAt(i) === 9)) {\n    i++;\n  }\n\n  return tsSource.slice(lineStart, i);\n};\n\n/**\n * Convert graphql-js 2-space indentation to the target indent unit.\n * Strips leading 2-space groups and replaces with equivalent indent units.\n */\nconst convertGraphqlIndent = (line: string, indentUnit: string): string => {\n  if (indentUnit === \"  \") return line; // No conversion needed\n  let level = 0;\n  let pos = 0;\n  while (pos + 1 < line.length && line[pos] === \" \" && line[pos + 1] === \" \") {\n    level++;\n    pos += 2;\n  }\n  if (level === 0) return line;\n  return indentUnit.repeat(level) + line.slice(pos);\n};\n\n/**\n * Re-indent formatted GraphQL to match the embedding context.\n *\n * **Inline templates** (content does NOT start with `\\n`):\n * - Line 0 (`{`): no prefix — appears right after backtick\n * - Lines 1..N: graphql-js indentation only (converted to target unit)\n *\n * **Block templates** (content starts with `\\n`):\n * - All lines: `baseIndent + indentUnit` prefix + converted graphql indent\n * - Trailing: `\\n` + `baseIndent`\n */\nexport const reindent = (formatted: string, baseIndent: string, originalContent: string, indentUnit: string = \"  \"): string => {\n  const trimmedFormatted = formatted.trim();\n\n  // If original was single-line and formatted is also single-line, keep it\n  if (!originalContent.includes(\"\\n\") && !trimmedFormatted.includes(\"\\n\")) {\n    return trimmedFormatted;\n  }\n\n  const lines = trimmedFormatted.split(\"\\n\");\n\n  // Match original leading/trailing newline pattern\n  const startsWithNewline = originalContent.startsWith(\"\\n\");\n  const endsWithNewline = /\\n\\s*$/.test(originalContent);\n\n  const indentedLines = lines.map((line, i) => {\n    if (line.trim() === \"\") return \"\";\n    const converted = convertGraphqlIndent(line, indentUnit);\n\n    if (!startsWithNewline) {\n      // Inline template: first line has no prefix (appears after backtick);\n      // body lines get baseIndent + converted graphql indent to align with TS context.\n      if (i === 0) return converted;\n      return baseIndent + converted;\n    }\n\n    // Block template: every line gets baseIndent + indentUnit prefix\n    return `${baseIndent}${indentUnit}${converted}`;\n  });\n\n  let result = indentedLines.join(\"\\n\");\n  if (startsWithNewline) {\n    result = `\\n${result}`;\n  }\n  if (endsWithNewline) {\n    result = `${result}\\n${baseIndent}`;\n  }\n\n  return result;\n};\n\n/**\n * Detect the indentation unit used in a TypeScript source file.\n *\n * Uses the smallest indentation width found as the indent unit.\n * In files with embedded templates (e.g., graphql in backticks),\n * template content lines are at `baseIndent + graphqlIndent`,\n * so their absolute indent is always >= the file's indent unit.\n */\nexport const detectIndentUnit = (tsSource: string): string => {\n  let minSpaceIndent = Infinity;\n  for (const line of tsSource.split(\"\\n\")) {\n    if (line.length === 0 || line.trimStart().length === 0) continue;\n    if (line[0] === \"\\t\") return \"\\t\";\n    const match = line.match(/^( +)\\S/);\n    if (match) minSpaceIndent = Math.min(minSpaceIndent, match[1]!.length);\n  }\n  if (minSpaceIndent === Infinity || minSpaceIndent <= 1) return \"  \";\n  return \" \".repeat(minSpaceIndent);\n};\n\nconst GRAPHQL_KEYWORDS = new Set([\"query\", \"mutation\", \"subscription\", \"fragment\"]);\n\n/**\n * Reconstruct a full GraphQL document from template content + metadata.\n *\n * For curried syntax, the template `content` is only the body (e.g., `{ user { id } }`).\n * GraphQL parsers need a full document (e.g., `query GetUser { user { id } }`).\n *\n * For bare-tag syntax, the content already starts with a keyword and is a full document.\n *\n * @returns The wrapped source and a regex pattern to strip the synthetic prefix after formatting\n */\nexport const buildGraphqlWrapper = (template: ExtractedTemplate): { wrapped: string; prefixPattern: RegExp | null } => {\n  const content = template.content.trimStart();\n  const firstWord = content.split(/[\\s({]/)[0] ?? \"\";\n\n  // If content already starts with a GraphQL keyword, it's a full document (bare-tag)\n  if (GRAPHQL_KEYWORDS.has(firstWord)) {\n    return { wrapped: template.content, prefixPattern: null };\n  }\n\n  // Curried syntax — reconstruct the header\n  if (template.elementName) {\n    if (template.kind === \"fragment\" && template.typeName) {\n      const prefix = `fragment ${template.elementName} on ${template.typeName} `;\n      const prefixPattern = new RegExp(`^fragment\\\\s+${template.elementName}\\\\s+on\\\\s+${template.typeName}\\\\s*`);\n      return { wrapped: prefix + template.content, prefixPattern };\n    }\n    const prefix = `${template.kind} ${template.elementName} `;\n    const prefixPattern = new RegExp(`^${template.kind}\\\\s+${template.elementName}\\\\s*`);\n    return { wrapped: prefix + template.content, prefixPattern };\n  }\n\n  // No elementName — try wrapping with just the kind\n  const prefix = `${template.kind} `;\n  const prefixPattern = new RegExp(`^${template.kind}\\\\s*`);\n  return { wrapped: prefix + template.content, prefixPattern };\n};\n\n/**\n * Strip the reconstructed prefix from formatted output to get back the template body.\n * Uses regex pattern matching to handle whitespace normalization by the formatter\n * (e.g., `query Foo ($id: ID!)` → `query Foo($id: ID!)`).\n */\nexport const unwrapFormattedContent = (formatted: string, prefixPattern: RegExp | null): string => {\n  if (!prefixPattern) return formatted;\n  const match = formatted.match(prefixPattern);\n  if (!match) return formatted;\n  return formatted.slice(match[0].length);\n};\n\n/**\n * Format GraphQL templates within TypeScript source.\n *\n * Applies the given format function to each template's content, handles\n * wrapper reconstruction for curried syntax, and re-indents the result\n * to match the TypeScript embedding context.\n *\n * @returns Array of edits to apply to the source (sorted by position, not yet applied)\n */\nexport const formatTemplatesInSource = (\n  templates: readonly ExtractedTemplate[],\n  tsSource: string,\n  formatGraphql: FormatGraphqlFn,\n): readonly TemplateFormatEdit[] => {\n  const indentUnit = detectIndentUnit(tsSource);\n  const edits: TemplateFormatEdit[] = [];\n\n  for (const template of templates) {\n    if (!template.contentRange) continue;\n    // Callback-variables contain only variable definitions (e.g., \"($id: ID!)\"),\n    // not valid standalone GraphQL — skip formatting.\n    if (template.source === \"callback-variables\") continue;\n\n    // Wrap the content for formatting\n    const { wrapped, prefixPattern } = buildGraphqlWrapper(template);\n\n    let formatted: string;\n    try {\n      formatted = formatGraphql(wrapped);\n    } catch {\n      continue;\n    }\n\n    // Unwrap the prefix\n    let unwrapped = unwrapFormattedContent(formatted, prefixPattern);\n\n    // Restore interpolation expressions: replace __FRAG_SPREAD_N__ with original ${...} syntax\n    if (template.expressionRanges && template.expressionRanges.length > 0) {\n      for (const [i, range] of template.expressionRanges.entries()) {\n        const exprText = tsSource.slice(range.start, range.end);\n        unwrapped = unwrapped.replace(`__FRAG_SPREAD_${i}__`, `\\${${exprText}}`);\n      }\n    }\n\n    // Fast path: skip if formatter produces identical output\n    if (unwrapped === template.content) {\n      continue;\n    }\n\n    // Detect base indentation from the TS source\n    const baseIndent = detectBaseIndent(tsSource, template.contentRange.start);\n\n    // Re-indent the formatted output\n    const reindented = reindent(unwrapped, baseIndent, template.content, indentUnit);\n\n    // Skip if no changes after re-indentation\n    if (reindented === template.content) {\n      continue;\n    }\n\n    edits.push({\n      start: template.contentRange.start,\n      end: template.contentRange.end,\n      newText: reindented,\n    });\n  }\n\n  return edits;\n};\n"],"mappings":"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"}