{"version":3,"sources":["../../../src/lib/typescript/runTypeCheck.ts"],"sourcesContent":["import path from 'path'\nimport { getFormattedDiagnostic } from './diagnosticFormatter'\nimport { getTypeScriptConfiguration } from './getTypeScriptConfiguration'\nimport { getRequiredConfiguration } from './writeConfigurationDefaults'\nimport { getDevTypesPath } from './type-paths'\n\nimport { CompileError } from '../compile-error'\nimport { warn } from '../../build/output/log'\n\nexport interface TypeCheckResult {\n  hasWarnings: boolean\n  warnings?: string[]\n  inputFilesCount: number\n  totalFilesCount: number\n  incremental: boolean\n}\n\nexport interface TypeCheckDirs {\n  app?: string\n  pages?: string\n}\n\nexport interface DebugBuildPaths {\n  app?: string[]\n  pages?: string[]\n}\n\n/**\n * Check if a file path matches any of the debug build paths.\n * Both filePath and debugPaths are resolved file paths from glob.\n */\nfunction fileMatchesDebugPaths(\n  filePath: string,\n  debugPaths: string[]\n): boolean {\n  return debugPaths.includes(filePath)\n}\n\nexport async function runTypeCheck(\n  typescript: typeof import('typescript'),\n  baseDir: string,\n  distDir: string,\n  tsConfigPath: string,\n  cacheDir?: string,\n  isAppDirEnabled?: boolean,\n  dirs?: TypeCheckDirs,\n  debugBuildPaths?: DebugBuildPaths\n): Promise<TypeCheckResult> {\n  const effectiveConfiguration = await getTypeScriptConfiguration(\n    typescript,\n    tsConfigPath\n  )\n\n  // tsconfig includes both .next/types and .next/dev/types to avoid config churn\n  // between dev/build modes. During build, we filter out .next/dev/types files to\n  // prevent stale dev types from causing errors when routes have been deleted since\n  // the last dev session.\n  let fileNames = effectiveConfiguration.fileNames\n\n  // Get the dev types path to filter (null if not applicable)\n  const devTypesDir = getDevTypesPath(baseDir, distDir)\n  if (devTypesDir) {\n    fileNames = fileNames.filter(\n      (fileName) => !fileName.startsWith(devTypesDir)\n    )\n  }\n\n  // Apply debug build paths filter if specified\n  if (dirs && debugBuildPaths) {\n    const { app: appDir, pages: pagesDir } = dirs\n    const { app: debugAppPaths, pages: debugPagePaths } = debugBuildPaths\n\n    fileNames = fileNames.filter((fileName) => {\n      // Check if file is in app directory\n      if (appDir && fileName.startsWith(appDir + path.sep)) {\n        // If debugAppPaths is undefined, include all app files\n        if (debugAppPaths === undefined) {\n          return true\n        }\n        // If debugAppPaths is empty array, exclude all app files\n        if (debugAppPaths.length === 0) {\n          return false\n        }\n        // Check if file matches any of the debug paths\n        const relativeToApp = fileName.slice(appDir.length)\n        return fileMatchesDebugPaths(relativeToApp, debugAppPaths)\n      }\n\n      // Check if file is in pages directory\n      if (pagesDir && fileName.startsWith(pagesDir + path.sep)) {\n        // If debugPagePaths is undefined, include all pages files\n        if (debugPagePaths === undefined) {\n          return true\n        }\n        // If debugPagePaths is empty array, exclude all pages files\n        if (debugPagePaths.length === 0) {\n          return false\n        }\n        // Check if file matches any of the debug paths\n        const relativeToPages = fileName.slice(pagesDir.length)\n        return fileMatchesDebugPaths(relativeToPages, debugPagePaths)\n      }\n\n      // Keep files outside app/pages directories (shared code, etc.)\n      return true\n    })\n  }\n\n  if (fileNames.length < 1) {\n    return {\n      hasWarnings: false,\n      inputFilesCount: 0,\n      totalFilesCount: 0,\n      incremental: false,\n    }\n  }\n  const requiredConfig = getRequiredConfiguration(typescript)\n\n  const options = {\n    ...requiredConfig,\n    ...effectiveConfiguration.options,\n    declarationMap: false,\n    emitDeclarationOnly: false,\n    noEmit: true,\n  }\n\n  let program:\n    | import('typescript').Program\n    | import('typescript').BuilderProgram\n  let incremental = false\n  if ((options.incremental || options.composite) && cacheDir) {\n    if (options.composite) {\n      warn(\n        'TypeScript project references are not fully supported. Attempting to build in incremental mode.'\n      )\n    }\n    incremental = true\n    program = typescript.createIncrementalProgram({\n      rootNames: fileNames,\n      options: {\n        ...options,\n        composite: false,\n        incremental: true,\n        tsBuildInfoFile: path.join(cacheDir, '.tsbuildinfo'),\n      },\n    })\n  } else {\n    program = typescript.createProgram(fileNames, options)\n  }\n\n  const result = program.emit()\n\n  const ignoreRegex = [\n    // matches **/__(tests|mocks)__/**\n    /[\\\\/]__(?:tests|mocks)__[\\\\/]/,\n    // matches **/*.(spec|test).*\n    /(?<=[\\\\/.])(?:spec|test)\\.[^\\\\/]+$/,\n  ]\n  const regexIgnoredFile = new RegExp(\n    ignoreRegex.map((r) => r.source).join('|')\n  )\n\n  const allDiagnostics = typescript\n    .getPreEmitDiagnostics(program as import('typescript').Program)\n    .concat(result.diagnostics)\n    .filter((d) => !(d.file && regexIgnoredFile.test(d.file.fileName)))\n\n  const firstError =\n    allDiagnostics.find(\n      (d) =>\n        d.category === typescript.DiagnosticCategory.Error && Boolean(d.file)\n    ) ??\n    allDiagnostics.find(\n      (d) => d.category === typescript.DiagnosticCategory.Error\n    )\n\n  // In test mode, we want to check all diagnostics, not just the first one.\n  if (process.env.__NEXT_TEST_MODE) {\n    if (firstError) {\n      const allErrors = allDiagnostics\n        .filter((d) => d.category === typescript.DiagnosticCategory.Error)\n        .map(\n          (d) =>\n            '[Test Mode] ' +\n            getFormattedDiagnostic(\n              typescript,\n              baseDir,\n              distDir,\n              d,\n              isAppDirEnabled\n            )\n        )\n\n      console.error(\n        '\\n\\n===== TS errors =====\\n\\n' +\n          allErrors.join('\\n\\n') +\n          '\\n\\n===== TS errors =====\\n\\n'\n      )\n\n      // Make sure all stdout is flushed before we exit.\n      await new Promise((resolve) => setTimeout(resolve, 100))\n    }\n  }\n\n  if (firstError) {\n    throw new CompileError(\n      getFormattedDiagnostic(\n        typescript,\n        baseDir,\n        distDir,\n        firstError,\n        isAppDirEnabled\n      )\n    )\n  }\n\n  const warnings = allDiagnostics\n    .filter((d) => d.category === typescript.DiagnosticCategory.Warning)\n    .map((d) =>\n      getFormattedDiagnostic(typescript, baseDir, distDir, d, isAppDirEnabled)\n    )\n\n  return {\n    hasWarnings: true,\n    warnings,\n    inputFilesCount: fileNames.length,\n    totalFilesCount: program.getSourceFiles().length,\n    incremental,\n  }\n}\n"],"names":["runTypeCheck","fileMatchesDebugPaths","filePath","debugPaths","includes","typescript","baseDir","distDir","tsConfigPath","cacheDir","isAppDirEnabled","dirs","debugBuildPaths","effectiveConfiguration","getTypeScriptConfiguration","fileNames","devTypesDir","getDevTypesPath","filter","fileName","startsWith","app","appDir","pages","pagesDir","debugAppPaths","debugPagePaths","path","sep","undefined","length","relativeToApp","slice","relativeToPages","hasWarnings","inputFilesCount","totalFilesCount","incremental","requiredConfig","getRequiredConfiguration","options","declarationMap","emitDeclarationOnly","noEmit","program","composite","warn","createIncrementalProgram","rootNames","tsBuildInfoFile","join","createProgram","result","emit","ignoreRegex","regexIgnoredFile","RegExp","map","r","source","allDiagnostics","getPreEmitDiagnostics","concat","diagnostics","d","file","test","firstError","find","category","DiagnosticCategory","Error","Boolean","process","env","__NEXT_TEST_MODE","allErrors","getFormattedDiagnostic","console","error","Promise","resolve","setTimeout","CompileError","warnings","Warning","getSourceFiles"],"mappings":"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","ignoreList":[0]}