Skip to content

Commit

Permalink
Upgrade all plugins, migrate all configs to FlatConfig
Browse files Browse the repository at this point in the history
TODO:
- update README and docs
- create github page
- create no-splice-add and no-splice-remove rules and include in base
- fix TS issues and upgrade plugins as they transition to FlatConfig
- add tests
- create release workflow for github

BREAKING CHANGE: FlatConfig requires eslint >= 8.23 and eslint.config.js
  • Loading branch information
burtek committed May 13, 2023
1 parent 4bc2ae0 commit 8496377
Show file tree
Hide file tree
Showing 32 changed files with 1,977 additions and 1,410 deletions.
File renamed without changes.
44 changes: 0 additions & 44 deletions .github/workflows/make-release.yml

This file was deleted.

Empty file.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
node_modules/
/node_modules
*.log
532 changes: 532 additions & 0 deletions configs/base.js

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions configs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { defineFlatConfig } from 'eslint-define-config';

import { prepareConfig as base } from './base.js';
import { prepareConfig as jest } from './jest.js';
import { prepareConfig as json } from './json.js';
import { prepareConfig as lodash } from './lodash.js';
import { prepareConfig as node } from './node.js';
import { prepareConfig as react } from './react.js';

/** @satisfies {Record<string, (config?: any) => import('eslint-define-config').FlatESLintConfig[]>} */
const configs = {
base,
jest,
json,
lodash,
node,
react
};

/**
* @template {keyof typeof configs} T
* @typedef {NonNullable<Parameters<(typeof configs)[T]>[0]>} Config
*/

/**
* Creates eslint flat config based on provided configuration object.
*
* @param {{ [K in Exclude<keyof typeof configs, 'base'>]?: Config<K> | true }} [providedConfigs]
* @returns
*/
export function prepareConfig(providedConfigs = {}) {
/** @type {{ [K in keyof typeof configs]?: Config<K> | true }} */
const config = { ...providedConfigs, base: true };
const configKeys = /** @type {Array<keyof typeof configs>} */(Object.keys(configs));

/**
* @template {keyof typeof configs} T
* @param {T} key
*/
function mapConfig(key) {
if (!config[key]) {
return [];
}
if (config[key] === true) {
return configs[key]();
}
// @ts-expect-error -- TODO: fixme
return configs[key](config[key]);
}

return defineFlatConfig([
...base(),
...configKeys.flatMap(mapConfig)
]);
}
80 changes: 80 additions & 0 deletions configs/jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { defineFlatConfig } from 'eslint-define-config';
import jestPlugin from 'eslint-plugin-jest';
import * as jestFormatting from 'eslint-plugin-jest-formatting';
import globals from 'globals';


const testFiles = '**/*.test.{js,cjs,mjs,jsx,ts,cts,mts,tsx}';
const mockFiles = '**/__mocks__/**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}';

const tsTestFiles = '**/*.test.{ts,cts,mts,tsx}';
const tsMockFiles = '**/__mocks__/**/*.{ts,cts,mts,tsx}';

// /** @typedef {Partial<import('eslint-define-config/src/rules/jsonc/index.js').JsoncRules>} JsoncRules */
// /** @typedef {Partial<import('eslint-define-config/src/rules/eslint/index.js').EslintRules>} EslintRules */

/**
* @param {Object} [config]
* @param {'jest' | 'vitest'} [config.mode]
*/
export function prepareConfig({ mode = 'jest' } = {}) {
return defineFlatConfig([
{
files: [testFiles, mockFiles],
languageOptions: {
globals: {
...globals.jest,
...globals.node
}
},
settings: {
jest: {
// lie to eslint-plugin-jest that we indeed use jest (vitest has same syntax)
...(mode === 'vitest' && { version: 29 })
}
},
rules: {
'no-console': 'off',
'no-magic-numbers': 'off',
'no-redeclare': 'off'
}
},
{
files: [tsTestFiles, tsMockFiles],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-magic-numbers': 'off',
'@typescript-eslint/no-redeclare': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off'
}
},
{
files: [testFiles],
plugins: {
'jest': jestPlugin,
'jest-formatting': jestFormatting
},
rules: {
'jest-formatting/padding-around-all': 'error',

...jestPlugin.configs.recommended.rules,
...jestPlugin.configs.style.rules,

'jest/consistent-test-it': 'error',
'jest/no-conditional-in-test': 'error',
'jest/no-duplicate-hooks': 'error',
'jest/no-test-return-statement': 'error',
'jest/prefer-each': 'error',
'jest/prefer-hooks-in-order': 'error',
'jest/prefer-hooks-on-top': 'error',
'jest/prefer-mock-promise-shorthand': 'error',
'jest/prefer-strict-equal': 'error',
'jest/prefer-todo': 'error'
}
},
{
files: [tsTestFiles],
rules: { 'jest/no-untyped-mock-factory': 'error' }
}
]);
}
49 changes: 49 additions & 0 deletions configs/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { defineFlatConfig } from 'eslint-define-config';
import * as jsonc from 'eslint-plugin-jsonc';
import jsonParser from 'jsonc-eslint-parser';

