From 05735eb55da1586b83f9718466085fc86ec80ff4 Mon Sep 17 00:00:00 2001 From: Matiss Janis Aboltins Date: Thu, 18 Dec 2025 23:53:46 +0000 Subject: [PATCH] Lint: simplify ESLint config and add oxlint configuration (#6443) * Simplify ESLint config and add oxlint configuration - Switch from typescript-eslint recommended to base config - Remove redundant TypeScript-specific rules that are handled by base config - Add oxlint configuration with appropriate rules - Simplify globals configuration using globals package - Add coverage directory to ESLint ignores - Clean up various TypeScript rule configurations * Add release notes for PR #6443 * [autofix.ci] apply automated fixes * Refactor release note generator and update CLI argument parsing - Adjusted the release note generator to fix string formatting. - Refactored CLI argument parsing in migrate/cli.ts to use parseSync for improved clarity and consistency. --------- Co-authored-by: github-actions[bot] Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .oxlintrc.json | 117 ++++++++++++- bin/release-note-generator.ts | 3 +- eslint.config.mjs | 162 ++---------------- package.json | 1 - packages/component-library/src/styles.ts | 4 +- packages/crdt/src/index.ts | 2 +- packages/crdt/src/proto/sync_pb.ts | 2 +- packages/desktop-client/globals.ts | 4 +- .../src/components/filters/FiltersMenu.tsx | 2 +- .../transactions/TransactionsTable.test.tsx | 2 +- packages/desktop-client/src/index.tsx | 2 +- packages/desktop-client/src/util/markdown.ts | 2 +- packages/desktop-client/vite.config.mts | 2 +- .../src/platform/server/fs/index.electron.ts | 2 +- packages/loot-core/src/server/accounts/app.ts | 2 +- packages/loot-core/src/server/aql/exec.ts | 2 +- .../loot-core/src/server/cloud-storage.ts | 2 +- packages/loot-core/src/server/db/index.ts | 4 +- packages/loot-core/src/server/errors.ts | 2 +- packages/loot-core/src/server/migrate/cli.ts | 42 +++-- .../src/server/sync/sync.property.test.ts | 2 +- .../transactions/import/parse-file.test.ts | 2 +- packages/loot-core/src/shared/async.ts | 2 +- .../loot-core/src/shared/platform.electron.ts | 2 +- .../loot-core/src/types/server-handlers.ts | 2 +- packages/loot-core/src/types/util.ts | 2 +- upcoming-release-notes/6443.md | 6 + yarn.lock | 3 +- 28 files changed, 187 insertions(+), 195 deletions(-) create mode 100644 upcoming-release-notes/6443.md diff --git a/.oxlintrc.json b/.oxlintrc.json index cac1941947..ed43589a40 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,6 +1,17 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", "plugins": ["react", "typescript", "import", "jsx-a11y"], + "env": { + "browser": true, + "jest": true, + "node": true + }, + "globals": { + "vi": "readonly", + "backend": "readonly", + "importScripts": "readonly", + "FS": "readonly" // TODO: remove this + }, "rules": { // TODO fix all these and re-enable "jsx-a11y/click-events-have-key-events": "off", @@ -11,7 +22,45 @@ "no-var": "warn", // JSX A11y rules - "jsx-a11y/no-autofocus": ["warn", { "ignoreNonDOM": true }], + "jsx-a11y/no-autofocus": [ + "warn", + { + "ignoreNonDOM": true + } + ], + + // Typescript rules + "typescript/ban-ts-comment": [ + "warn", + { + // TODO: remove this + "ts-ignore": "allow-with-description" + } + ], + "typescript/consistent-type-definitions": ["warn", "type"], + "typescript/consistent-type-imports": [ + "warn", + { + "prefer": "type-imports", + "fixStyle": "inline-type-imports" + } + ], + "typescript/no-explicit-any": "warn", + "typescript/no-restricted-types": [ + "warn", + { + "types": { + // forbid FC as superfluous + "FunctionComponent": { + "message": "Type the props argument and let TS infer or use ComponentType for a component prop" + }, + "FC": { + "message": "Type the props argument and let TS infer or use ComponentType for a component prop" + } + } + } + ], + "typescript/no-var-requires": "warn", // Import rules "import/first": "error", @@ -65,6 +114,14 @@ "react/style-prop-object": "warn", // ESLint rules + "eslint/default-case": [ + "warn", + { + "commentPattern": "^no default$" + } + ], + "eslint/no-array-constructor": "warn", + // "eslint/no-empty-function": "warn", // TODO: enable this "eslint/no-redeclare": "warn", "eslint/no-regex-spaces": "warn", "eslint/no-restricted-globals": [ @@ -175,7 +232,10 @@ } ] } - ] + ], + "eslint/no-useless-constructor": "warn", + "eslint/no-undef": "warn", + "eslint/no-unused-expressions": "warn" }, "overrides": [ { @@ -230,7 +290,6 @@ "react/exhaustive-deps": "off" } }, - { "files": [ "packages/api/migrations/*", @@ -241,6 +300,58 @@ "rules": { "import/no-default-export": "off" } + }, + // TODO: enable these + { + "files": [ + "packages/api/**", + "packages/component-library/**", + "packages/crdt/**", + "packages/desktop-electron/**", + "packages/desktop-client/vite.config.mts", + "packages/loot-core/**", + "packages/sync-server/**" + ], + "rules": { + "typescript/consistent-type-imports": "off" + } + }, + { + "files": [ + "packages/api/**", + "packages/component-library/**", + "packages/loot-core/src/server/**", + "packages/loot-core/src/types/**", + "packages/sync-server/**", + "packages/loot-core/typings/window.ts" + ], + "rules": { + "typescript/consistent-type-definitions": "off" + } + }, + { + "files": [ + "packages/desktop-client/src/components/budget/envelope/budgetsummary/BudgetMonthMenu.tsx", + "packages/desktop-client/src/components/budget/tracking/budgetsummary/BudgetMonthMenu.tsx", + "packages/desktop-client/src/components/HelpMenu.tsx", + "packages/desktop-client/src/components/mobile/budget/CategoryGroupActionMenu.tsx", + "packages/desktop-client/src/components/modals/SelectLinkedAccountsModal.tsx", + "packages/desktop-client/src/components/reports/Overview.tsx", + "packages/desktop-client/src/components/reports/reports/CustomReport.tsx", + "packages/desktop-client/src/components/reports/reports/CustomReportListCards.tsx", + "packages/desktop-client/src/components/reports/reports/MissingReportCard.tsx", + "packages/desktop-client/src/components/reports/util.ts", + "packages/desktop-client/src/components/sidebar/Account.tsx", + "packages/desktop-client/src/hooks/useSplitsExpanded.tsx", + "packages/loot-core/src/server/budget/category-template-context.ts", + "packages/loot-core/src/server/budget/schedule-template.ts", + "packages/loot-core/src/server/importers/ynab5.ts", + "packages/loot-core/src/server/rules/action.ts", + "packages/loot-core/src/shared/schedules.ts" + ], + "rules": { + "eslint/default-case": "off" + } } ] } diff --git a/bin/release-note-generator.ts b/bin/release-note-generator.ts index 4a0395241e..beb106375f 100644 --- a/bin/release-note-generator.ts +++ b/bin/release-note-generator.ts @@ -161,8 +161,7 @@ category: ${type} authors: [${username}] --- -${summary} -`; +${summary}`; } // simple exec that fails silently and returns an empty string on failure diff --git a/eslint.config.mjs b/eslint.config.mjs index fcd966dd1c..ba85f43252 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,4 +1,3 @@ -import tsParser from '@typescript-eslint/parser'; import pluginJSXA11y from 'eslint-plugin-jsx-a11y'; import oxlint from 'eslint-plugin-oxlint'; import pluginPerfectionist from 'eslint-plugin-perfectionist'; @@ -29,6 +28,7 @@ export default defineConfig( 'packages/desktop-electron/client-build/', 'packages/loot-core/**/lib-dist/*', 'packages/loot-core/**/proto/*', + 'packages/sync-server/coverage/', 'packages/sync-server/user-files/', 'packages/sync-server/server-files/', '.yarn/*', @@ -46,15 +46,8 @@ export default defineConfig( ], languageOptions: { globals: { + ...globals.jest, vi: true, - describe: true, - expect: true, - it: true, - beforeAll: true, - beforeEach: true, - afterAll: true, - afterEach: true, - test: true, }, }, }, @@ -67,8 +60,23 @@ export default defineConfig( ...globals.browser, ...globals.commonjs, ...globals.node, + ...globals.jest, globalThis: false, vi: true, + + RequestInfo: true, + RequestInit: true, + ParentNode: true, + FS: true, + IDBValidKey: true, + NodeJS: true, + Electron: true, + + // Worker globals + FetchEvent: true, + ExtendableEvent: true, + ExtendableMessageEvent: true, + ServiceWorkerGlobalScope: true, }, }, settings: { @@ -83,7 +91,7 @@ export default defineConfig( }, }, }, - pluginTypescript.configs.recommended, + pluginTypescript.configs.base, { plugins: { actual: pluginActual, @@ -103,13 +111,6 @@ export default defineConfig( // http://eslint.org/docs/rules/ 'array-callback-return': 'warn', - 'default-case': [ - 'warn', - { - commentPattern: '^no default$', - }, - ], - curly: ['warn', 'multi-line', 'consistent'], eqeqeq: ['warn', 'smart'], 'no-array-constructor': 'warn', @@ -292,18 +293,6 @@ export default defineConfig( 'actual/prefer-if-statement': 'warn', 'actual/prefer-logger-over-console': 'error', - // Note: base rule explicitly disabled in favor of the TS one - 'no-unused-vars': 'off', - '@typescript-eslint/no-unused-vars': [ - 'warn', - { - varsIgnorePattern: '^(_|React)', - argsIgnorePattern: '^(_|React)', - ignoreRestSiblings: true, - caughtErrors: 'none', - }, - ], - // https://github.com/eslint/eslint/issues/16954 // https://github.com/eslint/eslint/issues/16953 'no-loop-func': 'off', @@ -326,79 +315,9 @@ export default defineConfig( }, ], - '@typescript-eslint/ban-ts-comment': [ - 'error', - { - 'ts-ignore': 'allow-with-description', - }, - ], - // Rules disabled during TS migration - '@typescript-eslint/no-var-requires': 'off', 'prefer-const': 'warn', 'prefer-spread': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-require-imports': 'off', - }, - }, - { - files: ['**/*.{ts,tsx}'], - - languageOptions: { - parser: tsParser, - ecmaVersion: 2018, - sourceType: 'module', - - parserOptions: { - projectService: true, - ecmaFeatures: { - jsx: true, - }, - - // typescript-eslint specific options - warnOnUnsupportedTypeScriptVersion: true, - }, - }, - - // If adding a typescript-eslint version of an existing ESLint rule, - // make sure to disable the ESLint rule here. - rules: { - // TypeScript's `noFallthroughCasesInSwitch` option is more robust (#6906) - 'default-case': 'off', - // 'tsc' already handles this (https://github.com/typescript-eslint/typescript-eslint/issues/291) - 'no-dupe-class-members': 'off', - // 'tsc' already handles this (https://github.com/typescript-eslint/typescript-eslint/issues/477) - 'no-undef': 'off', - - // Add TypeScript specific rules (and turn off ESLint equivalents) - '@typescript-eslint/consistent-type-assertions': 'warn', - 'no-array-constructor': 'off', - '@typescript-eslint/no-array-constructor': 'warn', - 'no-use-before-define': 'off', - - '@typescript-eslint/no-use-before-define': [ - 'warn', - { - functions: false, - classes: false, - variables: false, - typedefs: false, - }, - ], - - 'no-unused-expressions': 'off', - - '@typescript-eslint/no-unused-expressions': [ - 'error', - { - allowShortCircuit: true, - allowTernary: true, - allowTaggedTemplates: true, - }, - ], - - 'no-useless-constructor': 'off', - '@typescript-eslint/no-useless-constructor': 'warn', }, }, { @@ -414,40 +333,6 @@ export default defineConfig( 'typescript-paths/absolute-import': ['error', { enableAlias: false }], }, }, - { - files: [ - 'packages/desktop-client/**/*.{ts,tsx}', - 'packages/loot-core/src/client/**/*.{ts,tsx}', - ], - rules: { - // enforce import type - '@typescript-eslint/consistent-type-imports': [ - 'warn', - { - prefer: 'type-imports', - fixStyle: 'inline-type-imports', - }, - ], - - '@typescript-eslint/no-restricted-types': [ - 'warn', - { - types: { - // forbid FC as superfluous - FunctionComponent: { - message: - 'Type the props argument and let TS infer or use ComponentType for a component prop', - }, - - FC: { - message: - 'Type the props argument and let TS infer or use ComponentType for a component prop', - }, - }, - }, - ], - }, - }, { files: [ 'eslint.config.mjs', @@ -472,17 +357,6 @@ export default defineConfig( 'no-restricted-syntax': 'off', }, }, - { - files: [ - 'packages/desktop-client/**/*.{ts,tsx}', - 'packages/loot-core/src/client/**/*.{ts,tsx}', - ], - ignores: ['**/**/globals.d.ts'], - rules: { - // enforce type over interface - '@typescript-eslint/consistent-type-definitions': ['warn', 'type'], - }, - }, { files: ['packages/sync-server/**/*'], // TODO: fix the issues in these files diff --git a/package.json b/package.json index dc1a01e25b..0a81b5d982 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,6 @@ "@octokit/rest": "^22.0.1", "@types/node": "^22.19.1", "@types/prompts": "^2.4.9", - "@typescript-eslint/parser": "^8.46.4", "cross-env": "^10.1.0", "eslint": "^9.39.2", "eslint-import-resolver-typescript": "^4.4.4", diff --git a/packages/component-library/src/styles.ts b/packages/component-library/src/styles.ts index 1e9613b583..c30b2a6e9c 100644 --- a/packages/component-library/src/styles.ts +++ b/packages/component-library/src/styles.ts @@ -3,7 +3,7 @@ import { keyframes } from '@emotion/css'; import { theme } from './theme'; import { tokens } from './tokens'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// oxlint-disable-next-line typescript/no-explicit-any export type CSSProperties = Record; const MOBILE_MIN_HEIGHT = 40; @@ -12,7 +12,7 @@ const shadowLarge = { boxShadow: '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)', }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// oxlint-disable-next-line typescript/no-explicit-any export const styles: Record = { incomeHeaderHeight: 70, cardShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)', diff --git a/packages/crdt/src/index.ts b/packages/crdt/src/index.ts index bfe5f0b55f..225262f1d7 100644 --- a/packages/crdt/src/index.ts +++ b/packages/crdt/src/index.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ +/* oxlint-disable typescript/no-explicit-any */ import './proto/sync_pb.js'; // Import for side effects export { diff --git a/packages/crdt/src/proto/sync_pb.ts b/packages/crdt/src/proto/sync_pb.ts index c281285cd8..be8e0b2923 100644 --- a/packages/crdt/src/proto/sync_pb.ts +++ b/packages/crdt/src/proto/sync_pb.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/no-namespace */ +/* oxlint-disable typescript/no-namespace */ // package: // file: sync.proto diff --git a/packages/desktop-client/globals.ts b/packages/desktop-client/globals.ts index 4f43f09a75..7140ff7774 100644 --- a/packages/desktop-client/globals.ts +++ b/packages/desktop-client/globals.ts @@ -6,9 +6,9 @@ declare module '*.png'; declare global { function __resetWorld(): void; - // eslint-disable-next-line @typescript-eslint/no-namespace + // oxlint-disable-next-line typescript/no-namespace namespace PlaywrightTest { - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + // oxlint-disable-next-line typescript/consistent-type-definitions interface Matchers { toMatchThemeScreenshots(): Promise; } diff --git a/packages/desktop-client/src/components/filters/FiltersMenu.tsx b/packages/desktop-client/src/components/filters/FiltersMenu.tsx index db3363bccc..e10e5fbb77 100644 --- a/packages/desktop-client/src/components/filters/FiltersMenu.tsx +++ b/packages/desktop-client/src/components/filters/FiltersMenu.tsx @@ -283,7 +283,7 @@ function ConfigureField({ op={op} options={subfieldToOptions(field, subfield)} style={{ marginTop: 10 }} - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any onChange={(v: any) => { dispatch({ type: 'set-value', value: v }); }} diff --git a/packages/desktop-client/src/components/transactions/TransactionsTable.test.tsx b/packages/desktop-client/src/components/transactions/TransactionsTable.test.tsx index 555f4ed013..31649ca97c 100644 --- a/packages/desktop-client/src/components/transactions/TransactionsTable.test.tsx +++ b/packages/desktop-client/src/components/transactions/TransactionsTable.test.tsx @@ -70,7 +70,7 @@ const payees: PayeeEntity[] = [ ]; vi.mock('../../hooks/usePayees', async importOriginal => { const actual = - // eslint-disable-next-line @typescript-eslint/consistent-type-imports + // oxlint-disable-next-line typescript/consistent-type-imports await importOriginal(); return { ...actual, diff --git a/packages/desktop-client/src/index.tsx b/packages/desktop-client/src/index.tsx index ad7d6ea7aa..3b63955fcc 100644 --- a/packages/desktop-client/src/index.tsx +++ b/packages/desktop-client/src/index.tsx @@ -96,7 +96,7 @@ root.render( ); declare global { - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + // oxlint-disable-next-line typescript/consistent-type-definitions interface Window { __actionsForMenu: typeof boundActions & { undo: typeof undo; diff --git a/packages/desktop-client/src/util/markdown.ts b/packages/desktop-client/src/util/markdown.ts index beeb974b4a..7587c94c16 100644 --- a/packages/desktop-client/src/util/markdown.ts +++ b/packages/desktop-client/src/util/markdown.ts @@ -9,7 +9,7 @@ export function sequentialNewlinesPlugin() { // Adapted from https://codesandbox.io/s/create-react-app-forked-h3rmcy?file=/src/sequentialNewlinePlugin.js:0-774 const data = this.data(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any function add(field: string, value: any) { const list = data[field] ? data[field] : (data[field] = []); diff --git a/packages/desktop-client/vite.config.mts b/packages/desktop-client/vite.config.mts index f57a295b8f..0ec6629756 100644 --- a/packages/desktop-client/vite.config.mts +++ b/packages/desktop-client/vite.config.mts @@ -221,6 +221,6 @@ export default defineConfig(async ({ mode }) => { }, maxWorkers: 2, }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any } satisfies UserConfig & { test: any }; }); diff --git a/packages/loot-core/src/platform/server/fs/index.electron.ts b/packages/loot-core/src/platform/server/fs/index.electron.ts index edb88f8a18..7a3eaed36d 100644 --- a/packages/loot-core/src/platform/server/fs/index.electron.ts +++ b/packages/loot-core/src/platform/server/fs/index.electron.ts @@ -105,7 +105,7 @@ export const readFile: T.ReadFile = ( encoding = null; } // `any` as cannot refine return with two function overrides - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any return new Promise((resolve, reject) => { fs.readFile(filepath, encoding, (err, data) => { if (err) { diff --git a/packages/loot-core/src/server/accounts/app.ts b/packages/loot-core/src/server/accounts/app.ts index 3c85be81f8..e12c12a231 100644 --- a/packages/loot-core/src/server/accounts/app.ts +++ b/packages/loot-core/src/server/accounts/app.ts @@ -850,7 +850,7 @@ function handleSyncError( acct: db.DbAccount, ): SyncError { // TODO: refactor bank sync logic to use BankSyncError properly - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any if (err instanceof BankSyncError || (err as any)?.type === 'BankSyncError') { const error = err as BankSyncError; diff --git a/packages/loot-core/src/server/aql/exec.ts b/packages/loot-core/src/server/aql/exec.ts index 43b3c47975..2aa122a36f 100644 --- a/packages/loot-core/src/server/aql/exec.ts +++ b/packages/loot-core/src/server/aql/exec.ts @@ -118,7 +118,7 @@ export async function compileAndRunAqlQuery( options: RunCompiledAqlQueryOptions, ) { const { sqlPieces, state } = compileQuery(queryState, schema, schemaConfig); - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any const data: any = await runCompiledAqlQuery( queryState, sqlPieces, diff --git a/packages/loot-core/src/server/cloud-storage.ts b/packages/loot-core/src/server/cloud-storage.ts index e975f77e77..3094b47ac5 100644 --- a/packages/loot-core/src/server/cloud-storage.ts +++ b/packages/loot-core/src/server/cloud-storage.ts @@ -306,7 +306,7 @@ export async function upload() { : null), ...(groupId ? { 'X-ACTUAL-GROUP-ID': groupId } : null), // TODO: fix me - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any } as any, body: uploadContent, }); diff --git a/packages/loot-core/src/server/db/index.ts b/packages/loot-core/src/server/db/index.ts index f03c630c1a..71d7f8c1d4 100644 --- a/packages/loot-core/src/server/db/index.ts +++ b/packages/loot-core/src/server/db/index.ts @@ -197,7 +197,7 @@ export async function select(table, id) { ); // TODO: In the next phase, we will make this function generic // and pass the type of the return type to `runQuery`. - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any return rows[0] as any; } @@ -279,7 +279,7 @@ export async function selectWithSchema(table, sql, params) { .map(row => convertFromSelect(schema, schemaConfig, table, row)) .filter(Boolean); // TODO: Make convertFromSelect generic so we don't need this cast - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any return convertedRows as any[]; } diff --git a/packages/loot-core/src/server/errors.ts b/packages/loot-core/src/server/errors.ts index de0d3d6d49..e75c7e593c 100644 --- a/packages/loot-core/src/server/errors.ts +++ b/packages/loot-core/src/server/errors.ts @@ -80,7 +80,7 @@ export class RuleError extends Error { } } -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// oxlint-disable-next-line typescript/no-explicit-any export function APIError(msg: string, meta?: Record) { return { type: 'APIError', message: msg, meta }; } diff --git a/packages/loot-core/src/server/migrate/cli.ts b/packages/loot-core/src/server/migrate/cli.ts index c70e35bae8..4919303fc2 100755 --- a/packages/loot-core/src/server/migrate/cli.ts +++ b/packages/loot-core/src/server/migrate/cli.ts @@ -3,6 +3,8 @@ import * as fs from 'fs'; import * as path from 'path'; +import yargs from 'yargs'; + import { logger } from '../../platform/server/log'; import * as sqlite from '../../platform/server/sqlite'; @@ -16,24 +18,26 @@ import { migrate, } from './migrations'; -const argv = require('yargs').options({ - m: { - alias: 'migrationsDir', - requiresArg: true, - type: 'string', - describe: 'Migrations directory', - }, - name: { - requiresArg: true, - type: 'string', - describe: 'Name of new migration', - }, - db: { - requiresArg: true, - type: 'string', - describe: 'Path to database', - }, -}).argv; +const argv = yargs() + .options({ + m: { + alias: 'migrationsDir', + requiresArg: true, + type: 'string', + describe: 'Migrations directory', + }, + name: { + requiresArg: true, + type: 'string', + describe: 'Name of new migration', + }, + db: { + requiresArg: true, + type: 'string', + describe: 'Path to database', + }, + }) + .parseSync(); function getDatabase() { return sqlite.openDatabase(argv.db); @@ -62,7 +66,7 @@ async function list(db) { const cmd = argv._[0]; -withMigrationsDir(argv.migrationsDir || getMigrationsDir(), async () => { +withMigrationsDir(argv.m || getMigrationsDir(), async () => { switch (cmd) { case 'reset': fs.unlinkSync(argv.db); diff --git a/packages/loot-core/src/server/sync/sync.property.test.ts b/packages/loot-core/src/server/sync/sync.property.test.ts index a6d8b99550..a883a4abc5 100644 --- a/packages/loot-core/src/server/sync/sync.property.test.ts +++ b/packages/loot-core/src/server/sync/sync.property.test.ts @@ -94,7 +94,7 @@ const baseTime = 1565374471903; const clientId1 = '80dd7da215247293'; const clientId2 = '90xU1sd5124329ac'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// oxlint-disable-next-line typescript/no-explicit-any function makeGen>({ table, row, diff --git a/packages/loot-core/src/server/transactions/import/parse-file.test.ts b/packages/loot-core/src/server/transactions/import/parse-file.test.ts index 8aaba2802a..d2a0b3163d 100644 --- a/packages/loot-core/src/server/transactions/import/parse-file.test.ts +++ b/packages/loot-core/src/server/transactions/import/parse-file.test.ts @@ -54,7 +54,7 @@ async function importFileWithRealTime( let transactions = originalTransactions; if (transactions) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any transactions = (transactions as any[]).map(trans => ({ ...trans, amount: amountToInteger(trans.amount), diff --git a/packages/loot-core/src/shared/async.ts b/packages/loot-core/src/shared/async.ts index a2b4ad4211..d36282174b 100644 --- a/packages/loot-core/src/shared/async.ts +++ b/packages/loot-core/src/shared/async.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// oxlint-disable-next-line typescript/no-explicit-any type AnyFunction = (...args: any[]) => any; export function sequential( diff --git a/packages/loot-core/src/shared/platform.electron.ts b/packages/loot-core/src/shared/platform.electron.ts index fc10d98eee..d24038afa4 100644 --- a/packages/loot-core/src/shared/platform.electron.ts +++ b/packages/loot-core/src/shared/platform.electron.ts @@ -1,4 +1,4 @@ -const os = require('os'); +import os from 'os'; const isWindows = os.platform() === 'win32'; const isMac = os.platform() === 'darwin'; diff --git a/packages/loot-core/src/types/server-handlers.ts b/packages/loot-core/src/types/server-handlers.ts index e4dc233fbc..9251995b01 100644 --- a/packages/loot-core/src/types/server-handlers.ts +++ b/packages/loot-core/src/types/server-handlers.ts @@ -9,7 +9,7 @@ export interface ServerHandlers { applySpecialCases?: boolean; }) => Promise<{ filters: unknown[] }>; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // oxlint-disable-next-line typescript/no-explicit-any query: (query: QueryState) => Promise<{ data: any; dependencies: string[] }>; 'get-server-version': () => Promise< diff --git a/packages/loot-core/src/types/util.ts b/packages/loot-core/src/types/util.ts index b7b05a8697..5af42d9641 100644 --- a/packages/loot-core/src/types/util.ts +++ b/packages/loot-core/src/types/util.ts @@ -12,7 +12,7 @@ export type WithRequired = T & Required>; // Allows use of object literals inside child elements of `Trans` tags // see https://github.com/i18next/react-i18next/issues/1483 -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// oxlint-disable-next-line typescript/no-explicit-any export type TransObjectLiteral = any; export type AtLeastOne> = diff --git a/upcoming-release-notes/6443.md b/upcoming-release-notes/6443.md new file mode 100644 index 0000000000..14d3fb8290 --- /dev/null +++ b/upcoming-release-notes/6443.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +Simplify linting configuration by migrating from ESLint to Oxlint with updated rules. diff --git a/yarn.lock b/yarn.lock index 96c04b3367..630633cd91 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9277,7 +9277,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.46.4, @typescript-eslint/parser@npm:^8.46.4": +"@typescript-eslint/parser@npm:8.46.4": version: 8.46.4 resolution: "@typescript-eslint/parser@npm:8.46.4" dependencies: @@ -10051,7 +10051,6 @@ __metadata: "@octokit/rest": "npm:^22.0.1" "@types/node": "npm:^22.19.1" "@types/prompts": "npm:^2.4.9" - "@typescript-eslint/parser": "npm:^8.46.4" cross-env: "npm:^10.1.0" eslint: "npm:^9.39.2" eslint-import-resolver-typescript: "npm:^4.4.4"