{"version":3,"file":"cli.cjs","sources":["../src/util.ts","../src/cli.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'fs'\nimport objectHash from 'object-hash'\n\nexport const CURRENT_BASELINE_VERSION = 1\n\nexport interface ErrorSummary {\n  code: string\n  count: number\n  file: string\n  message?: string\n}\n\nexport interface SpecificError {\n  code: string\n  column: number\n  file: string\n  line: number\n  message: string\n}\n\nexport interface OldBaselineFile {\n  [hash: string]: ErrorSummary | SpecificError\n}\n\nexport interface BaselineFile {\n  meta: {\n    baselineFileVersion: number\n    ignoreMessages: boolean\n  }\n  // eslint-disable-next-line typescript-sort-keys/interface\n  errors: {\n    [hash: string]: ErrorSummary\n  }\n}\n\nexport type SpecificErrorsMap = Map<string, SpecificError[]>\nexport type ErrorSummaryMap = Map<string, ErrorSummary>\nexport type GitLabErrorFormat = {\n  check_name: string\n  description: string\n  fingerprint: string\n  location: {\n    lines: {\n      begin: number\n    }\n    path: string\n  }\n  severity: string\n}\n\nexport interface ParsingResult {\n  errorSummaryMap: ErrorSummaryMap\n  specificErrorsMap: SpecificErrorsMap\n}\n\nexport enum ErrorFormat {\n  GITLAB = 'gitlab',\n  HUMAN = 'human'\n}\n\ntype ErrorOptions = {\n  ignoreMessages: boolean\n}\n\n// Hash just the error summary, not the count so that we can easily\n// modify the count independently\nconst getErrorSummaryHash = (\n  errorSummary: ErrorSummary,\n  { ignoreMessages }: ErrorOptions\n) => {\n  const { code, file, message } = errorSummary\n  if (ignoreMessages) {\n    return objectHash({ code, file })\n  }\n  return objectHash({ code, file, message })\n}\n\nexport const parseTypeScriptErrors = (\n  errorLog: string,\n  { ignoreMessages }: ErrorOptions\n): ParsingResult => {\n  const errorPattern = /^(.+)\\((\\d+),(\\d+)\\): error (\\w+): (.+)$/\n\n  const lines = errorLog.split('\\n')\n  const specificErrorsMap: SpecificErrorsMap = new Map<\n    string,\n    SpecificError[]\n  >()\n  const errorSummaryMap: ErrorSummaryMap = new Map<string, ErrorSummary>()\n\n  const addSpecificErrorToMap = (\n    filePathName: string,\n    error: SpecificError\n  ) => {\n    const existingFile = specificErrorsMap.get(filePathName)\n    if (existingFile) {\n      existingFile.push(error)\n    } else {\n      specificErrorsMap.set(filePathName, [error])\n    }\n  }\n\n  const addErrorToSummary = (error: SpecificError) => {\n    const { file, code, message } = error\n    let errorSummary: ErrorSummary = {\n      file,\n      code,\n      count: 1\n    }\n    if (!ignoreMessages) {\n      errorSummary.message = message\n    }\n    const key = getErrorSummaryHash(errorSummary, { ignoreMessages })\n\n    const existingError = errorSummaryMap.get(key)\n    if (existingError) {\n      errorSummary = { ...existingError }\n      errorSummary.count += 1\n    }\n    errorSummaryMap.set(key, errorSummary)\n  }\n\n  for (const line of lines) {\n    const match = line.match(errorPattern)\n    if (match) {\n      const [, file, lineStr, columnStr, code, message] = match\n      const error: SpecificError = {\n        file,\n        code,\n        message,\n        line: parseInt(lineStr),\n        column: parseInt(columnStr)\n      }\n      addSpecificErrorToMap(error.file, error)\n      addErrorToSummary(error)\n    }\n  }\n\n  return { specificErrorsMap, errorSummaryMap }\n}\n\nexport const writeTypeScriptErrorsToFile = (\n  map: ErrorSummaryMap,\n  filepath: string,\n  errorOptions: ErrorOptions\n): void => {\n  const newBaselineFile: BaselineFile = {\n    meta: {\n      baselineFileVersion: CURRENT_BASELINE_VERSION,\n      ignoreMessages: errorOptions.ignoreMessages\n    },\n    errors: Object.fromEntries(map)\n  }\n  writeFileSync(filepath, JSON.stringify(newBaselineFile, null, 2))\n}\n\nexport const readBaselineErrorsFile = (\n  filepath: string\n): BaselineFile | OldBaselineFile => {\n  const text = readFileSync(filepath, {\n    encoding: 'utf-8'\n  })\n  return JSON.parse(text)\n}\n\nexport const getBaselineFileVersion = (\n  baselineFile: BaselineFile | OldBaselineFile\n) => {\n  if (\n    typeof baselineFile?.meta === 'object' &&\n    'baselineFileVersion' in baselineFile?.meta\n  ) {\n    return baselineFile?.meta?.baselineFileVersion\n  }\n  return 0\n}\n\nexport const isBaselineVersionCurrent = (\n  baselineFile: BaselineFile | OldBaselineFile\n): baselineFile is BaselineFile => {\n  return getBaselineFileVersion(baselineFile) === CURRENT_BASELINE_VERSION\n}\n\nexport const getErrorSummaryMap = (baselineFile: BaselineFile) => {\n  return new Map(Object.entries(baselineFile.errors))\n}\n\nexport const getNewErrors = (\n  oldErrors: ErrorSummaryMap,\n  newErrors: ErrorSummaryMap\n): ErrorSummaryMap => {\n  const result = new Map<string, ErrorSummary>()\n\n  for (const [id, error] of newErrors) {\n    if (!oldErrors.has(id)) {\n      result.set(id, error)\n    } else {\n      const oldErrCount = oldErrors.get(id)?.count ?? 0\n      const newErrCount = newErrors.get(id)?.count ?? 0\n      if (oldErrCount < newErrCount) {\n        const newErrors = { ...error, count: newErrCount - oldErrCount }\n        result.set(id, newErrors)\n      }\n    }\n  }\n\n  return result\n}\n\nexport const getTotalErrorsCount = (errorMap: ErrorSummaryMap): number =>\n  // NOTE: Previously, this was written with an array spread, but there was a bug\n  // with microbundle that was incorrectly compiling that (see: https://github.com/TimMikeladze/tsc-baseline/issues/21).\n  // Until that is resolved or the bundler is switched for this repo, this has been\n  // rewritten with Array.from\n  Array.from(errorMap.values()).reduce((sum, info) => sum + info.count, 0)\n\nexport const toHumanReadableText = (\n  errorSummaryMap: ErrorSummaryMap,\n  specificErrorMap: SpecificErrorsMap,\n  errorOptions: ErrorOptions,\n  isReportingUnmatchedErrors = false\n): string => {\n  let log = ''\n\n  for (const [key, error] of errorSummaryMap) {\n    const specificErrors = getSpecificErrorsMatchingSummary(\n      error,\n      specificErrorMap,\n      errorOptions\n    )\n\n    log += `File: ${error.file}\\n`\n    if (error.message) {\n      log += `Message: ${error.message}\\n`\n    }\n    log += `Code: ${error.code}\\n`\n    log += `Hash: ${key}\\n`\n\n    if (!isReportingUnmatchedErrors) {\n      log += `Count of new errors: ${error.count}\\n`\n      log += `${specificErrors.length} current error${\n        specificErrors.length === 1 ? '' : 's'\n      }:\\n`\n\n      log += specificErrors\n        .map(\n          (specificError) =>\n            `${specificError.file}(${specificError.line},${specificError.column})`\n        )\n        .join('\\n')\n    }\n\n    log += '\\n\\n'\n  }\n\n  return log.trim()\n}\n\nexport const getSpecificErrorsMatchingSummary = (\n  errorSummary: ErrorSummary,\n  specificErrorsMap: SpecificErrorsMap,\n  errorOptions: ErrorOptions\n): SpecificError[] => {\n  return (\n    specificErrorsMap\n      .get(errorSummary.file)\n      ?.filter(\n        (specificError) =>\n          specificError.file === errorSummary.file &&\n          (errorOptions.ignoreMessages\n            ? true\n            : specificError.message === errorSummary.message) &&\n          specificError.code === errorSummary.code\n      ) || []\n  )\n}\n\nexport const addHashToBaseline = (hash: string, filepath: string): void => {\n  const baselineErrorsFile = readBaselineErrorsFile(filepath)\n  if (!isBaselineVersionCurrent(baselineErrorsFile)) {\n    throw new Error(\n      'The .tsc-baseline.json is not current. Please make sure your packages are up to date and save a new baseline file'\n    )\n  }\n\n  const oldErrors = getErrorSummaryMap(baselineErrorsFile)\n  const newErrors = new Map<string, ErrorSummary>()\n\n  for (const [key, error] of oldErrors) {\n    newErrors.set(key, error)\n  }\n\n  newErrors.set(hash, {\n    code: '0000',\n    file: '0000',\n    message: '0000',\n    count: 1\n  })\n\n  writeTypeScriptErrorsToFile(newErrors, filepath, {\n    ignoreMessages: baselineErrorsFile.meta.ignoreMessages\n  })\n}\n\nexport const toGitLabOutputFormat = (\n  errorSummaryMap: ErrorSummaryMap,\n  specificErrorMap: SpecificErrorsMap,\n  errorOptions: ErrorOptions\n): string => {\n  const result: GitLabErrorFormat[] = []\n\n  for (const [key, error] of errorSummaryMap.entries()) {\n    const specificErrors: SpecificError[] = getSpecificErrorsMatchingSummary(\n      error,\n      specificErrorMap,\n      errorOptions\n    )\n\n    specificErrors.forEach((specificError: SpecificError, index: number) => {\n      result.push(<GitLabErrorFormat>{\n        description: specificError.message,\n        check_name: 'typescript-errors',\n        fingerprint: `${key}-${index}`,\n        severity: 'minor',\n        location: {\n          path: specificError.file,\n          lines: {\n            begin: specificError.line\n          }\n        }\n      })\n    })\n  }\n\n  return JSON.stringify(result, null, 2)\n}\n","#!/usr/bin/env node\n\nimport { Command, Option } from 'commander'\nimport {\n  addHashToBaseline,\n  getNewErrors,\n  parseTypeScriptErrors,\n  getTotalErrorsCount,\n  toHumanReadableText,\n  writeTypeScriptErrorsToFile,\n  readBaselineErrorsFile,\n  isBaselineVersionCurrent,\n  getErrorSummaryMap,\n  getBaselineFileVersion,\n  toGitLabOutputFormat,\n  CURRENT_BASELINE_VERSION,\n  ErrorFormat\n} from './util'\nimport { resolve } from 'path'\nimport { rmSync } from 'fs'\n;(async () => {\n  const program = new Command()\n\n  program\n    .name('tsc-baseline')\n    .description(\n      'Save a baseline of TypeScript errors and compare new errors against it.Useful for type-safe feature development in TypeScript projects that have a lot of errors. This tool will filter out errors that are already in the baseline and only show new errors.'\n    )\n\n  let stdin = ''\n\n  program.option(\n    '-p --path <path>',\n    `Path to file to save baseline errors to. Defaults to .tsc-baseline.json`\n  )\n\n  program.option(\n    '--ignoreMessages',\n    'Ignores specific type error messages and only counts errors by code.'\n  )\n\n  const getConfig = () => {\n    const config = program.opts()\n    return {\n      path: resolve(process.cwd(), config.path || '.tsc-baseline.json'),\n      ignoreMessages: config.ignoreMessages || false\n    }\n  }\n\n  program.command('save [message]').action((message) => {\n    if (stdin) {\n      message = stdin\n      if (message) {\n        const config = getConfig()\n        const errorOptions = {\n          ignoreMessages: config.ignoreMessages\n        }\n        writeTypeScriptErrorsToFile(\n          parseTypeScriptErrors(message, errorOptions).errorSummaryMap,\n          config.path,\n          errorOptions\n        )\n        console.log(\"\\nSaved baseline errors to '\" + config.path + \"'\")\n      }\n    }\n  })\n\n  program.command('add [hash]').action((hash) => {\n    if (!hash) {\n      console.error('Missing hash')\n    } else {\n      const config = getConfig()\n      addHashToBaseline(hash, config.path)\n    }\n  })\n\n  program\n    .command('check [message]')\n    .addOption(\n      new Option(\n        '--error-format [error-format]',\n        'Specifies the format for outputting errors.'\n      )\n        .default(ErrorFormat.HUMAN)\n        .choices(Object.values(ErrorFormat))\n    )\n    .option(\n      '--reportUnmatchedIgnoredErrors',\n      'Reports unmatched ignored errors that are in the baseline but not in the new errors.'\n    )\n    .action((message, options) => {\n      if (stdin) {\n        message = stdin\n        if (message) {\n          const config = getConfig()\n          let baselineFile\n          try {\n            baselineFile = readBaselineErrorsFile(config.path)\n          } catch (err) {\n            console.error(\n              `\n  Unable to read the .tsc-baseline.json file at \"${config.path}\".\n  \n  Has the baseline file been properly saved with the 'save' command?\n  `\n            )\n            process.exit(1)\n          }\n          if (!isBaselineVersionCurrent(baselineFile)) {\n            const baselineFileVersion = getBaselineFileVersion(baselineFile)\n            if (baselineFileVersion < CURRENT_BASELINE_VERSION) {\n              console.error(\n                `\nThe .tsc-baseline.json file at \"${config.path}\"\nis out of date for this version of tsc-baseline.\n\nPlease update the baseline file using the 'save' command.\n`\n              )\n              process.exit(1)\n            } else {\n              console.error(\n                `\nThe .tsc-baseline.json file at \"${config.path}\"\nis from a future version of tsc-baseline.\n\nAre your installed packages up to date?\n`\n              )\n              process.exit(1)\n            }\n          }\n\n          const oldErrorSummaries = getErrorSummaryMap(baselineFile)\n          const errorOptions = {\n            ignoreMessages: baselineFile.meta.ignoreMessages\n          }\n          const { specificErrorsMap, errorSummaryMap } = parseTypeScriptErrors(\n            message,\n            errorOptions\n          )\n          const newErrorSummaries = getNewErrors(\n            oldErrorSummaries,\n            errorSummaryMap\n          )\n          const newErrorsCount = getTotalErrorsCount(newErrorSummaries)\n          const oldErrorsCount = getTotalErrorsCount(oldErrorSummaries)\n\n          const newErrorsCountMessage = `${newErrorsCount} new error${\n            newErrorsCount === 1 ? '' : 's'\n          } found`\n\n          if (options.errorFormat === ErrorFormat.GITLAB) {\n            console.error(\n              toGitLabOutputFormat(\n                newErrorSummaries,\n                specificErrorsMap,\n                errorOptions\n              )\n            )\n          } else if (options.errorFormat === ErrorFormat.HUMAN) {\n            console.error(`${newErrorsCount > 0 ? '\\nNew errors found:' : ''}\n${toHumanReadableText(newErrorSummaries, specificErrorsMap, errorOptions)}\n\n${newErrorsCountMessage}. ${oldErrorsCount} error${\n              oldErrorsCount === 1 ? '' : 's'\n            } already in baseline.`)\n          } else {\n            console.error(`Invalid error format: ${options.errorFormat}`)\n            process.exit(1)\n          }\n\n          let unmatchedIgnoredErrorsCount = 0\n          if (options.reportUnmatchedIgnoredErrors) {\n            const unmatchedIgnoredErrors = getNewErrors(\n              errorSummaryMap,\n              oldErrorSummaries\n            )\n            unmatchedIgnoredErrorsCount = getTotalErrorsCount(\n              unmatchedIgnoredErrors\n            )\n            if (unmatchedIgnoredErrorsCount > 0) {\n              console.error(`\nUnmatched ignored errors:\n${toHumanReadableText(\n  unmatchedIgnoredErrors,\n  specificErrorsMap,\n  errorOptions,\n  true\n)}\nCount of unmatched ignored errors: ${unmatchedIgnoredErrorsCount}\n`)\n            }\n          }\n\n          if (newErrorsCount > 0 || unmatchedIgnoredErrorsCount > 0) {\n            // Exit with a failure code so new errors fail CI by default\n            process.exit(1)\n          }\n        }\n      }\n    })\n\n  program.command('clear').action(() => {\n    const config = getConfig()\n    rmSync(config.path)\n    console.log(\"Removed baseline file '\" + config.path + \"'\")\n  })\n\n  if (process.stdin.isTTY) {\n    program.parse(process.argv)\n  } else {\n    process.stdin.on('readable', function () {\n      // @ts-ignore\n      const chunk = this.read()\n      if (chunk !== null) {\n        stdin += chunk\n      }\n    })\n    process.stdin.on('end', function () {\n      program.parse(process.argv)\n    })\n  }\n\n  try {\n    await program.parseAsync(process.argv)\n  } catch (err: any) {\n    console.error(err.message)\n  }\n})()\n"],"names":["ErrorFormat","parseTypeScriptErrors","errorLog","_ref2","_step","ignoreMessages","errorPattern","lines","split","specificErrorsMap","Map","errorSummaryMap","addSpecificErrorToMap","filePathName","error","existingFile","get","push","set","addErrorToSummary","errorSummary","file","code","count","message","key","_ref","objectHash","getErrorSummaryHash","existingError","_extends","_iterator","_createForOfIteratorHelperLoose","done","match","value","columnStr","line","parseInt","column","writeTypeScriptErrorsToFile","map","filepath","errorOptions","newBaselineFile","meta","baselineFileVersion","errors","Object","fromEntries","writeFileSync","JSON","stringify","readBaselineErrorsFile","text","readFileSync","encoding","parse","getBaselineFileVersion","baselineFile","_baselineFile$meta","isBaselineVersionCurrent","getErrorSummaryMap","entries","getNewErrors","oldErrors","newErrors","_step2","result","_iterator2","_step2$value","id","has","_oldErrors$get$count","_oldErrors$get","_newErrors$get$count","_newErrors$get","oldErrCount","newErrCount","getTotalErrorsCount","errorMap","Array","from","values","reduce","sum","info","toHumanReadableText","specificErrorMap","isReportingUnmatchedErrors","_step3","log","_iterator3","_step3$value","specificErrors","getSpecificErrorsMatchingSummary","length","specificError","join","trim","_specificErrorsMap$ge","filter","program","Command","name","description","stdin","option","getConfig","config","opts","path","resolve","process","cwd","command","action","console","hash","baselineErrorsFile","Error","_step4","_iterator4","_step4$value","addHashToBaseline","addOption","Option","HUMAN","choices","options","err","exit","oldErrorSummaries","_parseTypeScriptError","newErrorSummaries","newErrorsCount","oldErrorsCount","newErrorsCountMessage","errorFormat","GITLAB","_step5","_loop","_step5$value","forEach","index","check_name","fingerprint","severity","location","begin","_iterator5","toGitLabOutputFormat","unmatchedIgnoredErrorsCount","reportUnmatchedIgnoredErrors","unmatchedIgnoredErrors","rmSync","isTTY","argv","on","chunk","this","read","_temp","Promise","parseAsync","then","_catch","e","reject"],"mappings":"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"}