From db9c603cc16fc587e7dfaa2a4559420bfbb6221f Mon Sep 17 00:00:00 2001 From: Alireza Safaierad Date: Sat, 19 Oct 2024 21:12:20 +0200 Subject: [PATCH] fix: fix option.ignores --- README.md | 18 +++++++++- eslint.config.js | 3 +- package.json | 4 +-- src/index.js | 78 +++++++++++++++++++++++++++++-------------- src/modules/ignore.js | 12 +++++++ src/option.d.ts | 4 ++- src/utils/compose.js | 12 ------- 7 files changed, 88 insertions(+), 43 deletions(-) create mode 100644 src/modules/ignore.js delete mode 100644 src/utils/compose.js diff --git a/README.md b/README.md index b266392..202653c 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,22 @@ $ npm install --save-dev @fullstacksjs/eslint-config eslint prettier To use the configuration all you need is exporting generated config by `init` function. The configuration reads the metadata from your root `package.json` file and automatically adds the rules and plugins that are needed. +### ESM + ```js import { init } from '@fullstacksjs/eslint-config'; export default init(); ``` +### CJS + +```js +const { init } = require('@fullstacksjs/eslint-config'); + +module.exports = init(); +``` + ## Modules API You can fine tune module detection by overriding it, `init` function accepts options as its first argument to control enabled modules. @@ -70,7 +80,13 @@ import { init } from '@fullstacksjs/eslint-config'; export default init( { typescript: true, - }, { + // You can pass extends here + rules { + 'no-console': 'error' + } + }, + // And any number of extra configurations + { files: ['**/*.ts'], rules: {}, }, { diff --git a/eslint.config.js b/eslint.config.js index 37fdc15..9992fd4 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -2,6 +2,7 @@ import { init } from './src/index.js'; export default init( { + ignores: ['cjs/'], fp: false, test: true, esm: true, @@ -16,8 +17,6 @@ export default init( storybook: true, typescript: true, tailwind: false, - }, - { rules: { 'max-lines-per-function': 'off', 'complexity': 'off', diff --git a/package.json b/package.json index 795b3a5..237a25a 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ "module": "./src/index.js", "exports": { ".": { - "import": "./cjs/index.js", - "require": "./src/index.js" + "import": "./src/index.js", + "require": "./cjs/index.js" } }, "type": "module", diff --git a/src/index.js b/src/index.js index f8abdd1..687767a 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,7 @@ import { isPackageExists } from 'local-pkg'; import base from './modules/base.js'; import cypress from './modules/cypress.js'; import fp from './modules/functional.js'; +import ignores from './modules/ignore.js'; import imports from './modules/imports.js'; import jest from './modules/jest.js'; import next from './modules/next.js'; @@ -17,11 +18,15 @@ import tailwind from './modules/tailwind.js'; import tests from './modules/tests.js'; import typescript from './modules/typescript.js'; import vitest from './modules/vitest.js'; -import { compose } from './utils/compose.js'; const testPackages = ['jest', 'vitest', 'cypress', 'playwright']; -/** @type {import('./option.d.ts').Options} */ +/** + * @typedef {import('eslint').Linter.Config} Config + * @typedef {import('./option.d.ts').Options} Options + * / + +/** @type {Options} */ const defaultOptions = { cypress: isPackageExists('cypress'), disableExpensiveRules: false, @@ -41,18 +46,16 @@ const defaultOptions = { tailwind: isPackageExists('tailwindcss'), test: testPackages.some(p => isPackageExists(p)), typescript: isPackageExists('typescript') ? { projects: true } : false, - unocss: isPackageExists('unocss'), vitest: isPackageExists('vitest'), }; /** * Initialize eslint config - * - * @param {import('./option.d.ts').Options} initOptions - * @param {...(import('eslint').Linter.Config)} extend - * @returns {import('eslint').Linter.Config[]} + * @param {Options} initOptions + * @param {...Config} extend + * @returns {Config[]} */ -export function init(initOptions, ...extend) { +export function init(initOptions = {}, ...extend) { const options = merge(defaultOptions, initOptions); if (options.typescript === true) { options.typescript = {}; @@ -61,24 +64,49 @@ export function init(initOptions, ...extend) { options.import = {}; } - const rules = [compose(base, options)]; + const { + sort: enableSort, + cypress: enableCypress, + disableExpensiveRules, + esm: enableEsm, + fp: enableFp, + ignores: enableIgnores, + import: enableImport, + jest: enableJest, + next: enableNext, + node: enableNode, + playwright: enablePlaywright, + prettier: enablePrettier, + react: enableReact, + storybook: enableStorybook, + strict: enableStrict, + tailwind: enableTailwind, + test: enableTest, + typescript: enableTypescript, + vitest: enableVitest, + ...eslintOptions + } = options; + + const rules = [ignores(options), base(options)]; - if (options.fp) rules.push(compose(fp, options)); - if (options.sort) rules.push(compose(perfectionist, options)); - if (options.import) rules.push(compose(imports, options)); - if (options.tailwind) rules.push(compose(tailwind, options)); - if (options.test) rules.push(compose(tests, options)); - if (options.node) rules.push(compose(node, options)); - if (options.jest) rules.push(compose(jest, options)); - if (options.vitest) rules.push(compose(vitest, options)); - if (options.cypress) rules.push(compose(cypress, options)); - if (options.react) rules.push(compose(react, options)); - if (options.storybook) rules.push(compose(storybook, options)); - if (options.typescript) rules.push(compose(typescript, options)); - if (options.playwright) rules.push(compose(playwright, options)); - if (options.next && options.next) rules.push(compose(next, options)); + if (enableFp) rules.push(fp(options)); + if (enableSort) rules.push(perfectionist(options)); + if (enableImport) rules.push(imports(options)); + if (enableTailwind) rules.push(tailwind(options)); + if (enableTest) rules.push(tests(options)); + if (enableNode) rules.push(node(options)); + if (enableJest) rules.push(jest(options)); + if (enableVitest) rules.push(vitest(options)); + if (enableCypress) rules.push(cypress(options)); + if (enableReact) rules.push(react(options)); + if (enableStorybook) rules.push(storybook(options)); + if (enableTypescript) rules.push(typescript(options)); + if (enablePlaywright) rules.push(playwright(options)); + if (enableNext && enableNext) rules.push(next(options)); + if (enablePrettier) rules.push(prettier(options)); - if (options.prettier) rules.push(compose(prettier, options)); + if (Object.keys(eslintOptions).length > 0) rules.push(eslintOptions); + if (extend) Array.prototype.push.apply(rules, extend); - return rules.concat(extend); + return rules; } diff --git a/src/modules/ignore.js b/src/modules/ignore.js new file mode 100644 index 0000000..504874e --- /dev/null +++ b/src/modules/ignore.js @@ -0,0 +1,12 @@ +import { ignoreGlobs } from '../utils/globs.js'; +/** + * @param { import('../option').Options } options + * @return { import('eslint').Linter.Config } + */ +function ignores(options = {}) { + return { + ignores: [...ignoreGlobs, ...(options.ignores ?? [])], + }; +} + +export default ignores; diff --git a/src/option.d.ts b/src/option.d.ts index 89a53e9..096ac57 100644 --- a/src/option.d.ts +++ b/src/option.d.ts @@ -1,4 +1,6 @@ -export interface Options { +import type { Linter } from 'eslint'; + +export interface Options extends Linter.Config { react?: boolean; sort?: boolean; next?: boolean; diff --git a/src/utils/compose.js b/src/utils/compose.js deleted file mode 100644 index bfe5ca5..0000000 --- a/src/utils/compose.js +++ /dev/null @@ -1,12 +0,0 @@ -import { ignoreGlobs } from './globs.js'; - -/** - * @param { (options: import('eslint').Linter.Config) => import('eslint').Linter.Config } module - * @param { import('../option').Options } options - * @return { import('eslint').Linter.Config } - */ -export function compose(module, options) { - const config = module(options); - config.ignores = [...(config.ignores ?? []), ...(options.ignores ?? []), ...(ignoreGlobs ?? [])]; - return config; -}