{"version":3,"file":"eslint.mjs","sources":["../../../src/plugins/eslint.ts"],"sourcesContent":["import { compact, concurrently, isTypeOfString, lazyValue, toArray } from '@neodx/std';\nimport type { ESLint } from 'eslint';\nimport { extname } from 'pathe';\nimport { displayPath, getVfsActions } from '../core/operations';\nimport { createVfsPlugin } from '../create-vfs-plugin';\n\nexport interface EsLintPluginApi {\n  /** Fix ESLint issues in the given path(s) */\n  fix(path: string | string[]): Promise<void>;\n  /** Fix ESLint issues in all changed files */\n  fixAll(): Promise<void>;\n}\n\nexport interface EsLintPluginParams {\n  /**\n   * @see ESLint.Options.fix\n   * @default true\n   */\n  fix?: boolean;\n  /**\n   * Should fix all issues on apply?\n   * @default true\n   */\n  auto?: boolean;\n  /**\n   * Should log errors to the console?\n   * @default true\n   */\n  logErrors?: boolean;\n  /**\n   * Should log warnings to the console?\n   * @default false\n   */\n  logWarnings?: boolean;\n  /**\n   * Additional ESLint options\n   * @see ESLint.Options\n   */\n  eslintParams?: ESLint.Options;\n}\n\nexport function eslint({\n  fix = true,\n  auto = true,\n  logErrors = true,\n  logWarnings = false,\n  eslintParams\n}: EsLintPluginParams = {}) {\n  return createVfsPlugin<EsLintPluginApi>('eslint', (vfs, { context, beforeApply }) => {\n    const { fix: originalFix, fixAll: originalFixAll } = vfs;\n    const getEsLint = lazyValue(async () => {\n      const { ESLint } = await import('eslint');\n\n      return new ESLint({\n        overrideConfig: {\n          env: {\n            es6: true,\n            node: true\n          },\n          parserOptions: {\n            ecmaVersion: 2022,\n            sourceType: 'module'\n          }\n        },\n        ...eslintParams,\n        fix,\n        cwd: context.path\n      });\n    });\n    const log = context.log.child('eslint');\n\n    vfs.fix = async (path: string | string[]) => {\n      const lint = await getEsLint();\n      const allResults = await concurrently(toArray(path), async path => {\n        if (!(await vfs.isFile(path))) {\n          log.debug('Skipping %s, because it is not a file', displayPath(context, path));\n          return null;\n        }\n        if (await lint.isPathIgnored(path)) {\n          log.debug('Skipping %s, because it is ignored', displayPath(context, path));\n          return null;\n        }\n        if (!allSourceExtensions.includes(extname(path))) {\n          log.debug('Skipping %s, because it is not a source file', displayPath(context, path));\n          return null;\n        }\n        return await lint.lintText(await vfs.read(path, 'utf-8'), { filePath: vfs.resolve(path) });\n      });\n      const results = compact(allResults.flat());\n\n      const errors = results.filter(result => result.fatalErrorCount > 0);\n      const warnings = results.filter(result => result.fatalErrorCount > 0);\n      const fatalErrors = results.filter(result => result.fatalErrorCount > 0);\n      const formatter = await lint.loadFormatter('stylish');\n\n      if (fatalErrors.length > 0) {\n        log.error('ESLint fatal errors:%s', formatter.format(fatalErrors));\n      }\n      if (logErrors && errors.length > 0) {\n        log.error('ESLint errors:%s', formatter.format(errors));\n      }\n      if (logWarnings && warnings.length > 0) {\n        log.warn('ESLint warnings:%s', formatter.format(warnings));\n      }\n\n      await concurrently(\n        results,\n        async ({ filePath, fixableErrorCount, fixableWarningCount, output }) => {\n          if (!isTypeOfString(output)) return;\n          log.debug(\n            'fixing %d ESLint issues in %s',\n            fixableErrorCount + fixableWarningCount,\n            filePath\n          );\n          return await vfs.write(filePath, output);\n        }\n      );\n      await originalFix?.(path);\n    };\n\n    vfs.fixAll = async () => {\n      log.debug('Fixing all ESLint issues in changed files...');\n      const changes = await getVfsActions(context, ['create', 'update']);\n\n      await vfs.fix!(changes.map(change => change.path));\n      await originalFixAll?.();\n    };\n\n    if (auto) {\n      beforeApply(() => vfs.fixAll!());\n    }\n\n    return vfs;\n  });\n}\n\nconst allSourceExtensions = ['js', 'ts'].flatMap(ext => [\n  `.${ext}`,\n  `.c${ext}`,\n  `.m${ext}`,\n  `.${ext}x`\n]);\n"],"names":["eslint","fix","auto","logErrors","logWarnings","eslintParams","createVfsPlugin","vfs","context","beforeApply","originalFix","fixAll","originalFixAll","getEsLint","lazyValue","ESLint","overrideConfig","env","es6","node","parserOptions","ecmaVersion","sourceType","cwd","path","log","child","lint","results","compact","allResults","concurrently","toArray","isFile","isPathIgnored","debug","displayPath","allSourceExtensions","includes","extname","lintText","read","filePath","resolve","flat","errors","filter","result","fatalErrorCount","warnings","fatalErrors","formatter","loadFormatter","length","error","format","warn","fixableErrorCount","fixableWarningCount","output","isTypeOfString","write","changes","getVfsActions","map","change","flatMap","ext"],"mappings":"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"}