{"version":3,"file":"formatter.mjs","names":["bodyObject: ObjectExpression | null","_graphqlModule: GraphqlModule | undefined","_graphqlModuleError: Error | undefined","initialContext: TraversalContext","module: Module","insertionPoints: InsertionPoint[]","positionCtx: PositionTrackingContext","defaultFormat: FormatGraphqlFn"],"sources":["../src/formatter/detection.ts","../src/formatter/format.ts"],"sourcesContent":["import type {\n  ArrowFunctionExpression,\n  CallExpression,\n  Expression,\n  Module,\n  ObjectExpression,\n  ObjectPatternProperty,\n} from \"@swc/types\";\n\n/**\n * Check if an expression is a reference to gql\n * Handles: gql, namespace.gql\n */\nexport const isGqlReference = (node: Expression, gqlIdentifiers: ReadonlySet<string>): boolean => {\n  // Unwrap TsNonNullExpression: gql! -> gql\n  const unwrapped = node.type === \"TsNonNullExpression\" ? (node as { type: string; expression: Expression }).expression : node;\n  if (unwrapped.type === \"Identifier\") {\n    return gqlIdentifiers.has(unwrapped.value);\n  }\n  if (unwrapped.type === \"MemberExpression\" && unwrapped.property.type === \"Identifier\" && unwrapped.property.value === \"gql\") {\n    return true;\n  }\n  return false;\n};\n\n/**\n * Check if a call expression is a gql definition call\n * Handles: gql.default(...), gql.model(...), gql.schemaName(...) (multi-schema)\n */\nexport const isGqlDefinitionCall = (node: CallExpression, gqlIdentifiers: ReadonlySet<string>): boolean => {\n  if (node.callee.type !== \"MemberExpression\") return false;\n  const { object } = node.callee;\n\n  // Check object is a gql reference first\n  if (!isGqlReference(object, gqlIdentifiers)) return false;\n\n  // Verify first argument is an arrow function (factory pattern)\n  // SWC's arguments are ExprOrSpread[], so access via .expression\n  const firstArg = node.arguments[0];\n  if (!firstArg || (firstArg.expression.type !== \"ArrowFunctionExpression\" && firstArg.expression.type !== \"FunctionExpression\"))\n    return false;\n\n  return true;\n};\n\n/**\n * Check if an object expression is a field selection object\n * Field selection objects are returned from arrow functions with ({ f }) or ({ f, $ }) parameter\n */\nexport const isFieldSelectionObject = (object: ObjectExpression, parent: ArrowFunctionExpression): boolean => {\n  // The object must be the body of the arrow function\n  // Handle both direct ObjectExpression and parenthesized ObjectExpression: `({ ... })`\n  let bodyObject: ObjectExpression | null = null;\n\n  if (parent.body.type === \"ObjectExpression\") {\n    bodyObject = parent.body;\n  } else if (parent.body.type === \"ParenthesisExpression\") {\n    // Handle `({ f }) => ({ ...f.id() })` pattern where body is parenthesized\n    const inner = parent.body.expression;\n    if (inner.type === \"ObjectExpression\") {\n      bodyObject = inner;\n    }\n  }\n\n  if (!bodyObject) return false;\n  if (bodyObject.span.start !== object.span.start) return false;\n\n  // Check if first parameter has 'f' destructured\n  const param = parent.params[0];\n  if (!param || param.type !== \"ObjectPattern\") return false;\n\n  return param.properties.some((p: ObjectPatternProperty) => {\n    if (p.type === \"KeyValuePatternProperty\" && p.key.type === \"Identifier\") {\n      return p.key.value === \"f\";\n    }\n    if (p.type === \"AssignmentPatternProperty\" && p.key.type === \"Identifier\") {\n      return p.key.value === \"f\";\n    }\n    return false;\n  });\n};\n\n/**\n * Collect gql identifiers from import declarations\n */\nexport const collectGqlIdentifiers = (module: Module): Set<string> => {\n  const gqlIdentifiers = new Set<string>();\n\n  for (const item of module.body) {\n    if (item.type !== \"ImportDeclaration\") continue;\n\n    for (const specifier of item.specifiers) {\n      if (specifier.type === \"ImportSpecifier\") {\n        const imported = specifier.imported?.value ?? specifier.local.value;\n        if (imported === \"gql\") {\n          gqlIdentifiers.add(specifier.local.value);\n        }\n      }\n      if (specifier.type === \"ImportDefaultSpecifier\") {\n        // Check if default import might be gql\n        if (specifier.local.value === \"gql\") {\n          gqlIdentifiers.add(specifier.local.value);\n        }\n      }\n      if (specifier.type === \"ImportNamespaceSpecifier\") {\n        // namespace import: import * as ns from \"...\"\n        // Would need ns.gql pattern - handled by isGqlReference\n      }\n    }\n  }\n\n  return gqlIdentifiers;\n};\n","import { createRequire } from \"node:module\";\nimport {\n  type FormatGraphqlFn,\n  formatTemplatesInSource,\n  type PositionTrackingContext,\n  walkAndExtract,\n} from \"@soda-gql/common/template-extraction\";\nimport { createSwcSpanConverter } from \"@soda-gql/common/utils\";\nimport { parseSync } from \"@swc/core\";\nimport type { ArrowFunctionExpression, CallExpression, Module, Node, ObjectExpression } from \"@swc/types\";\nimport { err, ok, type Result } from \"neverthrow\";\n\nconst require = createRequire(import.meta.url);\n\ntype GraphqlModule = {\n  parse: (source: string, options?: { noLocation?: boolean }) => unknown;\n  print: (ast: unknown) => string;\n};\n\nlet _graphqlModule: GraphqlModule | undefined;\nlet _graphqlModuleError: Error | undefined;\n\nconst getGraphqlModule = (): Result<GraphqlModule, FormatError> => {\n  if (_graphqlModuleError) {\n    return err({\n      type: \"FormatError\",\n      code: \"MISSING_DEPENDENCY\",\n      message: 'The \"graphql\" package is required for soda-gql formatter. Install it with: bun add graphql',\n    });\n  }\n  if (!_graphqlModule) {\n    try {\n      // eslint-disable-next-line @typescript-eslint/no-require-imports\n      _graphqlModule = require(\"graphql\") as GraphqlModule;\n    } catch (cause) {\n      _graphqlModuleError = cause instanceof Error ? cause : new Error(String(cause));\n      return err({\n        type: \"FormatError\",\n        code: \"MISSING_DEPENDENCY\",\n        message: 'The \"graphql\" package is required for soda-gql formatter. Install it with: bun add graphql',\n        cause,\n      });\n    }\n  }\n  return ok(_graphqlModule);\n};\n\nimport { collectGqlIdentifiers, isFieldSelectionObject, isGqlDefinitionCall } from \"./detection\";\nimport type { FormatError, FormatOptions, FormatResult } from \"./types\";\n\nconst NEWLINE_INSERTION = \"\\n\";\n\ntype InsertionPoint = {\n  readonly position: number;\n  readonly content: string;\n  readonly endPosition?: number;\n};\n\ntype TraversalContext = {\n  insideGqlDefinition: boolean;\n  currentArrowFunction: ArrowFunctionExpression | null;\n};\n\ntype TraversalCallback = (object: ObjectExpression, parent: ArrowFunctionExpression) => void;\n\n/**\n * Simple recursive AST traversal\n */\nconst traverseNode = (\n  node: Node,\n  context: TraversalContext,\n  gqlIdentifiers: ReadonlySet<string>,\n  onObjectExpression: TraversalCallback,\n): void => {\n  // Check for gql definition call entry\n  if (node.type === \"CallExpression\" && isGqlDefinitionCall(node as CallExpression, gqlIdentifiers)) {\n    context = { ...context, insideGqlDefinition: true };\n  }\n\n  // Handle object expressions - check if it's the body of the current arrow function\n  if (\n    node.type === \"ObjectExpression\" &&\n    context.insideGqlDefinition &&\n    context.currentArrowFunction &&\n    isFieldSelectionObject(node as ObjectExpression, context.currentArrowFunction)\n  ) {\n    onObjectExpression(node as ObjectExpression, context.currentArrowFunction);\n  }\n\n  // Recursively visit children\n  if (node.type === \"CallExpression\") {\n    const call = node as CallExpression;\n    traverseNode(call.callee as Node, context, gqlIdentifiers, onObjectExpression);\n    for (const arg of call.arguments) {\n      traverseNode(arg.expression as Node, context, gqlIdentifiers, onObjectExpression);\n    }\n  } else if (node.type === \"ArrowFunctionExpression\") {\n    const arrow = node as ArrowFunctionExpression;\n    // Update context with the new arrow function\n    const childContext = { ...context, currentArrowFunction: arrow };\n    if (arrow.body.type !== \"BlockStatement\") {\n      traverseNode(arrow.body as Node, childContext, gqlIdentifiers, onObjectExpression);\n    }\n  } else if (node.type === \"ParenthesisExpression\") {\n    // Handle parenthesized expressions like `({ ...f.id() })`\n    // biome-ignore lint/suspicious/noExplicitAny: SWC types\n    const paren = node as any;\n    if (paren.expression) {\n      traverseNode(paren.expression as Node, context, gqlIdentifiers, onObjectExpression);\n    }\n  } else if (node.type === \"MemberExpression\") {\n    // biome-ignore lint/suspicious/noExplicitAny: SWC types\n    const member = node as any;\n    traverseNode(member.object as Node, context, gqlIdentifiers, onObjectExpression);\n  } else if (node.type === \"ObjectExpression\") {\n    const obj = node as ObjectExpression;\n    for (const prop of obj.properties) {\n      if (prop.type === \"SpreadElement\") {\n        traverseNode(prop.arguments as Node, context, gqlIdentifiers, onObjectExpression);\n      } else if (prop.type === \"KeyValueProperty\") {\n        traverseNode(prop.value as Node, context, gqlIdentifiers, onObjectExpression);\n      }\n    }\n  } else {\n    // Generic traversal for other node types\n    for (const value of Object.values(node)) {\n      if (Array.isArray(value)) {\n        for (const child of value) {\n          if (child && typeof child === \"object\" && \"type\" in child) {\n            traverseNode(child as Node, context, gqlIdentifiers, onObjectExpression);\n          }\n        }\n      } else if (value && typeof value === \"object\" && \"type\" in value) {\n        traverseNode(value as Node, context, gqlIdentifiers, onObjectExpression);\n      }\n    }\n  }\n};\n\nconst traverse = (module: Module, gqlIdentifiers: ReadonlySet<string>, onObjectExpression: TraversalCallback): void => {\n  const initialContext: TraversalContext = {\n    insideGqlDefinition: false,\n    currentArrowFunction: null,\n  };\n  for (const statement of module.body) {\n    traverseNode(statement, initialContext, gqlIdentifiers, onObjectExpression);\n  }\n};\n\n/**\n * Format soda-gql field selection objects by inserting newlines.\n */\nexport const format = (options: FormatOptions): Result<FormatResult, FormatError> => {\n  const { sourceCode, filePath } = options;\n\n  // Parse source code with SWC\n  let module: Module;\n  try {\n    const program = parseSync(sourceCode, {\n      syntax: \"typescript\",\n      tsx: filePath?.endsWith(\".tsx\") ?? true,\n      target: \"es2022\",\n      decorators: false,\n      dynamicImport: true,\n    });\n\n    if (program.type !== \"Module\") {\n      return err({\n        type: \"FormatError\",\n        code: \"PARSE_ERROR\",\n        message: `Not a module${filePath ? ` (${filePath})` : \"\"}`,\n      });\n    }\n    module = program;\n  } catch (cause) {\n    return err({\n      type: \"FormatError\",\n      code: \"PARSE_ERROR\",\n      message: `Failed to parse source code${filePath ? ` (${filePath})` : \"\"}`,\n      cause,\n    });\n  }\n\n  // Calculate span offset for position normalization\n  // SWC's BytePos counter accumulates across parseSync calls within the same process\n  // Using module.span.start ensures correct position calculation regardless of accumulation\n  const spanOffset = module.span.start;\n\n  // SWC returns UTF-8 byte offsets; JS strings use UTF-16 code units.\n  // The converter handles this mapping (fast path for ASCII-only sources).\n  const converter = createSwcSpanConverter(sourceCode);\n\n  // Collect gql identifiers from imports\n  const gqlIdentifiers = collectGqlIdentifiers(module);\n  if (gqlIdentifiers.size === 0) {\n    return ok({ modified: false, sourceCode });\n  }\n\n  // Collect insertion points\n  const insertionPoints: InsertionPoint[] = [];\n\n  traverse(module, gqlIdentifiers, (object) => {\n    // Calculate actual position in source (byte offset → char index)\n    const objectStart = converter.byteOffsetToCharIndex(object.span.start - spanOffset);\n\n    // For field selection objects, insert newline if not present\n    const nextChar = sourceCode[objectStart + 1];\n    const hasNewline = nextChar === \"\\n\" || nextChar === \"\\r\";\n    if (!hasNewline) {\n      insertionPoints.push({\n        position: objectStart + 1,\n        content: NEWLINE_INSERTION,\n      });\n    }\n  });\n\n  // Tagged template formatting\n  const graphqlResult = getGraphqlModule();\n  if (graphqlResult.isErr()) {\n    return err(graphqlResult.error);\n  }\n  const { parse: parseGraphql, print: printGraphql } = graphqlResult.value;\n\n  const positionCtx: PositionTrackingContext = { spanOffset, converter };\n  const templates = walkAndExtract(module as unknown as Node, gqlIdentifiers, positionCtx);\n\n  if (templates.length > 0) {\n    const defaultFormat: FormatGraphqlFn = (source) => {\n      const ast = parseGraphql(source, { noLocation: false });\n      return printGraphql(ast);\n    };\n\n    const templateEdits = formatTemplatesInSource(templates, sourceCode, defaultFormat);\n\n    for (const edit of templateEdits) {\n      insertionPoints.push({\n        position: edit.start,\n        content: edit.newText,\n        endPosition: edit.end,\n      });\n    }\n  }\n\n  // Apply insertions\n  if (insertionPoints.length === 0) {\n    return ok({ modified: false, sourceCode });\n  }\n\n  // Sort in descending order to insert from end to beginning\n  // This preserves earlier positions while modifying later parts\n  const sortedPoints = [...insertionPoints].sort((a, b) => b.position - a.position);\n\n  let result = sourceCode;\n  for (const point of sortedPoints) {\n    const end = point.endPosition ?? point.position;\n    result = result.slice(0, point.position) + point.content + result.slice(end);\n  }\n\n  return ok({ modified: true, sourceCode: result });\n};\n\n/**\n * Check if a file needs formatting (has unformatted field selections).\n * Useful for pre-commit hooks or CI checks.\n */\nexport const needsFormat = (options: FormatOptions): Result<boolean, FormatError> => {\n  const { sourceCode, filePath } = options;\n\n  // Parse source code with SWC\n  let module: Module;\n  try {\n    const program = parseSync(sourceCode, {\n      syntax: \"typescript\",\n      tsx: filePath?.endsWith(\".tsx\") ?? true,\n      target: \"es2022\",\n      decorators: false,\n      dynamicImport: true,\n    });\n\n    if (program.type !== \"Module\") {\n      return err({\n        type: \"FormatError\",\n        code: \"PARSE_ERROR\",\n        message: `Not a module${filePath ? ` (${filePath})` : \"\"}`,\n      });\n    }\n    module = program;\n  } catch (cause) {\n    return err({\n      type: \"FormatError\",\n      code: \"PARSE_ERROR\",\n      message: `Failed to parse source code${filePath ? ` (${filePath})` : \"\"}`,\n      cause,\n    });\n  }\n\n  const spanOffset = module.span.start;\n  const converter = createSwcSpanConverter(sourceCode);\n  const gqlIdentifiers = collectGqlIdentifiers(module);\n\n  if (gqlIdentifiers.size === 0) {\n    return ok(false);\n  }\n\n  let needsFormatting = false;\n\n  traverse(module, gqlIdentifiers, (object) => {\n    if (needsFormatting) return; // Early exit\n\n    const objectStart = converter.byteOffsetToCharIndex(object.span.start - spanOffset);\n    const nextChar = sourceCode[objectStart + 1];\n    const hasNewline = nextChar === \"\\n\" || nextChar === \"\\r\";\n    if (!hasNewline) {\n      needsFormatting = true;\n    }\n  });\n\n  // Check tagged templates\n  if (!needsFormatting) {\n    const graphqlResult = getGraphqlModule();\n    if (graphqlResult.isErr()) {\n      return err(graphqlResult.error);\n    }\n    const { parse: parseGraphql, print: printGraphql } = graphqlResult.value;\n\n    const positionCtx: PositionTrackingContext = { spanOffset, converter };\n    const templates = walkAndExtract(module as unknown as Node, gqlIdentifiers, positionCtx);\n\n    if (templates.length > 0) {\n      const defaultFormat: FormatGraphqlFn = (source) => {\n        const ast = parseGraphql(source, { noLocation: false });\n        return printGraphql(ast);\n      };\n\n      const templateEdits = formatTemplatesInSource(templates, sourceCode, defaultFormat);\n      if (templateEdits.length > 0) {\n        needsFormatting = true;\n      }\n    }\n  }\n\n  return ok(needsFormatting);\n};\n"],"mappings":"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"}