- Add ESLint configuration with TypeScript support - Add Prettier configuration for code formatting - Move all config files to .config/ folder to keep them hidden from Obsidian - Add lint and format scripts to package.json - Add .eslintignore and .prettierignore files - Remove framework-specific configuration - Configure for general JavaScript/TypeScript development
354 lines
14 KiB
JavaScript
354 lines
14 KiB
JavaScript
import { fixupPluginRules, includeIgnoreFile } from '@eslint/compat'
|
|
import checkFilePlugin from 'eslint-plugin-check-file'
|
|
import importPlugin from 'eslint-plugin-import'
|
|
import perfectionist from 'eslint-plugin-perfectionist'
|
|
import globals from 'globals'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import tsEslint, { parser } from 'typescript-eslint'
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
const gitIgnorePath = path.join(__dirname, '..', '.gitignore')
|
|
const autofix = process.env.CI ? 'error' : 'warn'
|
|
|
|
/** @type {import('@typescript-eslint/utils/ts-eslint').FlatConfig.Config[]} */
|
|
export default [
|
|
// Global ignore
|
|
{
|
|
ignores: ['**/*.json'],
|
|
name: 'claudesidian/global-ignore',
|
|
},
|
|
|
|
// Git ignore
|
|
{
|
|
...includeIgnoreFile(gitIgnorePath),
|
|
name: 'claudesidian/gitignore',
|
|
},
|
|
|
|
// Default config
|
|
{
|
|
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.mjs'],
|
|
languageOptions: {
|
|
parser,
|
|
parserOptions: {
|
|
warnOnUnsupportedTypeScriptVersion: false,
|
|
},
|
|
sourceType: 'module',
|
|
},
|
|
linterOptions: {
|
|
reportUnusedDisableDirectives: 'error',
|
|
reportUnusedInlineConfigs: 'error',
|
|
},
|
|
name: 'claudesidian/default',
|
|
plugins: {
|
|
'@typescript-eslint': tsEslint.plugin,
|
|
'check-file': checkFilePlugin,
|
|
'import': fixupPluginRules(importPlugin),
|
|
perfectionist,
|
|
},
|
|
rules: {
|
|
'@typescript-eslint/array-type': [autofix],
|
|
'@typescript-eslint/ban-ts-comment': [
|
|
'error',
|
|
{ minimumDescriptionLength: 10 },
|
|
],
|
|
'@typescript-eslint/ban-tslint-comment': [autofix],
|
|
'@typescript-eslint/consistent-generic-constructors': [autofix],
|
|
'@typescript-eslint/consistent-indexed-object-style': [autofix],
|
|
'@typescript-eslint/consistent-type-assertions': [autofix],
|
|
'@typescript-eslint/consistent-type-definitions': [autofix],
|
|
'@typescript-eslint/default-param-last': ['error'],
|
|
'@typescript-eslint/method-signature-style': [autofix, 'property'],
|
|
'@typescript-eslint/no-array-constructor': [autofix],
|
|
'@typescript-eslint/no-empty-function': ['error'],
|
|
'@typescript-eslint/no-empty-object-type': [
|
|
'error',
|
|
{ allowInterfaces: 'with-single-extends' },
|
|
],
|
|
'@typescript-eslint/no-explicit-any': ['error'],
|
|
'@typescript-eslint/no-extra-non-null-assertion': [autofix],
|
|
'@typescript-eslint/no-import-type-side-effects': [autofix],
|
|
'@typescript-eslint/no-inferrable-types': [autofix],
|
|
'@typescript-eslint/no-loop-func': ['error'],
|
|
'@typescript-eslint/no-misused-new': ['error'],
|
|
'@typescript-eslint/no-namespace': ['error'],
|
|
'@typescript-eslint/no-non-null-asserted-optional-chain': ['error'],
|
|
'@typescript-eslint/no-require-imports': ['error'],
|
|
'@typescript-eslint/no-this-alias': ['error'],
|
|
'@typescript-eslint/no-unnecessary-type-constraint': ['error'],
|
|
'@typescript-eslint/no-unsafe-declaration-merging': ['error'],
|
|
'@typescript-eslint/no-unsafe-function-type': ['error'],
|
|
'@typescript-eslint/no-unused-expressions': ['error'],
|
|
'@typescript-eslint/no-unused-vars': [
|
|
'error',
|
|
{
|
|
args: 'all',
|
|
argsIgnorePattern: '^_',
|
|
caughtErrors: 'all',
|
|
caughtErrorsIgnorePattern: '^_',
|
|
destructuredArrayIgnorePattern: '^_',
|
|
ignoreRestSiblings: false,
|
|
varsIgnorePattern: '^_',
|
|
},
|
|
],
|
|
'@typescript-eslint/no-useless-constructor': ['error'],
|
|
'@typescript-eslint/no-useless-empty-export': [autofix],
|
|
'@typescript-eslint/no-wrapper-object-types': [autofix],
|
|
'@typescript-eslint/prefer-as-const': [autofix],
|
|
'@typescript-eslint/prefer-for-of': ['error'],
|
|
'@typescript-eslint/prefer-function-type': [autofix],
|
|
'@typescript-eslint/prefer-literal-enum-member': ['error'],
|
|
'@typescript-eslint/prefer-namespace-keyword': [autofix],
|
|
'@typescript-eslint/triple-slash-reference': ['error'],
|
|
'check-file/filename-naming-convention': [
|
|
'error',
|
|
{ '**/*': 'KEBAB_CASE' },
|
|
{ ignoreMiddleExtensions: true },
|
|
],
|
|
'check-file/folder-naming-convention': [
|
|
'error',
|
|
{ '**/*': 'NEXT_JS_APP_ROUTER_CASE' },
|
|
{ ignoreMiddleExtensions: true },
|
|
],
|
|
'check-file/no-index': ['error', { ignoreMiddleExtensions: true }],
|
|
'constructor-super': ['error'],
|
|
'curly': [autofix, 'multi-line', 'consistent'],
|
|
'eqeqeq': [autofix, 'always', { null: 'ignore' }],
|
|
'for-direction': ['error'],
|
|
'getter-return': ['error'],
|
|
'import/enforce-node-protocol-usage': [autofix, 'always'],
|
|
'import/first': [autofix],
|
|
'import/newline-after-import': [autofix],
|
|
'import/no-default-export': ['error'],
|
|
'import/no-duplicates': [autofix],
|
|
'import/no-mutable-exports': ['error'],
|
|
'logical-assignment-operators': [autofix],
|
|
'no-async-promise-executor': ['error'],
|
|
'no-case-declarations': ['error'],
|
|
'no-class-assign': ['error'],
|
|
'no-compare-neg-zero': ['error'],
|
|
'no-cond-assign': ['error'],
|
|
'no-const-assign': ['error'],
|
|
'no-constant-binary-expression': ['error'],
|
|
'no-constant-condition': ['error'],
|
|
'no-control-regex': ['error'],
|
|
'no-debugger': ['error'],
|
|
'no-delete-var': ['error'],
|
|
'no-div-regex': [autofix],
|
|
'no-dupe-args': ['error'],
|
|
'no-dupe-else-if': ['error'],
|
|
'no-dupe-keys': ['error'],
|
|
'no-duplicate-case': ['error'],
|
|
'no-else-return': [autofix],
|
|
'no-empty': ['error'],
|
|
'no-empty-character-class': ['error'],
|
|
'no-empty-pattern': ['error'],
|
|
'no-empty-static-block': ['error'],
|
|
'no-ex-assign': ['error'],
|
|
'no-extra-bind': [autofix],
|
|
'no-extra-boolean-cast': [autofix],
|
|
'no-extra-label': [autofix],
|
|
'no-fallthrough': ['error', { commentPattern: 'no-fallthrough-ignore' }],
|
|
'no-func-assign': ['error'],
|
|
'no-global-assign': ['error'],
|
|
'no-implicit-coercion': [autofix, { allow: ['!!'] }],
|
|
'no-import-assign': ['error'],
|
|
'no-inner-declarations': ['error'],
|
|
'no-invalid-regexp': ['error'],
|
|
'no-irregular-whitespace': ['error'],
|
|
'no-lonely-if': [autofix],
|
|
'no-misleading-character-class': ['error'],
|
|
'no-new-native-nonconstructor': ['error'],
|
|
'no-nonoctal-decimal-escape': ['error'],
|
|
'no-obj-calls': ['error'],
|
|
'no-octal': ['error'],
|
|
'no-prototype-builtins': ['error'],
|
|
'no-regex-spaces': [autofix],
|
|
'no-self-assign': ['error'],
|
|
'no-setter-return': ['error'],
|
|
'no-shadow-restricted-names': ['error'],
|
|
'no-sparse-arrays': ['error'],
|
|
'no-template-curly-in-string': ['error'],
|
|
'no-this-before-super': ['error'],
|
|
'no-unassigned-vars': ['error'],
|
|
'no-undef': ['error'],
|
|
'no-undef-init': [autofix],
|
|
'no-unexpected-multiline': ['error'],
|
|
'no-unneeded-ternary': [autofix],
|
|
'no-unreachable': ['error'],
|
|
'no-unsafe-finally': ['error'],
|
|
'no-unsafe-negation': ['error'],
|
|
'no-unsafe-optional-chaining': ['error'],
|
|
'no-unused-labels': [autofix],
|
|
'no-unused-private-class-members': ['error'],
|
|
'no-useless-assignment': ['error'],
|
|
'no-useless-backreference': ['error'],
|
|
'no-useless-catch': ['error'],
|
|
'no-useless-computed-key': [autofix],
|
|
'no-useless-escape': ['error'],
|
|
'no-useless-rename': [autofix],
|
|
'no-useless-return': [autofix],
|
|
'no-var': [autofix],
|
|
'no-with': ['error'],
|
|
'object-shorthand': [autofix],
|
|
'one-var': [autofix, 'never'],
|
|
'operator-assignment': [autofix],
|
|
'perfectionist/sort-array-includes': [autofix],
|
|
'perfectionist/sort-classes': [autofix],
|
|
'perfectionist/sort-decorators': [autofix],
|
|
'perfectionist/sort-enums': [autofix],
|
|
'perfectionist/sort-exports': [autofix],
|
|
'perfectionist/sort-heritage-clauses': [autofix],
|
|
'perfectionist/sort-imports': [autofix],
|
|
'perfectionist/sort-interfaces': [autofix],
|
|
'perfectionist/sort-intersection-types': [autofix],
|
|
'perfectionist/sort-jsx-props': [autofix],
|
|
'perfectionist/sort-maps': [autofix],
|
|
'perfectionist/sort-modules': [autofix],
|
|
'perfectionist/sort-named-exports': [autofix],
|
|
'perfectionist/sort-named-imports': [autofix],
|
|
'perfectionist/sort-object-types': [autofix],
|
|
'perfectionist/sort-objects': [autofix],
|
|
'perfectionist/sort-sets': [autofix],
|
|
'perfectionist/sort-switch-case': [autofix],
|
|
'perfectionist/sort-union-types': [autofix],
|
|
'prefer-const': [autofix],
|
|
'prefer-exponentiation-operator': [autofix],
|
|
'prefer-numeric-literals': [autofix],
|
|
'prefer-object-has-own': [autofix],
|
|
'prefer-object-spread': [autofix],
|
|
'prefer-template': [autofix],
|
|
'radix': ['error'],
|
|
'require-yield': ['error'],
|
|
'unicode-bom': [autofix],
|
|
'use-isnan': ['error'],
|
|
'valid-typeof': ['error'],
|
|
'yoda': [autofix],
|
|
},
|
|
settings: {
|
|
perfectionist: {
|
|
partitionByComment: true,
|
|
type: 'natural',
|
|
},
|
|
},
|
|
},
|
|
|
|
// Files that require default exports
|
|
{
|
|
files: [
|
|
'**/*config.*',
|
|
'**/global-error.tsx',
|
|
'**/error.tsx',
|
|
'**/layout.tsx',
|
|
'**/loading.tsx',
|
|
'**/middleware.ts',
|
|
'**/page.tsx',
|
|
'**/not-found.tsx',
|
|
],
|
|
name: 'claudesidian/disable-default-export',
|
|
rules: {
|
|
'import/no-default-export': 'off',
|
|
},
|
|
},
|
|
|
|
// Typed rules
|
|
{
|
|
files: ['**/*.ts', '**/*.tsx'],
|
|
languageOptions: {
|
|
parserOptions: {
|
|
projectService: true,
|
|
tsconfigRootDir: path.join(__dirname, '..'),
|
|
},
|
|
},
|
|
name: 'claudesidian/typed',
|
|
plugins: { tsEslint: tsEslint.plugin },
|
|
rules: {
|
|
'@typescript-eslint/await-thenable': ['error'],
|
|
'@typescript-eslint/consistent-type-exports': [autofix],
|
|
'@typescript-eslint/consistent-type-imports': [
|
|
autofix,
|
|
{ fixStyle: 'inline-type-imports' },
|
|
],
|
|
'@typescript-eslint/dot-notation': [autofix],
|
|
'@typescript-eslint/explicit-member-accessibility': [
|
|
autofix,
|
|
{ overrides: { constructors: 'no-public' } },
|
|
],
|
|
'@typescript-eslint/no-array-delete': ['error'],
|
|
'@typescript-eslint/no-base-to-string': ['error'],
|
|
'@typescript-eslint/no-confusing-void-expression': [autofix],
|
|
'@typescript-eslint/no-deprecated': ['error'],
|
|
'@typescript-eslint/no-duplicate-enum-values': ['error'],
|
|
'@typescript-eslint/no-duplicate-type-constituents': [autofix],
|
|
'@typescript-eslint/no-dynamic-delete': [autofix],
|
|
'@typescript-eslint/no-extraneous-class': ['error'],
|
|
'@typescript-eslint/no-floating-promises': ['error'],
|
|
'@typescript-eslint/no-for-in-array': ['error'],
|
|
'@typescript-eslint/no-implied-eval': ['error'],
|
|
'@typescript-eslint/no-invalid-void-type': ['error'],
|
|
'@typescript-eslint/no-meaningless-void-operator': [autofix],
|
|
'@typescript-eslint/no-misused-promises': [
|
|
'error',
|
|
{ checksVoidReturn: false },
|
|
],
|
|
'@typescript-eslint/no-misused-spread': ['error'],
|
|
'@typescript-eslint/no-mixed-enums': ['error'],
|
|
'@typescript-eslint/no-non-null-asserted-nullish-coalescing': ['error'],
|
|
'@typescript-eslint/no-non-null-assertion': ['error'],
|
|
'@typescript-eslint/no-redundant-type-constituents': ['error'],
|
|
'@typescript-eslint/no-unnecessary-boolean-literal-compare': [autofix],
|
|
'@typescript-eslint/no-unnecessary-condition': ['error'],
|
|
'@typescript-eslint/no-unnecessary-qualifier': [autofix],
|
|
'@typescript-eslint/no-unnecessary-template-expression': [autofix],
|
|
'@typescript-eslint/no-unnecessary-type-arguments': [autofix],
|
|
'@typescript-eslint/no-unnecessary-type-assertion': [autofix],
|
|
'@typescript-eslint/no-unnecessary-type-conversion': ['error'],
|
|
'@typescript-eslint/no-unnecessary-type-parameters': ['error'],
|
|
'@typescript-eslint/no-unsafe-argument': ['error'],
|
|
'@typescript-eslint/no-unsafe-assignment': ['error'],
|
|
'@typescript-eslint/no-unsafe-call': ['error'],
|
|
'@typescript-eslint/no-unsafe-enum-comparison': ['error'],
|
|
'@typescript-eslint/no-unsafe-member-access': ['error'],
|
|
'@typescript-eslint/no-unsafe-return': ['error'],
|
|
'@typescript-eslint/no-unsafe-type-assertion': ['error'],
|
|
'@typescript-eslint/no-unsafe-unary-minus': ['error'],
|
|
'@typescript-eslint/non-nullable-type-assertion-style': [autofix],
|
|
'@typescript-eslint/only-throw-error': ['error'],
|
|
'@typescript-eslint/prefer-destructuring': [autofix, { array: false }],
|
|
'@typescript-eslint/prefer-find': ['error'],
|
|
'@typescript-eslint/prefer-includes': [autofix],
|
|
'@typescript-eslint/prefer-nullish-coalescing': [
|
|
'error',
|
|
{ ignorePrimitives: { string: true } },
|
|
],
|
|
'@typescript-eslint/prefer-optional-chain': [autofix],
|
|
'@typescript-eslint/prefer-promise-reject-errors': ['error'],
|
|
'@typescript-eslint/prefer-readonly': [autofix],
|
|
'@typescript-eslint/prefer-reduce-type-parameter': [autofix],
|
|
'@typescript-eslint/prefer-regexp-exec': [autofix],
|
|
'@typescript-eslint/prefer-return-this-type': [autofix],
|
|
'@typescript-eslint/prefer-string-starts-ends-with': [autofix],
|
|
'@typescript-eslint/promise-function-async': [autofix],
|
|
'@typescript-eslint/related-getter-setter-pairs': ['error'],
|
|
'@typescript-eslint/require-array-sort-compare': ['error'],
|
|
'@typescript-eslint/require-await': ['error'],
|
|
'@typescript-eslint/restrict-plus-operands': ['error'],
|
|
'@typescript-eslint/restrict-template-expressions': ['error'],
|
|
'@typescript-eslint/return-await': [autofix],
|
|
'@typescript-eslint/switch-exhaustiveness-check': ['error'],
|
|
'@typescript-eslint/unbound-method': ['error'],
|
|
'@typescript-eslint/unified-signatures': ['error'],
|
|
'@typescript-eslint/use-unknown-in-catch-callback-variable': ['error'],
|
|
},
|
|
},
|
|
|
|
// Node environment
|
|
{
|
|
files: ['**/*.ts', '**/*.js', '**/*.mjs'],
|
|
languageOptions: { globals: globals.nodeBuiltin },
|
|
name: 'claudesidian/node',
|
|
},
|
|
|
|
// App-specific rules
|
|
]
|