From c211e00e09b9117383b6100e766a167861a6a2f5 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 16 Dec 2019 12:57:55 +0200 Subject: [PATCH 1/6] Add lint script using the react-app config Signed-off-by: XhmikosR --- .github/workflows/ci.yml | 3 +++ package.json | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4ca637..1cfd5a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,9 @@ jobs: - name: Check Formatting run: npm run check-format + - name: Lint + run: npm run lint + - name: Test run: npm run coverage diff --git a/package.json b/package.json index 149a6eb..41e7681 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "test": "react-scripts test --env=jsdom", "coverage": "react-scripts test --env=jsdom --coverage", "codecov": "codecov", + "lint": "eslint --ignore-path .gitignore --ext js,ts,tsx .", "eject": "react-scripts eject", "format": "prettier --write \"**/*.{js,tsx}\"", "check-format": "prettier --list-different \"**/*.{js,tsx}\"" @@ -92,5 +93,16 @@ "prettier": { "arrowParens": "avoid", "trailingComma": "none" + }, + "eslintConfig": { + "root": true, + "extends": [ + "eslint:recommended", + "react-app", + "plugin:react/recommended" + ], + "rules": { + "react/display-name": "off" + } } } From f65d053153f058ac01f90e4ee31b4459079de479 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Sun, 22 Mar 2020 15:08:15 +0200 Subject: [PATCH 2/6] Attempt to fix the lint issues. Signed-off-by: XhmikosR --- src/components/common/__tests__/Header.test.tsx | 8 ++++---- src/components/dashboard/ClientsGraph.tsx | 2 +- .../dashboard/__tests__/TopBlockedClients.test.tsx | 1 - .../dashboard/__tests__/TopBlockedDomains.test.tsx | 1 - src/components/dashboard/__tests__/TopClients.test.tsx | 1 - src/components/dashboard/__tests__/TopDomains.test.tsx | 1 - src/views/ExactBlacklist.tsx | 5 +++++ src/views/ExactWhitelist.tsx | 5 +++++ src/views/Login.tsx | 2 +- src/views/Logout.tsx | 2 +- src/views/RegexBlacklist.tsx | 5 +++++ src/views/RegexWhitelist.tsx | 5 +++++ 12 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/components/common/__tests__/Header.test.tsx b/src/components/common/__tests__/Header.test.tsx index b6cf852..c5d7c57 100644 --- a/src/components/common/__tests__/Header.test.tsx +++ b/src/components/common/__tests__/Header.test.tsx @@ -8,7 +8,7 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -import React, { MouseEvent } from "react"; +import React from "react"; import api from "../../../util/api"; import { shallow } from "enzyme"; import Header from "../Header"; @@ -16,7 +16,7 @@ import { TimeRangeSelectorContainer } from "../../dashboard/TimeRangeSelector"; it("shows the time range selector on the dashboard", () => { api.loggedIn = true; - history.pushState({}, "", "/dashboard"); + window.history.pushState({}, "", "/dashboard"); const wrapper = shallow(
); @@ -25,7 +25,7 @@ it("shows the time range selector on the dashboard", () => { it("does not show the time range selector when not logged in", () => { api.loggedIn = false; - history.pushState({}, "", "/dashboard"); + window.history.pushState({}, "", "/dashboard"); const wrapper = shallow(
); @@ -34,7 +34,7 @@ it("does not show the time range selector when not logged in", () => { it("does not show the time range selector on non-dashboard pages", () => { api.loggedIn = true; - history.pushState({}, "", "/whitelist"); + window.history.pushState({}, "", "/whitelist"); const wrapper = shallow(
); diff --git a/src/components/dashboard/ClientsGraph.tsx b/src/components/dashboard/ClientsGraph.tsx index 441917e..30320a3 100644 --- a/src/components/dashboard/ClientsGraph.tsx +++ b/src/components/dashboard/ClientsGraph.tsx @@ -207,7 +207,7 @@ export const transformData = ( // Fill in data & labels for (let step of overTime) { for (let destination in datasets) { - if (datasets.hasOwnProperty(destination)) + if (Object.prototype.hasOwnProperty.call(datasets, destination)) (datasets[destination].data as Array).push( step.data[destination] ); diff --git a/src/components/dashboard/__tests__/TopBlockedClients.test.tsx b/src/components/dashboard/__tests__/TopBlockedClients.test.tsx index 2b0e178..477918a 100644 --- a/src/components/dashboard/__tests__/TopBlockedClients.test.tsx +++ b/src/components/dashboard/__tests__/TopBlockedClients.test.tsx @@ -8,7 +8,6 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -import React from "react"; import { generateRows, transformData } from "../TopBlockedClients"; const fakeData: ApiTopBlockedClients = { diff --git a/src/components/dashboard/__tests__/TopBlockedDomains.test.tsx b/src/components/dashboard/__tests__/TopBlockedDomains.test.tsx index 63012cd..8e5ed1e 100644 --- a/src/components/dashboard/__tests__/TopBlockedDomains.test.tsx +++ b/src/components/dashboard/__tests__/TopBlockedDomains.test.tsx @@ -8,7 +8,6 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -import React from "react"; import { generateRows, transformData } from "../TopBlockedDomains"; const fakeData: ApiTopBlockedDomains = { diff --git a/src/components/dashboard/__tests__/TopClients.test.tsx b/src/components/dashboard/__tests__/TopClients.test.tsx index 972c83d..41fa50a 100644 --- a/src/components/dashboard/__tests__/TopClients.test.tsx +++ b/src/components/dashboard/__tests__/TopClients.test.tsx @@ -8,7 +8,6 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -import React from "react"; import { generateRows, transformData } from "../TopClients"; const fakeData: ApiTopClients = { diff --git a/src/components/dashboard/__tests__/TopDomains.test.tsx b/src/components/dashboard/__tests__/TopDomains.test.tsx index eaf203c..7892db3 100644 --- a/src/components/dashboard/__tests__/TopDomains.test.tsx +++ b/src/components/dashboard/__tests__/TopDomains.test.tsx @@ -8,7 +8,6 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -import React from "react"; import { generateRows, transformData } from "../TopDomains"; const fakeData: ApiTopDomains = { diff --git a/src/views/ExactBlacklist.tsx b/src/views/ExactBlacklist.tsx index 9b542c2..50915f7 100644 --- a/src/views/ExactBlacklist.tsx +++ b/src/views/ExactBlacklist.tsx @@ -9,6 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; +import PropTypes from "prop-types"; import { WithTranslation, withTranslation } from "react-i18next"; import api from "../util/api"; import ListPage from "../components/list/ListPage"; @@ -31,4 +32,8 @@ const Blacklist: FunctionComponent = props => { ); }; +Blacklist.propTypes = { + t: PropTypes.func.isRequired +}; + export default withTranslation(["location", "lists"])(Blacklist); diff --git a/src/views/ExactWhitelist.tsx b/src/views/ExactWhitelist.tsx index 89827b8..4b7610e 100644 --- a/src/views/ExactWhitelist.tsx +++ b/src/views/ExactWhitelist.tsx @@ -9,6 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; +import PropTypes from "prop-types"; import { WithTranslation, withTranslation } from "react-i18next"; import ListPage from "../components/list/ListPage"; import api from "../util/api"; @@ -31,4 +32,8 @@ const Whitelist: FunctionComponent = props => { ); }; +Whitelist.propTypes = { + t: PropTypes.func.isRequired +}; + export default withTranslation(["location", "lists"])(Whitelist); diff --git a/src/views/Login.tsx b/src/views/Login.tsx index 6f01812..e460380 100644 --- a/src/views/Login.tsx +++ b/src/views/Login.tsx @@ -37,7 +37,7 @@ class Login extends Component { cookiesEnabled: false }; - componentWillMount() { + componentDidMount() { // Check if cookies are enabled if (navigator.cookieEnabled) this.setState({ cookiesEnabled: true }); } diff --git a/src/views/Logout.tsx b/src/views/Logout.tsx index ff1a84b..0f543ea 100644 --- a/src/views/Logout.tsx +++ b/src/views/Logout.tsx @@ -14,7 +14,7 @@ import api from "../util/api"; import config from "../config"; export default class Logout extends Component { - componentWillMount() { + componentDidMount() { api.loggedIn = false; if (config.fakeAPI) { diff --git a/src/views/RegexBlacklist.tsx b/src/views/RegexBlacklist.tsx index e31af49..850ea61 100644 --- a/src/views/RegexBlacklist.tsx +++ b/src/views/RegexBlacklist.tsx @@ -9,6 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; +import PropTypes from "prop-types"; import { WithTranslation, withTranslation } from "react-i18next"; import ListPage from "../components/list/ListPage"; import api from "../util/api"; @@ -31,4 +32,8 @@ const RegexBlacklist: FunctionComponent = props => { ); }; +RegexBlacklist.propTypes = { + t: PropTypes.func.isRequired +}; + export default withTranslation(["location", "lists"])(RegexBlacklist); diff --git a/src/views/RegexWhitelist.tsx b/src/views/RegexWhitelist.tsx index 34e6627..2621c11 100644 --- a/src/views/RegexWhitelist.tsx +++ b/src/views/RegexWhitelist.tsx @@ -9,6 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; +import PropTypes from "prop-types"; import { WithTranslation, withTranslation } from "react-i18next"; import ListPage from "../components/list/ListPage"; import api from "../util/api"; @@ -31,4 +32,8 @@ const RegexWhitelist: FunctionComponent = props => { ); }; +RegexWhitelist.propTypes = { + t: PropTypes.func.isRequired +}; + export default withTranslation(["location", "lists"])(RegexWhitelist); From bf6a822480814a3441f2d5ffd53d37f73ccf2527 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Sun, 19 Apr 2020 15:38:25 -0400 Subject: [PATCH 3/6] Remove prop-types and disable associated lint Validating props is left to TypeScript. The react/prop-types lint is no longer necessary, as it does not work with TypeScript (false positives). Signed-off-by: Mcat12 --- package.json | 4 ++-- src/components/settings/DnsOptionSettings.tsx | 7 ------- src/views/ExactBlacklist.tsx | 5 ----- src/views/ExactWhitelist.tsx | 5 ----- src/views/RegexBlacklist.tsx | 5 ----- src/views/RegexWhitelist.tsx | 5 ----- 6 files changed, 2 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 41e7681..6c04b91 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "lodash.debounce": "^4.0.8", "lodash.isequal": "^4.5.0", "moment": "^2.24.0", - "prop-types": "^15.7.2", "react": "^16.13.1", "react-app-polyfill": "^1.0.6", "react-bootstrap-daterangepicker": "^4.1.0", @@ -102,7 +101,8 @@ "plugin:react/recommended" ], "rules": { - "react/display-name": "off" + "react/display-name": "off", + "react/prop-types": "off" } } } diff --git a/src/components/settings/DnsOptionSettings.tsx b/src/components/settings/DnsOptionSettings.tsx index 0b13fc0..688cf4b 100644 --- a/src/components/settings/DnsOptionSettings.tsx +++ b/src/components/settings/DnsOptionSettings.tsx @@ -9,7 +9,6 @@ * Please see LICENSE file for your rights under this license. */ import React, { Fragment } from "react"; -import PropTypes from "prop-types"; import { Col, FormGroup, Input, Label } from "reactstrap"; import { TFunction } from "i18next"; @@ -86,10 +85,4 @@ const DnsOptionSettings = ({ ); -DnsOptionSettings.propTypes = { - settings: PropTypes.object.isRequired, - onUpdate: PropTypes.func.isRequired, - t: PropTypes.func.isRequired -}; - export default DnsOptionSettings; diff --git a/src/views/ExactBlacklist.tsx b/src/views/ExactBlacklist.tsx index 50915f7..9b542c2 100644 --- a/src/views/ExactBlacklist.tsx +++ b/src/views/ExactBlacklist.tsx @@ -9,7 +9,6 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; -import PropTypes from "prop-types"; import { WithTranslation, withTranslation } from "react-i18next"; import api from "../util/api"; import ListPage from "../components/list/ListPage"; @@ -32,8 +31,4 @@ const Blacklist: FunctionComponent = props => { ); }; -Blacklist.propTypes = { - t: PropTypes.func.isRequired -}; - export default withTranslation(["location", "lists"])(Blacklist); diff --git a/src/views/ExactWhitelist.tsx b/src/views/ExactWhitelist.tsx index 4b7610e..89827b8 100644 --- a/src/views/ExactWhitelist.tsx +++ b/src/views/ExactWhitelist.tsx @@ -9,7 +9,6 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; -import PropTypes from "prop-types"; import { WithTranslation, withTranslation } from "react-i18next"; import ListPage from "../components/list/ListPage"; import api from "../util/api"; @@ -32,8 +31,4 @@ const Whitelist: FunctionComponent = props => { ); }; -Whitelist.propTypes = { - t: PropTypes.func.isRequired -}; - export default withTranslation(["location", "lists"])(Whitelist); diff --git a/src/views/RegexBlacklist.tsx b/src/views/RegexBlacklist.tsx index 850ea61..e31af49 100644 --- a/src/views/RegexBlacklist.tsx +++ b/src/views/RegexBlacklist.tsx @@ -9,7 +9,6 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; -import PropTypes from "prop-types"; import { WithTranslation, withTranslation } from "react-i18next"; import ListPage from "../components/list/ListPage"; import api from "../util/api"; @@ -32,8 +31,4 @@ const RegexBlacklist: FunctionComponent = props => { ); }; -RegexBlacklist.propTypes = { - t: PropTypes.func.isRequired -}; - export default withTranslation(["location", "lists"])(RegexBlacklist); diff --git a/src/views/RegexWhitelist.tsx b/src/views/RegexWhitelist.tsx index 2621c11..34e6627 100644 --- a/src/views/RegexWhitelist.tsx +++ b/src/views/RegexWhitelist.tsx @@ -9,7 +9,6 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; -import PropTypes from "prop-types"; import { WithTranslation, withTranslation } from "react-i18next"; import ListPage from "../components/list/ListPage"; import api from "../util/api"; @@ -32,8 +31,4 @@ const RegexWhitelist: FunctionComponent = props => { ); }; -RegexWhitelist.propTypes = { - t: PropTypes.func.isRequired -}; - export default withTranslation(["location", "lists"])(RegexWhitelist); From 884c941f9a130a429f5a2e7726cc23666b717ba7 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Sun, 19 Apr 2020 15:53:28 -0400 Subject: [PATCH 4/6] Remove duplicate ESLint plugins from extends list The react-app ESLint plugin bundled with create-react-app already provides the rules from ESLint and the react plugin, and additionally tweaks the defaults to give a better experience (ex. with TypeScript). Signed-off-by: Mcat12 --- package.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/package.json b/package.json index 6c04b91..476b9ec 100644 --- a/package.json +++ b/package.json @@ -95,11 +95,7 @@ }, "eslintConfig": { "root": true, - "extends": [ - "eslint:recommended", - "react-app", - "plugin:react/recommended" - ], + "extends": ["react-app"], "rules": { "react/display-name": "off", "react/prop-types": "off" From 1c34345e14773739d1ccd41e6d6ad91cff58e7a1 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Sun, 19 Apr 2020 16:00:20 -0400 Subject: [PATCH 5/6] Ignore false positive unused namespace in global.d.ts Signed-off-by: Mcat12 --- src/types/global.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/global.d.ts b/src/types/global.d.ts index f63b95c..0fdd34a 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -8,6 +8,7 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars namespace NodeJS { import i18next from "i18next"; From 893e229de3b3f1d1d6ee14157fb8c4e482159274 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Sun, 19 Apr 2020 16:06:30 -0400 Subject: [PATCH 6/6] Ignore git-ignored files when running Prettier Signed-off-by: Mcat12 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 476b9ec..95353b6 100644 --- a/package.json +++ b/package.json @@ -78,8 +78,8 @@ "codecov": "codecov", "lint": "eslint --ignore-path .gitignore --ext js,ts,tsx .", "eject": "react-scripts eject", - "format": "prettier --write \"**/*.{js,tsx}\"", - "check-format": "prettier --list-different \"**/*.{js,tsx}\"" + "format": "prettier --write \"**/*.{js,tsx}\" --ignore-path .gitignore", + "check-format": "prettier --list-different \"**/*.{js,tsx}\" --ignore-path .gitignore" }, "browserslist": [ "defaults",