liseur-desktop/eslint.config.js
Chmouel Boudjnah 09f57aa46e
chore: check more than formatting before code leaves the machine
The hooks ran `pnpm format:check` on push and nothing else, which let a
change that does not compile, does not lint or does not pass its tests
get all the way to CI before anyone heard about it.

Now there are two passes. Committing runs the checks that answer in a
couple of seconds — formatting, lint, and a guard against a test left
focused with `.only`, which is how a whole test file quietly stops
being a test file. Pushing runs those again, so a commit made with
--no-verify still has to face them, and adds the types and the unit
tests. That is the half of CI that needs neither the network nor a
build; what is left to fail on GitHub is `pnpm build` and the
end-to-end suite.

The configuration moves to the name pre-commit looks for by itself, so
installing it no longer needs flags, and it names both hook types it
wants. Run `pre-commit install` once more after pulling this.

While writing the lint hook: the renderer's ban on Node builtins was
documented but never enforced — only `electron` was. The restriction
now says so, and applies to the renderer and to shared code rather
than to everything with an exception list, which is what it always
meant.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-12 20:35:07 +02:00

64 lines
1.8 KiB
JavaScript

import js from '@eslint/js'
import tseslint from 'typescript-eslint'
export default tseslint.config(
{
ignores: ['out/', 'dist/', 'release/', 'node_modules/', 'playwright-report/', 'test-results/'],
},
js.configs.recommended,
...tseslint.configs.recommended,
{
rules: {
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/consistent-type-imports': 'error',
},
},
{
// A plain Node script, deliberately free of dependencies — which includes
// not pulling in `globals` just to name three of them.
files: ['scripts/**/*.mjs'],
languageOptions: {
globals: {
console: 'readonly',
fetch: 'readonly',
process: 'readonly',
},
},
},
{
// The renderer runs in a browser with no Node and no electron: it reaches
// the outside world only through the preload API. Shared code is held to
// the same rule, because the renderer imports it. Everything else here —
// main, preload, worker, tests, scripts — is Node-side and unrestricted.
files: ['src/renderer/**', 'src/shared/**'],
rules: {
'no-restricted-imports': [
'error',
{
paths: [
{
name: 'electron',
message: 'Only main/preload may import electron. Renderer must use window.liseur.',
},
],
patterns: [
{
group: [
'node:*',
'fs',
'fs/*',
'path',
'os',
'crypto',
'child_process',
'worker_threads',
],
message:
'Only main/preload/worker may use Node builtins. Renderer must use window.liseur.',
},
],
},
],
},
},
)