upgraded eslint, defined new rules & added ignore comments

This commit is contained in:
2026-02-23 20:27:09 +01:00
parent b30c068f9e
commit c5c1cf1c8d
25 changed files with 2696 additions and 108 deletions

View File

@@ -1,31 +0,0 @@
{
"root": true,
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "@typescript-eslint/parser",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"extends": [
"@vue/eslint-config-airbnb",
"plugin:vue/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
"rules": {
"vue/no-v-model-argument": "off",
"no-underscore-dangle": "off",
"vue/multi-word-component-names": "off",
"no-shadow": "off",
"@typescript-eslint/no-shadow": ["error"],
},
"settings": {
"import/resolver": {
webpack: {
config: "./webpack.config.js"
}
}
}
}

67
eslint.config.mjs Normal file
View File

@@ -0,0 +1,67 @@
import path from "node:path";
import { includeIgnoreFile } from "@eslint/compat";
import js from "@eslint/js";
import { defineConfig } from "eslint/config";
import { configs, plugins } from "eslint-config-airbnb-extended";
import { rules as prettierConfigRules } from "eslint-config-prettier";
import prettierPlugin from "eslint-plugin-prettier";
const CUSTOM_RULES = {
"vue/no-v-model-argument": "off",
"no-underscore-dangle": "off",
"vue/multi-word-component-names": "off",
"no-shadow": "off",
"@typescript-eslint/no-shadow": ["error"]
};
const gitignorePath = path.resolve(".", ".gitignore");
// ESLint recommended config
const jsConfig = defineConfig([
{
name: "js/config",
...js.configs.recommended
},
plugins.stylistic,
plugins.importX,
...configs.base.recommended // Airbnb base recommended config
]);
// Node & Airbnb recommended config
const nodeConfig = defineConfig([plugins.node, ...configs.node.recommended]);
// Typescript & Airbnb base TS config
const typescriptConfig = defineConfig([
plugins.typescriptEslint,
...configs.base.typescript
]);
// Prettier config
const prettierConfig = defineConfig([
{
name: "prettier/plugin/config",
plugins: {
prettier: prettierPlugin
}
},
{
name: "prettier/config",
rules: {
...prettierConfigRules,
"prettier/prettier": "error"
}
}
]);
export default defineConfig([
// Ignore files and folders listed in .gitignore
includeIgnoreFile(gitignorePath),
...jsConfig,
...nodeConfig,
...typescriptConfig,
...prettierConfig,
{
rules: CUSTOM_RULES
}
]);

View File

@@ -7,8 +7,7 @@
"scripts": {
"dev": "NODE_ENV=development vite",
"build": "yarn vite build",
"postbuild": "cp public/dist/index.html public/index.html",
"clean": "rm -r public/dist 2> /dev/null; rm public/index.html 2> /dev/null; rm -r lib 2> /dev/null",
"clean": "rm -r dist 2> /dev/null; rm public/index.html 2> /dev/null; rm -r lib 2> /dev/null",
"start": "echo 'Start using docker, consult README'",
"lint": "eslint src --ext .ts,.vue",
"docs": "documentation build src/api.ts -f html -o docs/api && documentation build src/api.ts -f md -o docs/api.md"
@@ -20,10 +19,17 @@
"vuex": "4.1.0"
},
"devDependencies": {
"@eslint/compat": "^2.0.2",
"@eslint/js": "^10.0.1",
"@types/node": "^25.3.0",
"@vitejs/plugin-vue": "^5.2.1",
"prettier": "2.7.1",
"eslint": "^10.0.1",
"eslint-config-airbnb-extended": "^3.0.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.5",
"prettier": "^3.8.1",
"sass": "1.54.3",
"typescript": "4.7.4",
"typescript": "5.9.3",
"vite": "^6.0.3"
}
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable n/no-unsupported-features/node-builtins */
import { IList, IMediaCredits, IPersonCredits } from "./interfaces/IList";
const API_HOSTNAME = import.meta.env.VITE_SEASONED_API;
@@ -336,7 +337,11 @@ const register = (username, password) => {
});
};
const login = (username, password, throwError = false) => {
const login = async (
username: string,
password: string,
throwError = false
) => {
const url = new URL("/api/v1/user/login", API_HOSTNAME);
const options = {
method: "POST",
@@ -353,7 +358,7 @@ const login = (username, password, throwError = false) => {
});
};
const logout = (throwError = false) => {
const logout = async (throwError = false) => {
const url = new URL("/api/v1/user/logout", API_HOSTNAME);
const options = { method: "POST" };

View File

@@ -46,7 +46,7 @@
let _type: MediaTypes;
const params = new URLSearchParams(window.location.search);
params.forEach((value, key) => {
params.forEach((_, key) => {
if (
key !== MediaTypes.Movie &&
key !== MediaTypes.Show &&

View File

@@ -27,7 +27,6 @@
const overflow: Ref<boolean> = ref(false);
const descriptionElement: Ref<HTMLElement> = ref(null);
// eslint-disable-next-line no-undef
function removeElements(elems: NodeListOf<Element>) {
elems.forEach(el => el.remove());
}

View File

@@ -85,7 +85,7 @@
try {
validate();
} catch (error) {
console.log("not valid!"); // eslint-disable-line no-console
console.log("not valid! error:", error); // eslint-disable-line no-console
}
// const body: ResetPasswordPayload = {

View File

@@ -1,3 +1,4 @@
/*
let setValue = function(el, binding) {
let value = binding.value;
let dateArray = value.split('-');
@@ -13,3 +14,4 @@ module.exports = {
setValue(el, binding);
}
}
*/

View File

@@ -1,5 +1,6 @@
let setValue = function(el, binding) {
let img = new Image();
/*
const setValue = function(el, binding) {
const img = new Image();
img.src = binding.value;
img.onload = function() {
@@ -16,4 +17,5 @@ module.exports = {
update(el, binding) {
setValue(el, binding);
}
}
};
*/

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-use-before-define */
import { MediaTypes } from "./IList";
export interface IAutocompleteResult {

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-use-before-define */
export enum GraphTypes {
Plays = "plays",
Duration = "duration"
@@ -12,12 +10,12 @@ export enum GraphValueTypes {
export interface IGraphDataset {
name: string;
data: Array<number>;
data: number[];
}
export interface IGraphData {
labels: Array<string>;
series: Array<IGraphDataset>;
labels: string[];
series: IGraphDataset[];
}
export interface IGraphResponse {

View File

@@ -67,7 +67,7 @@ export interface IMovie {
backdrop: string;
release_date: string | Date;
rating: number;
genres: Array<MovieGenres>;
genres: MovieGenres[];
production_status: MovieProductionStatus;
tagline: string;
runtime: number;
@@ -88,9 +88,9 @@ export interface IShow {
seasons?: number;
episodes?: number;
popularity?: number;
genres?: Array<ShowGenres>;
genres?: ShowGenres[];
production_status?: string;
runtime?: Array<number>;
runtime?: number[];
exists_in_plex?: boolean;
type: MediaTypes.Show;
}
@@ -135,19 +135,19 @@ export interface ICrew {
}
export interface IMediaCredits {
cast: Array<ICast>;
crew: Array<ICrew>;
cast: ICast[];
crew: ICrew[];
id: number;
}
export interface IPersonCredits {
cast: Array<IMovie | IShow>;
crew: Array<ICrew>;
cast: (IMovie | IShow)[];
crew: ICrew[];
id: number;
type?: string;
}
export type ListResults = Array<IMovie | IShow | IPerson | IRequest>;
export type ListResults = (IMovie | IShow | IPerson | IRequest)[];
export interface IList {
results: ListResults;

View File

@@ -1,7 +1,7 @@
export default interface INavigationIcon {
title: string;
route: string;
icon: any; // eslint-disable-line @typescript-eslint/no-explicit-any
icon: any;
requiresAuth?: boolean;
useStroke?: boolean;
}

View File

@@ -1,6 +1,6 @@
import type ITorrent from "./ITorrent";
export default interface IStateTorrent {
results: Array<ITorrent>;
results: ITorrent[];
resultCount: number | null;
}

View File

@@ -7,5 +7,5 @@ export default interface ITorrent {
seed: string;
leech: string;
url: string | null;
release_type: Array<string>;
release_type: string[];
}

View File

@@ -3,7 +3,6 @@ import router from "./routes";
import store from "./store";
import Toast from "./plugins/Toast";
// eslint-disable-next-line @typescript-eslint/no-var-requires
import App from "./App.vue";
store.dispatch("darkmodeModule/findAndSetDarkmodeSupported");

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-param-reassign */
import IStateDarkmode from "../interfaces/IStateDarkmode";
const state: IStateDarkmode = {
@@ -10,9 +11,7 @@ export default {
namespaced: true,
state,
getters: {
darkmodeSupported: (state: IStateDarkmode) => {
return state.darkmodeSupported;
}
darkmodeSupported: (state: IStateDarkmode) => state.darkmodeSupported
},
mutations: {
SET_DARKMODE_SUPPORT: (

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-param-reassign */
import type IStateDocumentTitle from "../interfaces/IStateDocumentTitle";
const capitalize = (string: string) => {
@@ -26,7 +27,7 @@ const state: IStateDocumentTitle = {
title: undefined
};
/* eslint-disable @typescript-eslint/no-shadow, no-return-assign */
/* eslint-disable @typescript-eslint/no-shadow */
export default {
namespaced: true,
state,

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-param-reassign */
import type IStateHamburger from "../interfaces/IStateHamburger";
const state: IStateHamburger = {

View File

@@ -1,15 +1,16 @@
/* eslint-disable no-param-reassign */
import { MediaTypes } from "../interfaces/IList";
import type { IStatePopup, IPopupQuery } from "../interfaces/IStatePopup";
/* eslint-disable-next-line import/no-cycle */
/* eslint-disable-next-line import-x/no-cycle */
import router from "../routes";
const removeIncludedQueryParams = (params, key) => {
const removeIncludedQueryParams = (params: URLSearchParams, key: string) => {
if (params.has(key)) params.delete(key);
return params;
};
function paramsToObject(entries) {
function paramsToObject(entries: Iterator<[string, string]>) {
const result = {};
// eslint-disable-next-line no-restricted-syntax
for (const [key, value] of entries) {
@@ -65,7 +66,7 @@ export default {
actions: {
open: ({ commit }, { id, type }: { id: number; type: MediaTypes }) => {
if (!Number.isNaN(id)) {
id = Number(id); /* eslint-disable-line no-param-reassign */
id = Number(id);
}
commit("SET_OPEN", { id, type });

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-param-reassign */
import type ITorrent from "../interfaces/ITorrent";
import type IStateTorrent from "../interfaces/IStateTorrent";
@@ -11,16 +12,12 @@ export default {
namespaced: true,
state,
getters: {
results: (state: IStateTorrent) => {
return state.results;
},
resultCount: (state: IStateTorrent) => {
return state.resultCount;
}
results: (state: IStateTorrent) => state.results,
resultCount: (state: IStateTorrent) => state.resultCount
},
mutations: {
SET_RESULTS: (state: IStateTorrent, results: Array<ITorrent>) => {
SET_RESULTS: (state: IStateTorrent, results: ITorrent[]) => {
state.results = results;
},
SET_RESULT_COUNT: (state: IStateTorrent, count: number) => {
@@ -32,7 +29,7 @@ export default {
}
},
actions: {
setResults({ commit }, results: Array<ITorrent>) {
setResults({ commit }, results: ITorrent[]) {
commit("SET_RESULTS", results);
},
setResultCount({ commit }, count: number) {

View File

@@ -1,7 +1,7 @@
import { createRouter, createWebHistory } from "vue-router";
import type { RouteRecordRaw, RouteLocationNormalized } from "vue-router";
/* eslint-disable-next-line import/no-cycle */
/* eslint-disable-next-line import-x/no-cycle */
import store from "./store";
declare global {
@@ -10,7 +10,7 @@ declare global {
}
}
const routes: Array<RouteRecordRaw> = [
const routes: RouteRecordRaw[] = [
{
name: "home",
path: "/",
@@ -99,7 +99,6 @@ const loggedIn = () => store.getters["user/loggedIn"];
const hasPlexAccount = () => store.getters["user/plexUserId"] !== null;
const hamburgerIsOpen = () => store.getters["hamburger/isOpen"];
/* eslint-disable @typescript-eslint/no-explicit-any */
router.beforeEach(
(to: RouteLocationNormalized, from: RouteLocationNormalized, next: any) => {
store.dispatch("documentTitle/updateTitle", to.name);

View File

@@ -6,7 +6,7 @@ import torrentModule from "./modules/torrentModule";
import user from "./modules/user";
import hamburger from "./modules/hamburger";
/* eslint-disable-next-line import/no-cycle */
/* eslint-disable-next-line import-x/no-cycle */
import popup from "./modules/popup";
const store = createStore({

View File

@@ -14,9 +14,7 @@ export const parseJwt = (token: string) => {
const jsonPayload = decodeURIComponent(
atob(base64)
.split("")
.map(c => {
return `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`;
})
.map(c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)
.join("")
);
@@ -62,10 +60,10 @@ export function focusOnNextElement(elementEvent: KeyboardEvent): void {
}
}
export function humanMinutes(minutes) {
export function humanMinutes(minutes: number[] | number) {
if (minutes instanceof Array) {
/* eslint-disable-next-line prefer-destructuring, no-param-reassign */
minutes = minutes[0];
/* eslint-disable-next-line no-param-reassign */
[minutes] = minutes;
}
const hours = Math.floor(minutes / 60);
@@ -93,7 +91,7 @@ export function setUrlQueryParameter(parameter: string, value: string): void {
const url = `${window.location.protocol}//${window.location.hostname}${
window.location.port ? `:${window.location.port}` : ""
}${window.location.pathname}${params.toString().length ? `?${params}` : ""}`;
}${ndow.location.pathname}${params.toString().length ? `?${params}` : ""}`;
window.history.pushState({}, "search", url);
}

2582
yarn.lock

File diff suppressed because it is too large Load Diff