{"version":3,"sources":["../src/SeatbeltFile.ts","../src/errorHanding.ts"],"sourcesContent":["import * as os from \"node:os\"\nimport * as fs from \"node:fs\"\nimport path, * as nodePath from \"node:path\"\nimport {\n  formatFilename,\n  formatRuleId,\n  SEATBELT_FROZEN,\n  SEATBELT_KEEP,\n  SeatbeltArgs,\n} from \"./SeatbeltConfig\"\nimport { name } from \"../package.json\"\nimport { appendErrorContext, isErrno } from \"./errorHanding\"\n\nexport type SourceFileName = string\nexport type RuleId = string\n\ninterface SeatbeltFileLine {\n  encoded?: string\n  filename: SourceFileName\n  ruleId: RuleId\n  maxErrors: number\n}\n\nexport type SeatbeltFileJson = {\n  filename: SourceFileName\n  data: Record<SourceFileName, Record<RuleId, number>>\n}\n\nfunction encodeLine(line: SeatbeltFileLine): string {\n  const { filename, ruleId, maxErrors } = line\n  return `${JSON.stringify(filename)}\\t${JSON.stringify(ruleId)}\\t${maxErrors}\\n`\n}\n\nfunction decodeLine(line: string, index: number): SeatbeltFileLine {\n  try {\n    const lineParts = line.split(\"\\t\")\n    if (lineParts.length !== 3) {\n      throw new Error(\n        `Expected 3 tab-separated JSON strings, instead have ${lineParts.length}`,\n      )\n    }\n    let filename: string\n    try {\n      filename = JSON.parse(lineParts[0])\n    } catch (e) {\n      appendErrorContext(e, \"at tab-separated column 1 (filename)\")\n      throw e\n    }\n\n    let ruleId: RuleId\n    try {\n      ruleId = JSON.parse(lineParts[1])\n    } catch (e) {\n      appendErrorContext(e, \"at tab-separated column 2 (RuleId)\")\n      throw e\n    }\n\n    let maxErrors: number\n    try {\n      maxErrors = JSON.parse(lineParts[2])\n    } catch (e) {\n      appendErrorContext(e, \"at tab-separated column 3 (maxErrors)\")\n      throw e\n    }\n\n    return {\n      encoded: line,\n      filename,\n      ruleId,\n      maxErrors,\n    }\n  } catch (e) {\n    appendErrorContext(e, `at line ${index + 1}: \\`${line.trim()}\\``)\n    throw e\n  }\n}\n\ninterface SeatbeltStateFileData {\n  maxErrors?: Map<RuleId, number>\n  lines: SeatbeltFileLine[]\n}\n\nconst COMMENT_LINE_REGEX = /^\\s*#/\n\nconst DEFAULT_FILE_HEADER = `\n# ${name} temporarily allowed errors\n# docs: https://github.com/justjake/${name}#readme\n`.trim()\n\n/**\n * The state file is a Map<filename, Map<ruleId, allowedErrors>>.\n * It is stored in \"tab separated json\" format. This format is chosen over JSON\n * or YAML because each line is independent, which makes resolving merge\n * conflicts much easier than in a syntactically hierarchical format.\n */\nexport class SeatbeltFile {\n  static readSync(filename: string): SeatbeltFile {\n    const text = fs.readFileSync(filename, \"utf8\")\n    try {\n      return SeatbeltFile.parse(filename, text)\n    } catch (e) {\n      appendErrorContext(e, `in seatbelt file \\`${filename}\\``)\n      throw e\n    }\n  }\n\n  /**\n   * Read `filename` if it exists, otherwise create a new empty seatbelt file object\n   * that will write to that filename.\n   */\n  static openSync(filename: string): SeatbeltFile {\n    try {\n      return SeatbeltFile.readSync(filename)\n    } catch (e) {\n      if (isErrno(e, \"ENOENT\")) {\n        return new SeatbeltFile(filename, new Map(), DEFAULT_FILE_HEADER)\n      }\n      throw e\n    }\n  }\n\n  static parse(filename: string, text: string): SeatbeltFile {\n    const data = new Map<SourceFileName, SeatbeltStateFileData>()\n    const split = text.split(/(?<=\\n)/)\n    const lines = split\n      .filter(\n        (line) =>\n          line !== \"\" && line !== \"\\n\" && !COMMENT_LINE_REGEX.test(line),\n      )\n      .map(decodeLine)\n    const comments = split\n      .filter((line) => COMMENT_LINE_REGEX.test(line))\n      .join(\"\")\n    lines.forEach((line) => {\n      let fileState = data.get(line.filename)\n      if (!fileState) {\n        fileState = { maxErrors: undefined, lines: [] }\n        data.set(line.filename, fileState)\n      }\n      fileState.lines.push(line)\n    })\n    return new SeatbeltFile(filename, data, comments.trim())\n  }\n\n  static fromJSON(json: SeatbeltFileJson): SeatbeltFile {\n    const data = new Map(\n      Object.entries(json.data).map(([filename, maxErrors]) => [\n        filename,\n        { maxErrors: new Map(Object.entries(maxErrors)), lines: [] },\n      ]),\n    )\n    return new SeatbeltFile(json.filename, data)\n  }\n\n  public changed = false\n  private readonly dirname: string\n  private useTempDirForWrites = true\n\n  constructor(\n    public readonly filename: string,\n    protected data: Map<SourceFileName, SeatbeltStateFileData>,\n    public readonly comments: string = \"\",\n  ) {\n    this.filename = path.resolve(this.filename)\n    this.dirname = path.dirname(this.filename)\n  }\n\n  *filenames(): IterableIterator<SourceFileName> {\n    for (const filename of this.data.keys()) {\n      yield this.toAbsolutePath(filename)\n    }\n  }\n\n  getMaxErrors(\n    filename: SourceFileName,\n  ): ReadonlyMap<RuleId, number> | undefined {\n    const fileState = this.data.get(this.toRelativePath(filename))\n    if (!fileState) {\n      return undefined\n    }\n    fileState.maxErrors ??= parseMaxErrors(fileState.lines)\n    return fileState.maxErrors\n  }\n\n  removeFile(filename: SourceFileName, args: SeatbeltArgs) {\n    const relativeFilename = this.toRelativePath(filename)\n    if (!this.data.has(relativeFilename)) {\n      return false\n    }\n\n    SeatbeltArgs.verboseLog(args, () =>\n      args.frozen\n        ? `${formatFilename(filename)}: ${SEATBELT_FROZEN}: didn't remove max errors`\n        : `${formatFilename(filename)}: remove max errors`,\n    )\n\n    if (args.frozen) {\n      return false\n    }\n\n    this.data.delete(relativeFilename)\n    this.changed = true\n    return true\n  }\n\n  updateMaxErrors(\n    filename: SourceFileName,\n    args: SeatbeltArgs,\n    ruleToErrorCount: ReadonlyMap<RuleId, number>,\n  ) {\n    const removedRules = new Set<RuleId>()\n    let increasedRulesCount = 0\n    let decreasedRulesCount = 0\n    this.getMaxErrors(filename)\n    const relativeFilename = this.toRelativePath(filename)\n    const maxErrors =\n      this.data.get(relativeFilename)?.maxErrors ?? new Map<RuleId, number>()\n\n    ruleToErrorCount.forEach((errorCount, ruleId) => {\n      const maxErrorCount = maxErrors.get(ruleId) ?? 0\n      if (errorCount === maxErrorCount) {\n        return\n      }\n\n      if (\n        errorCount < maxErrorCount ||\n        SeatbeltArgs.ruleSetHas(args.allowIncreaseRules, ruleId)\n      ) {\n        SeatbeltArgs.verboseLog(args, () =>\n          args.frozen\n            ? `${formatFilename(filename)}: ${formatRuleId(ruleId)}: ${SEATBELT_FROZEN}: didn't update max errors ${maxErrorCount} -> ${errorCount}`\n            : `${formatFilename(filename)}: ${formatRuleId(ruleId)}: update max errors ${maxErrorCount} -> ${errorCount}`,\n        )\n        maxErrors.set(ruleId, errorCount)\n        if (errorCount > maxErrorCount) {\n          increasedRulesCount++\n        } else {\n          decreasedRulesCount++\n        }\n      }\n    })\n\n    if (args.verbose || args.keepRules !== \"all\") {\n      maxErrors.forEach((maxErrorCount, ruleId) => {\n        const shouldRemove =\n          maxErrorCount === 0 || !ruleToErrorCount.has(ruleId)\n\n        if (!shouldRemove) {\n          return\n        }\n\n        if (SeatbeltArgs.ruleSetHas(args.keepRules, ruleId)) {\n          SeatbeltArgs.verboseLog(\n            args,\n            () =>\n              `${formatFilename(filename)}: ${formatRuleId(ruleId)}: ${SEATBELT_KEEP}: didn't update max errors ${maxErrorCount} -> ${0}`,\n          )\n          return\n        }\n\n        SeatbeltArgs.verboseLog(args, () =>\n          args.frozen\n            ? `${formatFilename(filename)}: ${formatRuleId(ruleId)}: ${SEATBELT_FROZEN}: didn't update max errors ${maxErrorCount} -> ${0}`\n            : `${formatFilename(filename)}: ${formatRuleId(ruleId)}: update max errors ${maxErrorCount} -> ${0}`,\n        )\n\n        maxErrors.delete(ruleId)\n        removedRules.add(ruleId)\n      })\n    }\n\n    const changed =\n      increasedRulesCount > 0 ||\n      decreasedRulesCount > 0 ||\n      removedRules.size > 0\n    if (changed && !args.frozen) {\n      const file = this.data.get(relativeFilename)\n      if (file) {\n        file.maxErrors = maxErrors\n      } else {\n        this.data.set(relativeFilename, {\n          maxErrors,\n          lines: [],\n        })\n      }\n      this.changed = true\n    }\n\n    return { removedRules, increasedRulesCount, decreasedRulesCount }\n  }\n\n  toDataString(): string {\n    const lines: string[] = []\n    this.data.forEach((fileState, filename) => {\n      if (fileState.maxErrors) {\n        // Serialize maxErrors map structure if it exists, since it may have changes.\n        fileState.lines = []\n        fileState.maxErrors.forEach((maxErrorCount, ruleId) => {\n          fileState.lines.push({ filename, ruleId, maxErrors: maxErrorCount })\n        })\n        fileState.lines.sort((a, b) =>\n          a.ruleId === b.ruleId ? 0 : a.ruleId < b.ruleId ? -1 : 1,\n        )\n      }\n      fileState.lines.forEach((line) => {\n        const encoded = (line.encoded ??= encodeLine(line))\n        lines.push(encoded)\n      })\n    })\n    lines.sort()\n    if (this.comments) {\n      return this.comments + \"\\n\\n\" + lines.join(\"\")\n    } else {\n      return lines.join(\"\")\n    }\n  }\n\n  readSync() {\n    const nextStateFile = SeatbeltFile.openSync(this.filename)\n    if (nextStateFile) {\n      this.data = nextStateFile.data\n      this.changed = false\n      return true\n    }\n    return false\n  }\n\n  flushChanges() {\n    if (this.changed) {\n      this.writeSync()\n      this.changed = false\n      return { updated: true }\n    }\n    return { updated: false }\n  }\n\n  writeSync() {\n    const dataString = this.toDataString()\n    const dir = nodePath.dirname(this.filename)\n    const base = nodePath.basename(this.filename)\n    const tempFile = nodePath.join(\n      this.useTempDirForWrites ? os.tmpdir() : dir,\n      `.${base}.wip${process.pid}.${Date.now()}.tmp`,\n    )\n    fs.mkdirSync(dir, { recursive: true })\n    fs.writeFileSync(tempFile, dataString, \"utf8\")\n    try {\n      fs.renameSync(tempFile, this.filename)\n    } catch (error) {\n      // If $TMPDIR is on a different filesystem from the git repo, we won't be\n      // able to move the tempfile over the existing file.\n      //\n      // In such cases copy & remove the tempfile instead, and then prefer to create\n      // tempfiles in the desination dir.\n      //\n      // https://github.com/justjake/eslint-seatbelt/issues/7\n      if (isErrno(error, 'EXDEV')) {\n        this.useTempDirForWrites = false\n        fs.copyFileSync(tempFile, this.filename)\n        fs.rmSync(tempFile)\n        return\n      }\n      throw error\n    }\n  }\n\n  toJSON(): SeatbeltFileJson {\n    const data = Object.fromEntries(\n      Array.from(this.data.keys()).map((filename) => {\n        const maxErrors = this.getMaxErrors(filename)\n        if (!maxErrors) {\n          throw new Error(`${name} bug: expected errors for existing key`)\n        }\n        return [filename, Object.fromEntries(maxErrors)]\n      }),\n    )\n    return { filename: this.filename, data }\n  }\n\n  toRelativePath(filename: string) {\n    if (!nodePath.isAbsolute(filename)) {\n      return filename\n    }\n    return nodePath.relative(this.dirname, filename)\n  }\n\n  toAbsolutePath(filename: string) {\n    if (nodePath.isAbsolute(filename)) {\n      return filename\n    }\n    return nodePath.resolve(this.dirname, filename)\n  }\n}\n\nfunction parseMaxErrors(lines: SeatbeltFileLine[]): Map<RuleId, number> {\n  const maxErrors = new Map<RuleId, number>()\n  lines.forEach((line) => {\n    maxErrors.set(line.ruleId, line.maxErrors)\n  })\n  return maxErrors\n}\n","export function appendErrorContext(error: unknown, context: string) {\n  if (error instanceof Error) {\n    error.message += `\\n  ${context}`\n  }\n}\n\nexport function isErrno(\n  error: unknown,\n  code: string,\n): error is NodeJS.ErrnoException {\n  return error instanceof Error && \"code\" in error && error.code === code\n}\n"],"mappings":"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","names":[]}