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' } } ];