/** @typedef {Partial<import('eslint-define-config/src/rules/jsonc/index.js').JsoncRules>} JsoncRules */
/** @typedef {Partial<import('eslint-define-config/src/rules/eslint/index.js').EslintRules>} EslintRules */

/**
* @param {Object} [config]
* @param {Partial<Record<'json' | 'jsonc' | 'json5', string[]>>} [config.additionalFiles]
*/
export function prepareConfig({
additionalFiles: {
json: additionalFilesJson = [],
json5: additionalFilesJson5 = [],
jsonc: additionalFilesJsonc = []
} = {}
} = {}) {
return defineFlatConfig([
{
files: ['**/*.{json,jsonc,json5}', ...additionalFilesJson, ...additionalFilesJson5, ...additionalFilesJsonc],
plugins: /** @type {any} */({ jsonc }),
languageOptions: { parser: /** @type {any} */(jsonParser) },
rules: /** @type {EslintRules} */(jsonc.configs.base.overrides[0].rules)
},
{
files: ['**/*.json', ...additionalFilesJson],
ignores: ['**/tsconfig.json', '**/jsconfig.json'],
rules: {
.../** @type {JsoncRules} */(jsonc.configs['recommended-with-json'].rules),
'jsonc/indent': ['error', 2]
}
},
{
files: ['**/*.jsonc', '**/tsconfig.json', '**/jsconfig.json', ...additionalFilesJsonc],
rules: {
.../** @type {JsoncRules} */(jsonc.configs['recommended-with-jsonc'].rules),
'jsonc/indent': ['error', 2]
}
},
{
files: ['**/*.json5', ...additionalFilesJson5],
rules: {
.../** @type {JsoncRules} */(jsonc.configs['recommended-with-json5'].rules),
'jsonc/indent': ['error', 2]
}
}
]);
}
27 changes: 27 additions & 0 deletions configs/lodash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineFlatConfig } from 'eslint-define-config';
import lodash from 'eslint-plugin-lodash';


const files = ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'];

export function prepareConfig() {
return defineFlatConfig([
{
files,
plugins: { lodash },
rules: {
'lodash/import-scope': ['error', 'method'],
'lodash/prefer-compact': 'error',
'lodash/prefer-find': 'error',
'lodash/prefer-flat-map': 'error',
'lodash/prefer-immutable-method': 'error',
'lodash/prefer-is-nil': 'error',
'lodash/prefer-map': 'error',
'lodash/prefer-matches': 'error',
'lodash/prefer-noop': 'error',
'lodash/prefer-reject': 'error',
'lodash/prefer-times': 'error'
}
}
]);
}
52 changes: 52 additions & 0 deletions configs/node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { defineFlatConfig } from 'eslint-define-config';
import n from 'eslint-plugin-n';
import nodeSecurity from 'eslint-plugin-security-node';
import globals from 'globals';


export function prepareConfig() {
return defineFlatConfig([
{
files: ['**/*.{js,cjs,mjs,ts,cts,mts}'],
plugins: {
n,
'security-node': nodeSecurity
},
languageOptions: {
globals: {
// eslint-disable-next-line no-warning-comments
...n.configs['recommended-module'].globals, // TODO: recommended once eslint-plugin-n moves to FlatConfig
...globals.node
},
parserOptions: { ecmaFeatures: { globalReturn: false } }
},
rules: {
// eslint-disable-next-line no-warning-comments
...n.configs['recommended-module'].rules, // TODO: recommended once eslint-plugin-n moves to FlatConfig
...nodeSecurity.configs.recommended.rules,

'no-console': 'off',

'n/no-missing-import': 'off',
'n/no-missing-require': 'off',
'n/no-path-concat': 'error',
'n/callback-return': 'error',
'n/prefer-global/buffer': 'error',
'n/prefer-global/console': 'error',
'n/prefer-global/process': 'error',
'n/prefer-global/url-search-params': 'error',
'n/prefer-global/url': 'error',
'n/prefer-promises/dns': 'error',
'n/prefer-promises/fs': 'error'
}
},
{
files: ['**/*.{ts,cts,mts}'],
rules: {
'n/no-unpublished-import': 'error',
'n/no-unpublished-require': 'error',
'n/no-unsupported-features/es-syntax': 'off'
}
}
]);
}
Loading

0 comments on commit 8496377

Please sign in to comment.