Skip to content

Commit 6bb9524

Browse files
committed
update husky setup, migrate to eslint flat config
1 parent ad3623a commit 6bb9524

File tree

8 files changed

+261
-755
lines changed

8 files changed

+261
-755
lines changed

.eslintrc.json

Lines changed: 0 additions & 97 deletions
This file was deleted.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ src/ui/next-env.d.ts
220220
# Root-level UI config files that should be tracked
221221
!package.json
222222
!package-lock.json
223-
!.eslintrc.json
224223
!tsconfig.json
225224
!tsconfig.*.json
226225
!src/ui/lib
227226
!src/ui/public/manifest.json
227+
.eslintcache

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx lint-staged

.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
!tests/ui/**/*.json
1313

1414
# Root-level configs to format
15-
!/.eslintrc.json
15+
!/.eslint.config.js
1616
!/tsconfig*.json
1717
!/*.config.{js,ts}
1818
!/jest.setup.ts

eslint.config.js

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// @ts-check
2+
3+
import eslint from '@eslint/js';
4+
import typescriptPlugin from '@typescript-eslint/eslint-plugin';
5+
import typescriptParser from '@typescript-eslint/parser';
6+
import { FlatCompat } from '@eslint/eslintrc';
7+
import reactPlugin from 'eslint-plugin-react';
8+
import hooksPlugin from 'eslint-plugin-react-hooks';
9+
import importPlugin from 'eslint-plugin-import';
10+
import jestPlugin from 'eslint-plugin-jest';
11+
import noSecretsPlugin from 'eslint-plugin-no-secrets';
12+
import prettierPlugin from 'eslint-plugin-prettier';
13+
import prettierConfig from 'eslint-config-prettier';
14+
import globals from 'globals';
15+
import path from 'node:path';
16+
import { fileURLToPath } from 'node:url';
17+
18+
const __filename = fileURLToPath(import.meta.url);
19+
const __dirname = path.dirname(__filename);
20+
21+
const compat = new FlatCompat({
22+
baseDirectory: __dirname,
23+
recommendedConfig: eslint.configs.recommended,
24+
});
25+
26+
export default [
27+
// Base configuration
28+
eslint.configs.recommended,
29+
30+
// Next.js configuration using FlatCompat
31+
...compat.extends('next/core-web-vitals'),
32+
33+
// --- Main Configuration for your files ---
34+
{
35+
files: ['src/**/*.{js,jsx,ts,tsx}', 'tests/**/*.{js,jsx,ts,tsx}'],
36+
languageOptions: {
37+
parser: typescriptParser,
38+
ecmaVersion: 2024,
39+
sourceType: 'module',
40+
globals: {
41+
...globals.browser,
42+
...globals.node,
43+
...globals.jest,
44+
},
45+
parserOptions: {
46+
ecmaFeatures: {
47+
jsx: true,
48+
},
49+
project: [
50+
'./src/ui/tsconfig.json',
51+
'./tsconfig.test.json',
52+
'./tsconfig.cypress.json',
53+
],
54+
tsconfigRootDir: import.meta.dirname,
55+
noWarnOnMultipleProjects: true,
56+
},
57+
},
58+
plugins: {
59+
'@typescript-eslint': typescriptPlugin,
60+
react: reactPlugin,
61+
'react-hooks': hooksPlugin,
62+
import: importPlugin,
63+
jest: jestPlugin,
64+
'no-secrets': noSecretsPlugin,
65+
prettier: prettierPlugin,
66+
},
67+
rules: {
68+
// Your custom rules
69+
complexity: ['warn', { max: 8 }],
70+
curly: ['error', 'all'],
71+
'no-unused-vars': 'off',
72+
73+
// TypeScript rules
74+
'@typescript-eslint/no-unused-vars': [
75+
'warn',
76+
{
77+
argsIgnorePattern: '^_',
78+
varsIgnorePattern: '^_',
79+
caughtErrorsIgnorePattern: '^_',
80+
},
81+
],
82+
'@typescript-eslint/no-explicit-any': 'warn',
83+
84+
// Next.js overrides (these will override the ones from next/core-web-vitals)
85+
'@next/next/no-img-element': 'off', // Allow img tags if needed
86+
'@next/next/no-page-custom-font': 'warn',
87+
88+
// React rules
89+
'react/react-in-jsx-scope': 'off', // Not needed in Next.js
90+
'react/prop-types': 'off', // Using TypeScript
91+
'react-hooks/rules-of-hooks': 'error',
92+
'react-hooks/exhaustive-deps': 'warn',
93+
94+
// Import rules
95+
'import/no-extraneous-dependencies': [
96+
'error',
97+
{
98+
devDependencies: [
99+
'**/*.test.{js,jsx,ts,tsx}',
100+
'**/*.d.ts',
101+
'**/*.interfaces.ts',
102+
'**/*.setup.{js,ts}',
103+
'**/*.config.{js,mjs,ts}',
104+
'tests/**/*',
105+
'cypress/**/*',
106+
],
107+
optionalDependencies: false,
108+
peerDependencies: false,
109+
},
110+
],
111+
'import/order': [
112+
'error',
113+
{
114+
groups: [
115+
['builtin', 'external'],
116+
['internal', 'parent', 'sibling', 'index'],
117+
],
118+
'newlines-between': 'always-and-inside-groups',
119+
pathGroups: [
120+
{
121+
pattern:
122+
'@{app,assets,classes,components,hooks,lib,pages,store,tests,types,utils}/**',
123+
group: 'internal',
124+
position: 'before',
125+
},
126+
{
127+
pattern: '{.,..}/**',
128+
group: 'internal',
129+
position: 'after',
130+
},
131+
],
132+
pathGroupsExcludedImportTypes: ['builtin'],
133+
alphabetize: { order: 'asc', caseInsensitive: true },
134+
},
135+
],
136+
137+
// Security
138+
'no-secrets/no-secrets': ['error', { additionalRegexes: {}, ignoreContent: [] }],
139+
140+
// Prettier
141+
'prettier/prettier': 'error',
142+
},
143+
settings: {
144+
next: {
145+
rootDir: ['src/ui/', 'tests/ui/'],
146+
},
147+
'import/resolver': {
148+
typescript: {
149+
project: [
150+
'./src/ui/tsconfig.json',
151+
'./tsconfig.test.json',
152+
'./tsconfig.cypress.json',
153+
],
154+
noWarnOnMultipleProjects: true,
155+
},
156+
},
157+
react: {
158+
version: 'detect',
159+
},
160+
},
161+
},
162+
163+
// Jest-specific rules for test files
164+
{
165+
files: [
166+
'tests/**/*.{js,jsx,ts,tsx}',
167+
'**/*.test.{js,jsx,ts,tsx}',
168+
'**/*.spec.{js,jsx,ts,tsx}',
169+
],
170+
rules: {
171+
'jest/expect-expect': 'error',
172+
'jest/no-focused-tests': 'error',
173+
'jest/no-identical-title': 'error',
174+
'jest/prefer-to-have-length': 'warn',
175+
'jest/valid-expect': 'error',
176+
},
177+
},
178+
179+
// Prettier config (disables conflicting rules)
180+
prettierConfig,
181+
];

0 commit comments

Comments
 (0)