Update typescript and eslint config (#1878)

* Update eslint rules
* Update typescript to 4.4
* Disable react/display-name
* Add @typescript-eslint/typescript-estree
This commit is contained in:
InfiniteTF
2021-10-28 01:27:26 +02:00
committed by GitHub
parent 372ea7218e
commit c93b5e12b7
30 changed files with 1815 additions and 982 deletions

View File

@@ -10,18 +10,23 @@
"project": "./tsconfig.json"
},
"plugins": [
"@typescript-eslint"
"@typescript-eslint",
"jsx-a11y"
],
"extends": [
"airbnb-typescript",
"airbnb/hooks",
"plugin:react/recommended",
"plugin:import/recommended",
"prettier",
"prettier/prettier",
"prettier/react",
"prettier/@typescript-eslint"
"prettier/prettier"
],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": 2,
"@typescript-eslint/naming-convention": [
"error",
@@ -48,36 +53,17 @@
],
"import/named": "off",
"import/namespace": "off",
"import/default": "off",
"import/no-named-as-default-member": "off",
"import/no-named-as-default": "off",
"import/no-cycle": "off",
"import/no-unused-modules": "off",
"import/no-deprecated": "off",
"import/no-unresolved": "off",
"import/prefer-default-export": "off",
"import/no-extraneous-dependencies": "off",
"indent": "off",
"@typescript-eslint/indent": "off",
"react/display-name": "off",
"react/prop-types": "off",
"react/destructuring-assignment": "off",
"react/require-default-props": "off",
"react/jsx-props-no-spreading": "off",
"react/sort-comp": "off",
"react/style-prop-object": ["error", {
"allow": ["FormattedNumber"]
}],
"spaced-comment": ["error", "always", {
"markers": ["/"]
}],
"max-classes-per-file": "off",
"no-plusplus": "off",
"prefer-destructuring": ["error", {"object": true, "array": false}],
"default-case": "off",
"consistent-return": "off",
"@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": true }],
"no-underscore-dangle": "off",
"no-nested-ternary": "off",
"jsx-a11y/media-has-caption": "off"
"no-nested-ternary": "off"
}
}

View File

@@ -55,9 +55,9 @@
"mousetrap": "^1.6.5",
"mousetrap-pause": "^1.0.0",
"query-string": "6.13.8",
"react": "17.0.1",
"react": "17.0.2",
"react-bootstrap": "1.4.3",
"react-dom": "17.0.1",
"react-dom": "17.0.2",
"react-helmet": "^6.1.0",
"react-intl": "^5.10.16",
"react-jw-player": "1.19.1",
@@ -88,21 +88,22 @@
"@types/lodash": "^4.14.168",
"@types/mousetrap": "^1.6.5",
"@types/node": "14.14.22",
"@types/react": "17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react": "17.0.31",
"@types/react-dom": "^17.0.10",
"@types/react-helmet": "^6.1.3",
"@types/react-router-bootstrap": "^0.24.5",
"@types/react-router-dom": "5.1.7",
"@types/react-router-hash-link": "^1.2.1",
"@typescript-eslint/eslint-plugin": "^4.14.0",
"@typescript-eslint/parser": "^4.14.0",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"craco-esbuild": "^0.4.2",
"eslint": "^7.18.0",
"eslint-config-airbnb-typescript": "^12.0.0",
"eslint-config-prettier": "^7.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint": "^7.32.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-airbnb-typescript": "^14.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react-hooks": "^4.2.0",
"extract-react-intl-messages": "^4.1.1",
"postcss-safe-parser": "^5.0.2",
@@ -111,6 +112,6 @@
"stylelint": "^13.9.0",
"stylelint-config-prettier": "^8.0.2",
"stylelint-order": "^4.1.0",
"typescript": "~4.0.5"
"typescript": "~4.4.4"
}
}

View File

