eslint update

This commit is contained in:
Athou
2023-12-28 19:54:51 +01:00
parent f4e48383cc
commit 97781d5551
65 changed files with 1258 additions and 3103 deletions

View File

@@ -1,29 +1,30 @@
import axios from "axios"
import {
AddCategoryRequest,
Category,
CategoryModificationRequest,
CollapseRequest,
Entries,
FeedInfo,
FeedInfoRequest,
FeedModificationRequest,
GetEntriesPaginatedRequest,
IDRequest,
LoginRequest,
MarkRequest,
Metrics,
MultipleMarkRequest,
PasswordResetRequest,
ProfileModificationRequest,
RegistrationRequest,
ServerInfo,
Settings,
StarRequest,
SubscribeRequest,
Subscription,
TagRequest,
UserModel,
type AddCategoryRequest,
type AdminSaveUserRequest,
type Category,
type CategoryModificationRequest,
type CollapseRequest,
type Entries,
type FeedInfo,
type FeedInfoRequest,
type FeedModificationRequest,
type GetEntriesPaginatedRequest,
type IDRequest,
type LoginRequest,
type MarkRequest,
type Metrics,
type MultipleMarkRequest,
type PasswordResetRequest,
type ProfileModificationRequest,
type RegistrationRequest,
type ServerInfo,
type Settings,
type StarRequest,
type SubscribeRequest,
type Subscription,
type TagRequest,
type UserModel,
} from "./types"
const axiosInstance = axios.create({ baseURL: "./rest", withCredentials: true })
@@ -42,34 +43,34 @@ axiosInstance.interceptors.response.use(
export const client = {
category: {
getRoot: () => axiosInstance.get<Category>("category/get"),
modify: (req: CategoryModificationRequest) => axiosInstance.post("category/modify", req),
collapse: (req: CollapseRequest) => axiosInstance.post("category/collapse", req),
getEntries: (req: GetEntriesPaginatedRequest) => axiosInstance.get<Entries>("category/entries", { params: req }),
markEntries: (req: MarkRequest) => axiosInstance.post("category/mark", req),
add: (req: AddCategoryRequest) => axiosInstance.post("category/add", req),
delete: (req: IDRequest) => axiosInstance.post("category/delete", req),
getRoot: async () => await axiosInstance.get<Category>("category/get"),
modify: async (req: CategoryModificationRequest) => await axiosInstance.post("category/modify", req),
collapse: async (req: CollapseRequest) => await axiosInstance.post("category/collapse", req),
getEntries: async (req: GetEntriesPaginatedRequest) => await axiosInstance.get<Entries>("category/entries", { params: req }),
markEntries: async (req: MarkRequest) => await axiosInstance.post("category/mark", req),
add: async (req: AddCategoryRequest) => await axiosInstance.post("category/add", req),
delete: async (req: IDRequest) => await axiosInstance.post("category/delete", req),
},
entry: {
mark: (req: MarkRequest) => axiosInstance.post("entry/mark", req),
markMultiple: (req: MultipleMarkRequest) => axiosInstance.post("entry/markMultiple", req),
star: (req: StarRequest) => axiosInstance.post("entry/star", req),
getTags: () => axiosInstance.get<string[]>("entry/tags"),
tag: (req: TagRequest) => axiosInstance.post("entry/tag", req),
mark: async (req: MarkRequest) => await axiosInstance.post("entry/mark", req),
markMultiple: async (req: MultipleMarkRequest) => await axiosInstance.post("entry/markMultiple", req),
star: async (req: StarRequest) => await axiosInstance.post("entry/star", req),
getTags: async () => await axiosInstance.get<string[]>("entry/tags"),
tag: async (req: TagRequest) => await axiosInstance.post("entry/tag", req),
},
feed: {
get: (id: string) => axiosInstance.get<Subscription>(`feed/get/${id}`),
modify: (req: FeedModificationRequest) => axiosInstance.post("feed/modify", req),
getEntries: (req: GetEntriesPaginatedRequest) => axiosInstance.get<Entries>("feed/entries", { params: req }),
markEntries: (req: MarkRequest) => axiosInstance.post("feed/mark", req),
fetchFeed: (req: FeedInfoRequest) => axiosInstance.post<FeedInfo>("feed/fetch", req),
refreshAll: () => axiosInstance.get("feed/refreshAll"),
subscribe: (req: SubscribeRequest) => axiosInstance.post<number>("feed/subscribe", req),
unsubscribe: (req: IDRequest) => axiosInstance.post("feed/unsubscribe", req),
importOpml: (req: File) => {
get: async (id: string) => await axiosInstance.get<Subscription>(`feed/get/${id}`),
modify: async (req: FeedModificationRequest) => await axiosInstance.post("feed/modify", req),
getEntries: async (req: GetEntriesPaginatedRequest) => await axiosInstance.get<Entries>("feed/entries", { params: req }),
markEntries: async (req: MarkRequest) => await axiosInstance.post("feed/mark", req),
fetchFeed: async (req: FeedInfoRequest) => await axiosInstance.post<FeedInfo>("feed/fetch", req),
refreshAll: async () => await axiosInstance.get("feed/refreshAll"),
subscribe: async (req: SubscribeRequest) => await axiosInstance.post<number>("feed/subscribe", req),
unsubscribe: async (req: IDRequest) => await axiosInstance.post("feed/unsubscribe", req),
importOpml: async (req: File) => {
const formData = new FormData()
formData.append("file", req)
return axiosInstance.post("feed/import", formData, {
return await axiosInstance.post("feed/import", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
@@ -77,23 +78,23 @@ export const client = {
},
},
user: {
login: (req: LoginRequest) => axiosInstance.post("user/login", req),
register: (req: RegistrationRequest) => axiosInstance.post("user/register", req),
passwordReset: (req: PasswordResetRequest) => axiosInstance.post("user/passwordReset", req),
getSettings: () => axiosInstance.get<Settings>("user/settings"),
saveSettings: (settings: Settings) => axiosInstance.post("user/settings", settings),
getProfile: () => axiosInstance.get<UserModel>("user/profile"),
saveProfile: (req: ProfileModificationRequest) => axiosInstance.post("user/profile", req),
deleteProfile: () => axiosInstance.post("user/profile/deleteAccount"),
login: async (req: LoginRequest) => await axiosInstance.post("user/login", req),
register: async (req: RegistrationRequest) => await axiosInstance.post("user/register", req),
passwordReset: async (req: PasswordResetRequest) => await axiosInstance.post("user/passwordReset", req),
getSettings: async () => await axiosInstance.get<Settings>("user/settings"),
saveSettings: async (settings: Settings) => await axiosInstance.post("user/settings", settings),
getProfile: async () => await axiosInstance.get<UserModel>("user/profile"),
saveProfile: async (req: ProfileModificationRequest) => await axiosInstance.post("user/profile", req),
deleteProfile: async () => await axiosInstance.post("user/profile/deleteAccount"),
},
server: {
getServerInfos: () => axiosInstance.get<ServerInfo>("server/get"),
getServerInfos: async () => await axiosInstance.get<ServerInfo>("server/get"),
},
admin: {
getAllUsers: () => axiosInstance.get<UserModel[]>("admin/user/getAll"),
saveUser: (req: UserModel) => axiosInstance.post("admin/user/save", req),
deleteUser: (req: IDRequest) => axiosInstance.post("admin/user/delete", req),
getMetrics: () => axiosInstance.get<Metrics>("admin/metrics"),
getAllUsers: async () => await axiosInstance.get<UserModel[]>("admin/user/getAll"),
saveUser: async (req: AdminSaveUserRequest) => await axiosInstance.post("admin/user/save", req),
deleteUser: async (req: IDRequest) => await axiosInstance.post("admin/user/delete", req),
getMetrics: async () => await axiosInstance.get<Metrics>("admin/metrics"),
},
}
@@ -109,7 +110,7 @@ export const errorToStrings = (err: unknown) => {
if (err.response) {
const { data } = err.response
if (typeof data === "string") strings.push(data)
if (typeof data === "object" && data.message) strings.push(data.message)
if (typeof data === "object" && data.message) strings.push(data.message as string)
if (typeof data === "object" && data.errors) strings = [...strings, ...data.errors]
}
}

View File

@@ -1,11 +1,11 @@
import { t } from "@lingui/macro"
import { DEFAULT_THEME } from "@mantine/core"
import { IconType } from "react-icons"
import { type IconType } from "react-icons"
import { FaAt } from "react-icons/fa"
import { SiBuffer, SiFacebook, SiGmail, SiInstapaper, SiPocket, SiTumblr, SiTwitter } from "react-icons/si"
import { Category, Entry, SharingSettings } from "./types"
import { type Category, type Entry, type SharingSettings } from "./types"
const categories: { [key: string]: Category } = {
const categories: Record<string, Category> = {
all: {
id: "all",
name: t`All`,

View File

@@ -1,9 +1,9 @@
/* eslint-disable import/first */
import { configureStore } from "@reduxjs/toolkit"
import { client } from "app/client"
import { type client } from "app/client"
import { reducers } from "app/store"
import { Entries, Entry } from "app/types"
import { AxiosResponse } from "axios"
import { type Entries, type Entry } from "app/types"
import { type AxiosResponse } from "axios"
import { beforeEach, describe, expect, it, vi } from "vitest"
import { mockReset } from "vitest-mock-extended"
import { loadEntries, loadMoreEntries, markAllEntries, markEntry } from "./entries"

View File

@@ -1,8 +1,8 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { createSlice, type PayloadAction } from "@reduxjs/toolkit"
import { client } from "app/client"
import { Constants } from "app/constants"
import { createAppAsyncThunk, RootState } from "app/store"
import { Entry, MarkRequest, TagRequest } from "app/types"
import { createAppAsyncThunk, type RootState } from "app/store"
import { type Entry, type MarkRequest, type TagRequest } from "app/types"
import { scrollToWithCallback } from "app/utils"
import { flushSync } from "react-dom"
// eslint-disable-next-line import/no-cycle
@@ -11,7 +11,10 @@ import { reloadTree } from "./tree"
import { reloadTags } from "./user"
export type EntrySourceType = "category" | "feed" | "tag"
export type EntrySource = { type: EntrySourceType; id: string }
export interface EntrySource {
type: EntrySourceType
id: string
}
export type ExpendableEntry = Entry & { expanded?: boolean }
interface EntriesState {

View File

@@ -1,4 +1,4 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { createSlice, type PayloadAction } from "@reduxjs/toolkit"
import { Constants } from "app/constants"
import { createAppAsyncThunk } from "app/store"
@@ -22,8 +22,9 @@ export const redirectToSelectedSource = createAppAsyncThunk("redirect/selectedSo
export const redirectToCategory = createAppAsyncThunk("redirect/category", (id: string, thunkApi) =>
thunkApi.dispatch(redirectTo(`/app/category/${id}`))
)
export const redirectToRootCategory = createAppAsyncThunk("redirect/category/root", (_, thunkApi) =>
thunkApi.dispatch(redirectToCategory(Constants.categories.all.id))
export const redirectToRootCategory = createAppAsyncThunk(
"redirect/category/root",
async (_, thunkApi) => await thunkApi.dispatch(redirectToCategory(Constants.categories.all.id))
)
export const redirectToCategoryDetails = createAppAsyncThunk("redirect/category/details", (id: string, thunkApi) =>
thunkApi.dispatch(redirectTo(`/app/category/${id}/details`))

View File

@@ -1,7 +1,7 @@
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
import { type PayloadAction, createSlice } from "@reduxjs/toolkit"
import { client } from "app/client"
import { createAppAsyncThunk } from "app/store"
import { ServerInfo } from "app/types"
import { type ServerInfo } from "app/types"
interface ServerState {
serverInfos?: ServerInfo
@@ -12,7 +12,7 @@ const initialState: ServerState = {
webSocketConnected: false,
}
export const reloadServerInfos = createAppAsyncThunk("server/infos", () => client.server.getServerInfos().then(r => r.data))
export const reloadServerInfos = createAppAsyncThunk("server/infos", async () => await client.server.getServerInfos().then(r => r.data))
export const serverSlice = createSlice({
name: "server",
initialState,

View File

@@ -1,7 +1,7 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { createSlice, type PayloadAction } from "@reduxjs/toolkit"
import { client } from "app/client"
import { createAppAsyncThunk } from "app/store"
import { Category, CollapseRequest } from "app/types"
import { type Category, type CollapseRequest } from "app/types"
import { visitCategoryTree } from "app/utils"
// eslint-disable-next-line import/no-cycle
import { markEntry } from "./entries"
@@ -20,9 +20,10 @@ const initialState: TreeState = {
sidebarVisible: true,
}
export const reloadTree = createAppAsyncThunk("tree/reload", () => client.category.getRoot().then(r => r.data))
export const collapseTreeCategory = createAppAsyncThunk("tree/category/collapse", async (req: CollapseRequest) =>
client.category.collapse(req)
export const reloadTree = createAppAsyncThunk("tree/reload", async () => await client.category.getRoot().then(r => r.data))
export const collapseTreeCategory = createAppAsyncThunk(
"tree/category/collapse",
async (req: CollapseRequest) => await client.category.collapse(req)
)
export const treeSlice = createSlice({

View File

@@ -3,7 +3,7 @@ import { showNotification } from "@mantine/notifications"
import { createSlice, isAnyOf } from "@reduxjs/toolkit"
import { client } from "app/client"
import { createAppAsyncThunk } from "app/store"
import { ReadingMode, ReadingOrder, Settings, SharingSettings, UserModel } from "app/types"
import { type ReadingMode, type ReadingOrder, type Settings, type SharingSettings, type UserModel } from "app/types"
// eslint-disable-next-line import/no-cycle
import { reloadEntries } from "./entries"
@@ -15,9 +15,9 @@ interface UserState {
const initialState: UserState = {}
export const reloadSettings = createAppAsyncThunk("settings/reload", () => client.user.getSettings().then(r => r.data))
export const reloadProfile = createAppAsyncThunk("profile/reload", () => client.user.getProfile().then(r => r.data))
export const reloadTags = createAppAsyncThunk("entries/tags", () => client.entry.getTags().then(r => r.data))
export const reloadSettings = createAppAsyncThunk("settings/reload", async () => await client.user.getSettings().then(r => r.data))
export const reloadProfile = createAppAsyncThunk("profile/reload", async () => await client.user.getProfile().then(r => r.data))
export const reloadTags = createAppAsyncThunk("entries/tags", async () => await client.entry.getTags().then(r => r.data))
export const changeReadingMode = createAppAsyncThunk("settings/readingMode", (readingMode: ReadingMode, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return

View File

@@ -1,6 +1,6 @@
import { configureStore, createAsyncThunk } from "@reduxjs/toolkit"
import { setupListeners } from "@reduxjs/toolkit/query"
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
import { type TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
import entriesReducer from "./slices/entries"
import redirectReducer from "./slices/redirect"
import serverReducer from "./slices/server"

View File

@@ -134,7 +134,7 @@ export interface MetricMeter {
units: string
}
export type MetricTimer = {
export interface MetricTimer {
count: number
max: number
mean: number
@@ -155,10 +155,10 @@ export type MetricTimer = {
}
export interface Metrics {
counters: { [key: string]: MetricCounter }
gauges: { [key: string]: MetricGauge }
meters: { [key: string]: MetricMeter }
timers: { [key: string]: MetricTimer }
counters: Record<string, MetricCounter>
gauges: Record<string, MetricGauge>
meters: Record<string, MetricMeter>
timers: Record<string, MetricTimer>
}
export interface MultipleMarkRequest {
@@ -273,6 +273,15 @@ export interface UserModel {
admin: boolean
}
export interface AdminSaveUserRequest {
id?: number
name: string
email?: string
password?: string
enabled: boolean
admin: boolean
}
export type ReadingMode = "all" | "unread"
export type ReadingOrder = "asc" | "desc"

View File

@@ -1,5 +1,5 @@
import { throttle } from "throttle-debounce"
import { Category } from "./types"
import { type Category } from "./types"
export function visitCategoryTree(category: Category, visitor: (category: Category) => void): void {
visitor(category)