{"version":3,"file":"transform.cjs","sources":["../../../src/transform/transform.ts"],"sourcesContent":["import { parseAst } from '@tanstack/router-utils'\nimport { parse, print, types, visit } from 'recast'\nimport { SourceMapConsumer } from 'source-map'\nimport { mergeImportDeclarations } from '../utils'\nimport { ensureStringArgument } from './utils'\nimport type { ImportDeclaration } from '../types'\nimport type { RawSourceMap } from 'source-map'\nimport type { TransformOptions, TransformResult } from './types'\n\nconst b = types.builders\n\nexport async function transform({\n  ctx,\n  source,\n  node,\n}: TransformOptions): Promise<TransformResult> {\n  let appliedChanges = false as boolean\n  let ast: types.namedTypes.File\n  try {\n    ast = parse(source, {\n      sourceFileName: 'output.ts',\n      parser: {\n        parse(code: string) {\n          return parseAst({\n            code,\n            // we need to instruct babel to produce tokens,\n            // otherwise recast will try to generate the tokens via its own parser and will fail\n            tokens: true,\n          })\n        },\n      },\n    })\n  } catch (e) {\n    console.error('Error parsing code', ctx.routeId, source, e)\n    return {\n      result: 'error',\n      error: e,\n    }\n  }\n\n  const preferredQuote = detectPreferredQuoteStyle(ast)\n\n  let routeExportHandled = false as boolean\n  function onExportFound(decl: types.namedTypes.VariableDeclarator) {\n    if (decl.init?.type === 'CallExpression') {\n      const callExpression = decl.init\n      const firstArgument = callExpression.arguments[0]\n      if (firstArgument) {\n        if (firstArgument.type === 'ObjectExpression') {\n          const staticProperties = firstArgument.properties.flatMap((p) => {\n            if (p.type === 'ObjectProperty' && p.key.type === 'Identifier') {\n              return p.key.name\n            }\n            return []\n          })\n          node.createFileRouteProps = new Set(staticProperties)\n        }\n      }\n      let identifier: types.namedTypes.Identifier | undefined\n      // `const Route = createFileRoute({ ... })`\n      if (callExpression.callee.type === 'Identifier') {\n        identifier = callExpression.callee\n        if (ctx.verboseFileRoutes) {\n          // we need to add the string literal via another CallExpression\n          callExpression.callee = b.callExpression(identifier, [\n            b.stringLiteral(ctx.routeId),\n          ])\n          appliedChanges = true\n        }\n      }\n      // `const Route = createFileRoute('/path')({ ... })`\n      else if (\n        callExpression.callee.type === 'CallExpression' &&\n        callExpression.callee.callee.type === 'Identifier'\n      ) {\n        identifier = callExpression.callee.callee\n        if (!ctx.verboseFileRoutes) {\n          // we need to remove the route id\n          callExpression.callee = identifier\n          appliedChanges = true\n        } else {\n          // check if the route id is correct\n          appliedChanges = ensureStringArgument(\n            callExpression.callee,\n            ctx.routeId,\n            ctx.preferredQuote,\n          )\n        }\n      }\n      if (identifier === undefined) {\n        throw new Error(\n          `expected identifier to be present in ${ctx.routeId} for export \"Route\"`,\n        )\n      }\n      if (identifier.name === 'createFileRoute' && ctx.lazy) {\n        identifier.name = 'createLazyFileRoute'\n        appliedChanges = true\n      } else if (identifier.name === 'createLazyFileRoute' && !ctx.lazy) {\n        identifier.name = 'createFileRoute'\n        appliedChanges = true\n      }\n    } else {\n      throw new Error(\n        `expected \"Route\" export to be initialized by a CallExpression`,\n      )\n    }\n    routeExportHandled = true\n  }\n\n  const program: types.namedTypes.Program = ast.program\n  // first pass: find Route export\n  for (const n of program.body) {\n    if (n.type === 'ExportNamedDeclaration') {\n      // direct export of a variable declaration, e.g. `export const Route = createFileRoute('/path')`\n      if (n.declaration?.type === 'VariableDeclaration') {\n        const decl = n.declaration.declarations[0]\n        if (\n          decl &&\n          decl.type === 'VariableDeclarator' &&\n          decl.id.type === 'Identifier'\n        ) {\n          if (decl.id.name === 'Route') {\n            onExportFound(decl)\n          }\n        }\n      }\n      // this is an export without a declaration, e.g. `export { Route }`\n      else if (n.declaration === null && n.specifiers) {\n        for (const spec of n.specifiers) {\n          if (typeof spec.exported.name === 'string') {\n            if (spec.exported.name === 'Route') {\n              const variableName = spec.local?.name || spec.exported.name\n              // find the matching variable declaration by iterating over the top-level declarations\n              for (const decl of program.body) {\n                if (\n                  decl.type === 'VariableDeclaration' &&\n                  decl.declarations[0]\n                ) {\n                  const variable = decl.declarations[0]\n                  if (\n                    variable.type === 'VariableDeclarator' &&\n                    variable.id.type === 'Identifier' &&\n                    variable.id.name === variableName\n                  ) {\n                    onExportFound(variable)\n                    break\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n    if (routeExportHandled) {\n      break\n    }\n  }\n\n  if (!routeExportHandled) {\n    return {\n      result: 'no-route-export',\n    }\n  }\n\n  const imports: {\n    required: Array<ImportDeclaration>\n    banned: Array<ImportDeclaration>\n  } = {\n    required: [],\n    banned: [],\n  }\n\n  const targetModule = `@tanstack/${ctx.target}-router`\n  if (ctx.verboseFileRoutes === false) {\n    imports.banned = [\n      {\n        source: targetModule,\n        specifiers: [\n          { imported: 'createLazyFileRoute' },\n          { imported: 'createFileRoute' },\n        ],\n      },\n    ]\n  } else {\n    if (ctx.lazy) {\n      imports.required = [\n        {\n          source: targetModule,\n          specifiers: [{ imported: 'createLazyFileRoute' }],\n        },\n      ]\n      imports.banned = [\n        {\n          source: targetModule,\n          specifiers: [{ imported: 'createFileRoute' }],\n        },\n      ]\n    } else {\n      imports.required = [\n        {\n          source: targetModule,\n          specifiers: [{ imported: 'createFileRoute' }],\n        },\n      ]\n      imports.banned = [\n        {\n          source: targetModule,\n          specifiers: [{ imported: 'createLazyFileRoute' }],\n        },\n      ]\n    }\n  }\n\n  imports.required = mergeImportDeclarations(imports.required)\n  imports.banned = mergeImportDeclarations(imports.banned)\n\n  const importStatementCandidates: Array<types.namedTypes.ImportDeclaration> =\n    []\n  const importDeclarationsToRemove: Array<types.namedTypes.ImportDeclaration> =\n    []\n\n  // second pass: apply import rules, but only if a matching export for the plugin was found\n  for (const n of program.body) {\n    const findImport =\n      (opts: { source: string; importKind?: 'type' | 'value' | 'typeof' }) =>\n      (i: ImportDeclaration) => {\n        if (i.source === opts.source) {\n          const importKind = i.importKind || 'value'\n          const expectedImportKind = opts.importKind || 'value'\n          return expectedImportKind === importKind\n        }\n        return false\n      }\n    if (n.type === 'ImportDeclaration' && typeof n.source.value === 'string') {\n      const filterImport = findImport({\n        source: n.source.value,\n        importKind: n.importKind,\n      })\n      let requiredImports = imports.required.filter(filterImport)[0]\n\n      const bannedImports = imports.banned.filter(filterImport)[0]\n      if (!requiredImports && !bannedImports) {\n        continue\n      }\n      const importSpecifiersToRemove: types.namedTypes.ImportDeclaration['specifiers'] =\n        []\n      if (n.specifiers) {\n        for (const spec of n.specifiers) {\n          if (!requiredImports && !bannedImports) {\n            break\n          }\n          if (\n            spec.type === 'ImportSpecifier' &&\n            typeof spec.imported.name === 'string'\n          ) {\n            if (requiredImports) {\n              const requiredImportIndex = requiredImports.specifiers.findIndex(\n                (imp) => imp.imported === spec.imported.name,\n              )\n              if (requiredImportIndex !== -1) {\n                // import is already present, remove it from requiredImports\n                requiredImports.specifiers.splice(requiredImportIndex, 1)\n                if (requiredImports.specifiers.length === 0) {\n                  imports.required = imports.required.splice(\n                    imports.required.indexOf(requiredImports),\n                    1,\n                  )\n                  requiredImports = undefined\n                }\n              } else {\n                // add the import statement to the candidates\n                importStatementCandidates.push(n)\n              }\n            }\n            if (bannedImports) {\n              const bannedImportIndex = bannedImports.specifiers.findIndex(\n                (imp) => imp.imported === spec.imported.name,\n              )\n              if (bannedImportIndex !== -1) {\n                importSpecifiersToRemove.push(spec)\n              }\n            }\n          }\n        }\n        if (importSpecifiersToRemove.length > 0) {\n          appliedChanges = true\n          n.specifiers = n.specifiers.filter(\n            (spec) => !importSpecifiersToRemove.includes(spec),\n          )\n\n          // mark the import statement as to be deleted if it is now empty\n          if (n.specifiers.length === 0) {\n            importDeclarationsToRemove.push(n)\n          }\n        }\n      }\n    }\n  }\n  imports.required.forEach((requiredImport) => {\n    if (requiredImport.specifiers.length > 0) {\n      appliedChanges = true\n      if (importStatementCandidates.length > 0) {\n        // find the first import statement that matches both the module and the import kind\n        const importStatement = importStatementCandidates.find(\n          (importStatement) => {\n            if (importStatement.source.value === requiredImport.source) {\n              const importKind = importStatement.importKind || 'value'\n              const requiredImportKind = requiredImport.importKind || 'value'\n              return importKind === requiredImportKind\n            }\n            return false\n          },\n        )\n        if (importStatement) {\n          if (importStatement.specifiers === undefined) {\n            importStatement.specifiers = []\n          }\n          const importSpecifiersToAdd = requiredImport.specifiers.map((spec) =>\n            b.importSpecifier(\n              b.identifier(spec.imported),\n              b.identifier(spec.imported),\n            ),\n          )\n          importStatement.specifiers = [\n            ...importStatement.specifiers,\n            ...importSpecifiersToAdd,\n          ]\n          return\n        }\n      }\n      const importStatement = b.importDeclaration(\n        requiredImport.specifiers.map((spec) =>\n          b.importSpecifier(\n            b.identifier(spec.imported),\n            spec.local ? b.identifier(spec.local) : null,\n          ),\n        ),\n        b.stringLiteral(requiredImport.source),\n      )\n      program.body.unshift(importStatement)\n    }\n  })\n  if (importDeclarationsToRemove.length > 0) {\n    appliedChanges = true\n    for (const importDeclaration of importDeclarationsToRemove) {\n      // check if the import declaration is still empty\n      if (importDeclaration.specifiers?.length === 0) {\n        const index = program.body.indexOf(importDeclaration)\n        if (index !== -1) {\n          program.body.splice(index, 1)\n        }\n      }\n    }\n  }\n\n  if (!appliedChanges) {\n    return {\n      result: 'not-modified',\n    }\n  }\n\n  const printResult = print(ast, {\n    reuseWhitespace: true,\n    sourceMapName: 'output.map',\n  })\n  let transformedCode = printResult.code\n  if (printResult.map) {\n    const fixedOutput = await fixTransformedOutputText({\n      originalCode: source,\n      transformedCode,\n      sourceMap: printResult.map as RawSourceMap,\n      preferredQuote,\n    })\n    transformedCode = fixedOutput\n  }\n  return {\n    result: 'modified',\n    output: transformedCode,\n  }\n}\n\nasync function fixTransformedOutputText({\n  originalCode,\n  transformedCode,\n  sourceMap,\n  preferredQuote,\n}: {\n  originalCode: string\n  transformedCode: string\n  sourceMap: RawSourceMap\n  preferredQuote: '\"' | \"'\"\n}) {\n  const originalLines = originalCode.split('\\n')\n  const transformedLines = transformedCode.split('\\n')\n\n  const defaultUsesSemicolons = detectSemicolonUsage(originalCode)\n\n  const consumer = await new SourceMapConsumer(sourceMap)\n\n  const fixedLines = transformedLines.map((line, i) => {\n    const transformedLineNum = i + 1\n\n    let origLineText: string | undefined = undefined\n\n    for (let col = 0; col < line.length; col++) {\n      const mapped = consumer.originalPositionFor({\n        line: transformedLineNum,\n        column: col,\n      })\n      if (mapped.line != null && mapped.line > 0) {\n        origLineText = originalLines[mapped.line - 1]\n        break\n      }\n    }\n\n    if (origLineText !== undefined) {\n      if (origLineText === line) {\n        return origLineText\n      }\n      return fixLine(line, {\n        originalLine: origLineText,\n        useOriginalSemicolon: true,\n        useOriginalQuotes: true,\n        fallbackQuote: preferredQuote,\n      })\n    } else {\n      return fixLine(line, {\n        originalLine: null,\n        useOriginalSemicolon: false,\n        useOriginalQuotes: false,\n        fallbackQuote: preferredQuote,\n        fallbackSemicolon: defaultUsesSemicolons,\n      })\n    }\n  })\n\n  return fixedLines.join('\\n')\n}\n\nfunction fixLine(\n  line: string,\n  {\n    originalLine,\n    useOriginalSemicolon,\n    useOriginalQuotes,\n    fallbackQuote,\n    fallbackSemicolon = true,\n  }: {\n    originalLine: string | null\n    useOriginalSemicolon: boolean\n    useOriginalQuotes: boolean\n    fallbackQuote: string\n    fallbackSemicolon?: boolean\n  },\n) {\n  let result = line\n\n  if (useOriginalQuotes && originalLine) {\n    result = fixQuotes(result, originalLine, fallbackQuote)\n  } else if (!useOriginalQuotes && fallbackQuote) {\n    result = fixQuotesToPreferred(result, fallbackQuote)\n  }\n\n  if (useOriginalSemicolon && originalLine) {\n    const hadSemicolon = originalLine.trimEnd().endsWith(';')\n    const hasSemicolon = result.trimEnd().endsWith(';')\n    if (hadSemicolon && !hasSemicolon) result += ';'\n    if (!hadSemicolon && hasSemicolon) result = result.replace(/;\\s*$/, '')\n  } else if (!useOriginalSemicolon) {\n    const hasSemicolon = result.trimEnd().endsWith(';')\n    if (!fallbackSemicolon && hasSemicolon) result = result.replace(/;\\s*$/, '')\n    if (fallbackSemicolon && !hasSemicolon && result.trim()) result += ';'\n  }\n\n  return result\n}\n\nfunction fixQuotes(line: string, originalLine: string, fallbackQuote: string) {\n  let originalQuote = detectQuoteFromLine(originalLine)\n  if (!originalQuote) {\n    originalQuote = fallbackQuote\n  }\n  return fixQuotesToPreferred(line, originalQuote)\n}\n\nfunction fixQuotesToPreferred(line: string, quote: string) {\n  // Replace existing quotes with preferred quote\n  return line.replace(\n    /(['\"`])([^'\"`\\\\]*(?:\\\\.[^'\"`\\\\]*)*)\\1/g,\n    (_, q, content) => {\n      const escaped = content.replaceAll(quote, `\\\\${quote}`)\n      return `${quote}${escaped}${quote}`\n    },\n  )\n}\n\nfunction detectQuoteFromLine(line: string) {\n  const match = line.match(/(['\"`])(?:\\\\.|[^\\\\])*?\\1/)\n  return match ? match[1] : null\n}\n\nfunction detectSemicolonUsage(code: string) {\n  const lines = code.split('\\n').map((l) => l.trim())\n  const total = lines.length\n  const withSemis = lines.filter((l) => l.endsWith(';')).length\n  return withSemis > total / 2\n}\n\nexport function detectPreferredQuoteStyle(ast: types.ASTNode): \"'\" | '\"' {\n  let single = 0\n  let double = 0\n\n  visit(ast, {\n    visitStringLiteral(path) {\n      if (path.parent.node.type !== 'JSXAttribute') {\n        const raw = path.node.extra?.raw\n        if (raw?.startsWith(\"'\")) single++\n        else if (raw?.startsWith('\"')) double++\n      }\n      return false\n    },\n  })\n\n  if (single >= double) {\n    return \"'\"\n  }\n  return '\"'\n}\n"],"names":["types","parse","parseAst","ensureStringArgument","mergeImportDeclarations","importStatement","print","sourceMap","SourceMapConsumer","visit"],"mappings":"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"}