@@ -1,6 +1,6 @@
import React, { useEffect } from "react";
import { Route, Switch, useRouteMatch } from "react-router-dom";
import { IntlProvider } from "react-intl";
import { IntlProvider, CustomFormats } from "react-intl";
import { Helmet } from "react-helmet";
import { mergeWith } from "lodash";
import { ToastProvider } from "src/hooks/Toast";
@@ -32,7 +32,7 @@ import { Setup } from "./components/Setup/Setup";
import { Migrate } from "./components/Setup/Migrate";
import * as GQL from "./core/generated-graphql";
import { LoadingIndicator, TITLE_SUFFIX } from "./components/Shared";
import ConfigurationProvider from "./hooks/Config";
import { ConfigurationProvider } from "./hooks/Config";
initPolyfills();
@@ -41,7 +41,7 @@ MousetrapPause(Mousetrap);
// Set fontawesome/free-solid-svg as default fontawesome icons
library.add(fas);
const intlFormats = {
const intlFormats: CustomFormats = {
date: {
long: { year: "numeric", month: "long", day: "numeric" },
},

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useHistory } from "react-router-dom";
import { useHistory, Prompt } from "react-router-dom";
import {
Button,
Dropdown,
@@ -30,7 +30,6 @@ import {
} from "src/components/Shared";
import { useToast } from "src/hooks";
import { useFormik } from "formik";
import { Prompt } from "react-router";
import { FormUtils, TextUtils } from "src/utils";
import { RatingStars } from "src/components/Scenes/SceneDetails/RatingStars";
import { GalleryScrapeDialog } from "./GalleryScrapeDialog";

View File

@@ -11,7 +11,7 @@ export const GalleryScenesPanel: React.FC<IGalleryScenesPanelProps> = ({
}) => (
<div className="container gallery-scenes">
{scenes.map((scene) => (
<SceneCard scene={scene} />
<SceneCard scene={scene} key={scene.id} />
))}
</div>
);

View File

@@ -14,7 +14,7 @@ import {
import { useToast } from "src/hooks";
import { FormUtils } from "src/utils";
import { useFormik } from "formik";
import { Prompt } from "react-router";
import { Prompt } from "react-router-dom";
import { RatingStars } from "src/components/Scenes/SceneDetails/RatingStars";
interface IProps {

View File

@@ -162,7 +162,7 @@ export const ListFilter: React.FC<IListFilterProps> = ({
const SavedFilterDropdown = React.forwardRef<
HTMLDivElement,
HTMLAttributes<HTMLDivElement>
>(({ style, className }, ref) => (
>(({ style, className }: HTMLAttributes<HTMLDivElement>, ref) => (
<div ref={ref} style={style} className={className}>
<SavedFilterList
filter={filter}
@@ -173,6 +173,7 @@ export const ListFilter: React.FC<IListFilterProps> = ({
/>
</div>
));
SavedFilterDropdown.displayName = "SavedFilterDropdown";
function render() {
const currentSortBy = filterOptions.sortByOptions.find(

View File

@@ -100,6 +100,7 @@ export const ListOperationButtons: React.FC<IListOperationButtonsProps> = ({
return (
<OverlayTrigger
overlay={<Tooltip id="edit">{button.text}</Tooltip>}
key={button.text}
>
<Button
variant={button.buttonVariant ?? "secondary"}

View File

@@ -6,7 +6,7 @@ import { LoadingIndicator } from "src/components/Shared";
import { useToast } from "src/hooks";
import { MovieEditPanel } from "./MovieEditPanel";
export const MovieCreate: React.FC = () => {
const MovieCreate: React.FC = () => {
const history = useHistory();
const Toast = useToast();

View File

@@ -33,7 +33,7 @@ import { useToast } from "src/hooks";
import { ImageUtils, FormUtils, TextUtils, getStashIDs } from "src/utils";
import { MovieSelect } from "src/components/Shared/Select";
import { useFormik } from "formik";
import { Prompt } from "react-router";
import { Prompt } from "react-router-dom";
import { ConfigurationContext } from "src/hooks/Config";
import { stashboxDisplayName } from "src/utils/stashbox";
import { SceneMovieTable } from "./SceneMovieTable";

View File

@@ -25,7 +25,11 @@ const SceneSearchResultDetails: React.FC<ISceneSearchResultDetailsProps> = ({
<Row>
<Col>
{scene.performers?.map((performer) => (
<Badge className="tag-item" variant="secondary">
<Badge
className="tag-item"
variant="secondary"
key={performer.name}
>
{performer.name}
</Badge>
))}
@@ -41,7 +45,11 @@ const SceneSearchResultDetails: React.FC<ISceneSearchResultDetailsProps> = ({
<Row>
<Col>
{scene.tags?.map((tag) => (
<Badge className="tag-item" variant="secondary">
<Badge
className="tag-item"
variant="secondary"
key={tag.stored_id}
>
{tag.name}
</Badge>
))}
@@ -136,7 +144,7 @@ export const SceneQueryModal: React.FC<IProps> = ({
const r = await queryScrapeSceneQuery(scraper, input);
setScenes(r.data.scrapeSingleScene);
} catch (err) {
setError(err);
if (err instanceof Error) setError(err);
} finally {
setLoading(false);
}

View File

@@ -9,7 +9,8 @@ import {
} from "src/core/StashService";
import { useToast } from "src/hooks";
import { Icon, LoadingIndicator } from "src/components/Shared";
import StashBoxConfiguration, {
import {
StashBoxConfiguration,
IStashBoxInstance,
} from "./StashBoxConfiguration";
import StashConfiguration from "./StashConfiguration";
@@ -47,7 +48,7 @@ export const ExclusionPatterns: React.FC<IExclusionPatternsProps> = (props) => {
<Form.Group>
{props.excludes &&
props.excludes.map((regexp, i) => (
<InputGroup>
<InputGroup key={regexp}>
<Form.Control
className="col col-sm-6 text-input"
value={regexp}

View File

@@ -1,7 +1,7 @@
import React, { useState } from "react";
import { Formik, useFormikContext } from "formik";
import { Button, Form } from "react-bootstrap";
import { Prompt } from "react-router";
import { Prompt } from "react-router-dom";
import { FormattedMessage, useIntl } from "react-intl";
import * as yup from "yup";
import {

View File

@@ -72,7 +72,7 @@ export const SettingsPluginsPanel: React.FC = () => {
>
<ul>
{h.hooks?.map((hh) => (
<li>
<li key={hh}>
<code>{hh}</code>
</li>
))}

View File

@@ -50,7 +50,7 @@ export const DirectorySelectionDialog: React.FC<IDirectorySelectionDialogProps>
>
<div className="dialog-container">
{paths.map((p) => (
<Row className="align-items-center mb-1">
<Row className="align-items-center mb-1" key={p}>
<Form.Label column xs={10}>
{p}
</Form.Label>

View File

@@ -140,5 +140,3 @@ export const StashBoxConfiguration: React.FC<IStashBoxConfigurationProps> = ({
</Form.Group>
);
};
export default StashBoxConfiguration;

View File

@@ -64,7 +64,7 @@ interface IStashConfigurationProps {
setStashes: (v: GQL.StashConfig[]) => void;
}
export const StashConfiguration: React.FC<IStashConfigurationProps> = ({
const StashConfiguration: React.FC<IStashConfigurationProps> = ({
stashes,
setStashes,
}) => {

View File

@@ -80,7 +80,7 @@ export const Migrate: React.FC = () => {
const newURL = new URL("/", window.location.toString());
window.location.href = newURL.toString();
} catch (e) {
setMigrateError(e.message ?? e.toString());
if (e instanceof Error) setMigrateError(e.message ?? e.toString());
setMigrateLoading(false);
}
}

View File

@@ -310,7 +310,7 @@ export const Setup: React.FC = () => {
return (
<ul>
{stashes.map((s) => (
<li>
<li key={s.path}>
<code>{s.path} </code>
{maybeRenderExclusions(s)}
</li>
@@ -329,7 +329,7 @@ export const Setup: React.FC = () => {
stashes,
});
} catch (e) {
setSetupError(e.message ?? e.toString());
if (e instanceof Error) setSetupError(e.message ?? e.toString());
} finally {
setLoading(false);
next();

View File

@@ -104,7 +104,7 @@ const DeleteEntityDialog: React.FC<IDeleteEntityDialogProps> = ({
</p>
<ul>
{selected.slice(0, 10).map((s) => (
<li>{s.name}</li>
<li key={s.name}>{s.name}</li>
))}
{selected.length > 10 && (
<FormattedMessage

View File

@@ -42,7 +42,7 @@ export const StudioDetailsPanel: React.FC<IStudioDetailsPanel> = ({
</dt>
<dd>
{studio.aliases.map((a) => (
<Badge className="tag-item" variant="secondary">
<Badge className="tag-item" variant="secondary" key={a}>
{a}
</Badge>
))}

View File

@@ -46,7 +46,7 @@ const Config: React.FC<IConfigProps> = ({ show, config, setConfig }) => {
<span>
{excludedFields.length > 0
? excludedFields.map((f) => (
<Badge variant="secondary" className="tag-item">
<Badge variant="secondary" className="tag-item" key={f}>
{TextUtils.capitalize(f)}
</Badge>
))

View File

@@ -271,7 +271,7 @@ const PerformerTaggerList: React.FC<IPerformerTaggerListProps> = ({
-1;
return (
<div>
<div key={performer.id}>
<InputGroup className="PerformerTagger-box-link">
<InputGroup.Text>{link}</InputGroup.Text>
<InputGroup.Append>

View File

@@ -89,7 +89,7 @@ const getFingerprintStatus = (
const phashList = (
<div className="m-2">
{phashMatches.map((fp) => (
<div>
<div key={fp.hash}>
<b>{fp.hash}</b>
{fp.hash === stashScene.phash
? ", Exact match"

View File

@@ -21,7 +21,7 @@ export const TagDetailsPanel: React.FC<ITagDetails> = ({ tag }) => {
</dt>
<dd className="col-9 col-xl-10">
{tag.aliases.map((a) => (
<Badge className="tag-item" variant="secondary">
<Badge className="tag-item" variant="secondary" key={a}>
{a}
</Badge>
))}

View File

@@ -6,7 +6,7 @@ import { FormUtils } from "src/utils";
import { useTagsMerge } from "src/core/StashService";
import { useIntl } from "react-intl";
import { useToast } from "src/hooks";
import { useHistory } from "react-router";
import { useHistory } from "react-router-dom";
interface ITagMergeModalProps {
show: boolean;

View File

@@ -24,5 +24,3 @@ export const ConfigurationProvider: React.FC<IContext> = ({
</ConfigurationContext.Provider>
);
};
export default ConfigurationProvider;

View File

@@ -27,7 +27,7 @@ export function useLocalForage<T>(
key: string,
defaultValue: T = {} as T
): [ILocalForage<T>, Dispatch<SetStateAction<T>>] {
const [error, setError] = React.useState(null);
const [error, setError] = React.useState<Error | null>(null);
const [data, setData] = React.useState<T>(Cache[key] as T);
const [loading, setLoading] = React.useState(Loading[key]);
@@ -45,7 +45,7 @@ export function useLocalForage<T>(
}
setError(null);
} catch (err) {
setError(err);
if (err instanceof Error) setError(err);
Cache[key] = defaultValue;
} finally {
Loading[key] = false;

View File

@@ -18,7 +18,7 @@
"moduleResolution": "node",
"resolveJsonModule": true,
"noEmit": true,
"jsx": "react",
"jsx": "react-jsx",
"downlevelIteration": true,
"experimentalDecorators": true,
"baseUrl": ".",

File diff suppressed because it is too large Load Diff