Files
noitu/web/eslint.config.js
T
tiennm99 90cd679639 feat(web): state the rules, reach the chat from the top of the board, lint the tree
A /rules page says, in one place, what nothing in the app said before:
the chain rule, the clock, what a dead end costs, elimination and the last
player standing, how a word is scored and the reconnect window. Linked
from the landing page and from the board and lobby headers.

The chat control moves above the chain as a pill with the unread count,
where it can be reached on a phone mid-game, and the lobby's folded chat
now carries an unread badge too.

ESLint with the Svelte and JSDoc plugins, run in CI; the real findings
it turned up (missing each keys, untyped timer handles) are fixed.
2026-09-21 01:17:52 +07:00

79 lines
2.9 KiB
JavaScript

import js from '@eslint/js';
import jsdoc from 'eslint-plugin-jsdoc';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
/**
* Flat config. Type-checking already lives in `svelte-check` via the JSDoc
* annotations in `jsconfig.json`'s `checkJs`, so this is style and correctness
* only — there is no TypeScript project for a type-aware rule set to attach
* to.
*
* `src/lib/proto/` is generated by `buf` from `proto/noitu/v1/game.proto` and
* committed as-is; linting it would flag code nobody here is meant to edit.
*/
export default [
{
ignores: ['build/**', '.svelte-kit/**', 'static/**', 'src/lib/proto/**']
},
js.configs.recommended,
...svelte.configs['flat/recommended'],
jsdoc.configs['flat/recommended-typescript-flavor'],
{
languageOptions: {
ecmaVersion: 2024,
sourceType: 'module',
globals: {
...globals.browser
}
}
},
{
// The build config, the test config and everything under test/ and e2e/
// run under Node rather than in a browser.
files: ['*.config.js', 'tests/**/*.js', 'e2e/**/*.js'],
languageOptions: {
globals: {
...globals.node
}
}
},
{
rules: {
// The word field and the chat field are deliberately uncontrolled —
// see WordInput.svelte and ChatPanel.svelte — so an unused event
// parameter kept for its shape (a composition handler ignoring its
// event, say) is a documented choice, not dead code. Leading
// underscore still flags a genuine oversight.
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
// This app has no base path — adapter-static builds to the root the
// Go binary serves everything from — and several of its own links
// carry a query string built at the call site (`/play?difficulty=`,
// `/online?code=`), a shape the rule does not recognise as resolved.
// Adopting resolve() here would be for a base path this app will
// never have, working around a limitation in exactly the links this
// app uses.
'svelte/no-navigation-without-resolve': 'off',
// require-jsdoc and the param/returns completeness rules assume
// per-parameter @param/@returns prose; this codebase instead types a
// function's inputs with one @type {{ ... }} object-shape block
// (see any component's props, e.g. GameBoard.svelte) and skips a
// comment on a name that already says what it is. Turning these off
// keeps the rules that check what is actually written — tag names,
// param names, and no bare `any` — without demanding a second prose
// copy of every signature already typed.
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-param': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/require-param-type': 'off',
'jsdoc/require-property': 'off',
'jsdoc/require-property-description': 'off',
'jsdoc/require-returns': 'off',
'jsdoc/require-returns-description': 'off',
'jsdoc/require-returns-type': 'off'
}
}
];