diff --git a/makefile b/makefile index 0058b20..130481c 100644 --- a/makefile +++ b/makefile @@ -4,6 +4,9 @@ watch-tsc: watch-sass: ./node_modules/.bin/sass --watch ./src/client/webapp/styles/styles.scss ./dist/client/webapp/styles/styles.css +lint-autofix: + ./node_modules/.bin/eslint ./src --ext .js,.jsx,.ts,.tsx --fix + lint: ./node_modules/.bin/eslint ./src --ext .js,.jsx,.ts,.tsx diff --git a/package-lock.json b/package-lock.json index 110393c..c71a187 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,7 @@ "@typescript-eslint/parser": "^5.5.0", "electron": "^15.3.0", "eslint": "^8.4.0", + "eslint-plugin-unused-imports": "^2.0.0", "jest": "^27.4.0", "react": "^17.0.2", "react-dom": "^17.0.2", @@ -3108,6 +3109,36 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-plugin-unused-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz", + "integrity": "sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==", + "dev": true, + "dependencies": { + "eslint-rule-composer": "^0.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, + "node_modules/eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -10424,6 +10455,21 @@ } } }, + "eslint-plugin-unused-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz", + "integrity": "sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==", + "dev": true, + "requires": { + "eslint-rule-composer": "^0.3.0" + } + }, + "eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", diff --git a/package.json b/package.json index fbad019..7c3f59c 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@typescript-eslint/parser": "^5.5.0", "electron": "^15.3.0", "eslint": "^8.4.0", + "eslint-plugin-unused-imports": "^2.0.0", "jest": "^27.4.0", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/src/.eslintrc.js b/src/.eslintrc.js index ba638e4..40b426e 100644 --- a/src/.eslintrc.js +++ b/src/.eslintrc.js @@ -4,6 +4,7 @@ module.exports = { parser: '@typescript-eslint/parser', plugins: [ '@typescript-eslint', + 'unused-imports' ], extends: [ 'eslint:recommended', @@ -11,6 +12,7 @@ module.exports = { ], "rules": { "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "off" + "@typescript-eslint/no-unused-vars": "off", + "unused-imports/no-unused-imports": "warn" } }; diff --git a/src/client/webapp/auto-verifier-with-args.ts b/src/client/webapp/auto-verifier-with-args.ts index 28672c4..1c0d746 100644 --- a/src/client/webapp/auto-verifier-with-args.ts +++ b/src/client/webapp/auto-verifier-with-args.ts @@ -5,7 +5,6 @@ const LOG = Logger.create(__filename, electronConsole); import { AutoVerifier, AutoVerifierChangesType } from "./auto-verifier"; import { Changes, WithEquals } from "./data-types"; -import Q from './q-module'; export interface PartialMessageListQuery { channelId: string; diff --git a/src/client/webapp/elements/components/button-download.tsx b/src/client/webapp/elements/components/button-download.tsx index d53daaa..17b980d 100644 --- a/src/client/webapp/elements/components/button-download.tsx +++ b/src/client/webapp/elements/components/button-download.tsx @@ -4,8 +4,8 @@ import Logger from '../../../../logger/logger'; const LOG = Logger.create(__filename, electronConsole); import electron from 'electron'; -import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; -import { Resource, ShouldNeverHappenError } from '../../data-types'; +import React, { FC, useCallback, useEffect, useState } from 'react'; +import { ShouldNeverHappenError } from '../../data-types'; import CombinedGuild from '../../guild-combined'; import Util from '../../util'; import Globals from '../../globals'; diff --git a/src/client/webapp/elements/components/input-dropdown.tsx b/src/client/webapp/elements/components/input-dropdown.tsx index f17ab0b..3279c6d 100644 --- a/src/client/webapp/elements/components/input-dropdown.tsx +++ b/src/client/webapp/elements/components/input-dropdown.tsx @@ -1,4 +1,4 @@ -import React, { ChangeEvent, createRef, FC, MouseEvent, MouseEventHandler, useCallback, useEffect, useMemo, useState } from 'react'; +import React, { createRef, FC, MouseEvent, useCallback, useEffect, useMemo, useState } from 'react'; export interface DropdownInputProps { label?: string; diff --git a/src/client/webapp/elements/components/input-image-edit.tsx b/src/client/webapp/elements/components/input-image-edit.tsx index 46aa426..ec06a60 100644 --- a/src/client/webapp/elements/components/input-image-edit.tsx +++ b/src/client/webapp/elements/components/input-image-edit.tsx @@ -8,7 +8,6 @@ import ElementsUtil from '../require/elements-util'; import * as FileType from 'file-type'; -import * as crypto from 'crypto'; interface ImageEditInputProps { alt?: string; diff --git a/src/client/webapp/elements/components/invite-preview.tsx b/src/client/webapp/elements/components/invite-preview.tsx index 0d1021f..ded45a2 100644 --- a/src/client/webapp/elements/components/invite-preview.tsx +++ b/src/client/webapp/elements/components/invite-preview.tsx @@ -1,4 +1,4 @@ -import moment, { Duration } from 'moment'; +import { Duration } from 'moment'; import React, { FC, useMemo } from 'react'; export interface InvitePreviewProps { diff --git a/src/client/webapp/elements/components/overlay.tsx b/src/client/webapp/elements/components/overlay.tsx index e591a8f..5fc4c75 100644 --- a/src/client/webapp/elements/components/overlay.tsx +++ b/src/client/webapp/elements/components/overlay.tsx @@ -3,8 +3,7 @@ const electronConsole = electronRemote.getGlobal('console') as Console; import Logger from '../../../../logger/logger'; const LOG = Logger.create(__filename, electronConsole); -import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "react"; -import ReactDOM from "react-dom"; +import React, { FC, useMemo, useRef, useState } from "react"; import ElementsUtil from '../require/elements-util'; interface OverlayProps { diff --git a/src/client/webapp/elements/context-menu-guild-title.tsx b/src/client/webapp/elements/context-menu-guild-title.tsx index d02b912..74112a9 100644 --- a/src/client/webapp/elements/context-menu-guild-title.tsx +++ b/src/client/webapp/elements/context-menu-guild-title.tsx @@ -5,7 +5,6 @@ const LOG = Logger.create(__filename, electronConsole); import ElementsUtil from './require/elements-util.js'; import BaseElements from './require/base-elements.js'; -import { GuildMetadata } from '../data-types'; import Q from '../q-module'; import UI from '../ui'; @@ -16,7 +15,6 @@ import CombinedGuild from '../guild-combined'; import React from 'react'; import ReactHelper from './require/react-helper'; import GuildSettingsOverlay from './overlays/overlay-guild-settings'; -import ErrorMessageOverlay from './overlays/overlay-error-message'; import CreateChannelOverlay from './overlays/overlay-create-channel'; export default function createGuildTitleContextMenu(document: Document, q: Q, ui: UI, guild: CombinedGuild): Element { diff --git a/src/client/webapp/elements/displays/display-guild-overview.tsx b/src/client/webapp/elements/displays/display-guild-overview.tsx index 0923f0d..8253260 100644 --- a/src/client/webapp/elements/displays/display-guild-overview.tsx +++ b/src/client/webapp/elements/displays/display-guild-overview.tsx @@ -5,13 +5,11 @@ const LOG = Logger.create(__filename, electronConsole); import React, { Dispatch, FC, SetStateAction, useCallback, useEffect, useMemo, useState } from 'react'; -import { GuildMetadata } from '../../data-types'; import Globals from '../../globals'; import CombinedGuild from '../../guild-combined'; import Display from '../components/display'; import TextInput from '../components/input-text'; import ImageEditInput from '../components/input-image-edit'; -import ReactHelper from '../require/react-helper'; import GuildSubscriptions from '../require/guild-subscriptions'; export interface GuildOverviewDisplayProps { diff --git a/src/client/webapp/elements/msg-img-res.tsx b/src/client/webapp/elements/msg-img-res.tsx index 6ad5426..03d95bf 100644 --- a/src/client/webapp/elements/msg-img-res.tsx +++ b/src/client/webapp/elements/msg-img-res.tsx @@ -15,7 +15,6 @@ import CombinedGuild from '../guild-combined'; import React from 'react'; import ReactHelper from './require/react-helper'; -import BaseElements from './require/base-elements'; import ImageOverlay from './overlays/overlay-image'; export default function createImageResourceMessage(document: Document, q: Q, guild: CombinedGuild, message: Message): Element { diff --git a/src/client/webapp/elements/overlays/overlay-create-channel.tsx b/src/client/webapp/elements/overlays/overlay-create-channel.tsx index bee5882..428104e 100644 --- a/src/client/webapp/elements/overlays/overlay-create-channel.tsx +++ b/src/client/webapp/elements/overlays/overlay-create-channel.tsx @@ -3,7 +3,7 @@ const electronConsole = electronRemote.getGlobal('console') as Console; import Logger from '../../../../logger/logger'; const LOG = Logger.create(__filename, electronConsole); -import React, { createRef, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { createRef, FC, useCallback, useEffect, useMemo, useState } from 'react'; import CombinedGuild from '../../guild-combined'; import BaseElements from '../require/base-elements'; import TextInput from '../components/input-text'; diff --git a/src/client/webapp/elements/overlays/overlay-image.tsx b/src/client/webapp/elements/overlays/overlay-image.tsx index 9ce019a..dd26823 100644 --- a/src/client/webapp/elements/overlays/overlay-image.tsx +++ b/src/client/webapp/elements/overlays/overlay-image.tsx @@ -5,10 +5,9 @@ const LOG = Logger.create(__filename, electronConsole); import * as FileType from 'file-type'; -import React, { FC, useEffect, useMemo, useState } from 'react'; +import React, { FC, useMemo } from 'react'; import CombinedGuild from '../../guild-combined'; import ElementsUtil from '../require/elements-util'; -import { Resource } from '../../data-types'; import DownloadButton from '../components/button-download'; import createImageContextMenu from '../context-menu-img'; import Q from '../../q-module'; diff --git a/src/client/webapp/elements/overlays/overlay-modify-channel.tsx b/src/client/webapp/elements/overlays/overlay-modify-channel.tsx index ab7d904..8c3dd54 100644 --- a/src/client/webapp/elements/overlays/overlay-modify-channel.tsx +++ b/src/client/webapp/elements/overlays/overlay-modify-channel.tsx @@ -3,7 +3,7 @@ const electronConsole = electronRemote.getGlobal('console') as Console; import Logger from '../../../../logger/logger'; const LOG = Logger.create(__filename, electronConsole); -import React, { createRef, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { createRef, FC, useCallback, useEffect, useMemo, useState } from 'react'; import CombinedGuild from '../../guild-combined'; import BaseElements from '../require/base-elements'; import TextInput from '../components/input-text'; diff --git a/src/client/webapp/elements/overlays/overlay-personalize.tsx b/src/client/webapp/elements/overlays/overlay-personalize.tsx index 52ceb91..f8d6e8c 100644 --- a/src/client/webapp/elements/overlays/overlay-personalize.tsx +++ b/src/client/webapp/elements/overlays/overlay-personalize.tsx @@ -3,7 +3,6 @@ const electronConsole = electronRemote.getGlobal('console') as Console; import Logger from '../../../../logger/logger'; const LOG = Logger.create(__filename, electronConsole); -import moment from 'moment'; import React, { createRef, FC, useCallback, useEffect, useMemo, useState } from 'react'; import { ConnectionInfo } from '../../data-types'; import Globals from '../../globals'; @@ -12,7 +11,6 @@ import ImageEditInput from '../components/input-image-edit'; import TextInput from '../components/input-text'; import SubmitOverlayLower from '../components/submit-overlay-lower'; import ElementsUtil from '../require/elements-util'; -import ReactHelper from '../require/react-helper'; import GuildSubscriptions from '../require/guild-subscriptions'; export interface PersonalizeOverlayProps { diff --git a/src/client/webapp/elements/require/base-elements.tsx b/src/client/webapp/elements/require/base-elements.tsx index 2d8bf6d..82adad9 100644 --- a/src/client/webapp/elements/require/base-elements.tsx +++ b/src/client/webapp/elements/require/base-elements.tsx @@ -14,9 +14,7 @@ import { Channel } from '../../data-types'; import CombinedGuild from '../../guild-combined'; import Q from '../../q-module'; import ReactHelper from './react-helper'; -import Overlay from '../components/overlay'; -import ReactDOM from 'react-dom'; - + export interface HTMLElementWithRemoveSelf extends HTMLElement { removeSelf: (() => void); } diff --git a/src/client/webapp/elements/require/guild-subscriptions.ts b/src/client/webapp/elements/require/guild-subscriptions.ts index 324f41c..d31af98 100644 --- a/src/client/webapp/elements/require/guild-subscriptions.ts +++ b/src/client/webapp/elements/require/guild-subscriptions.ts @@ -6,7 +6,7 @@ const LOG = Logger.create(__filename, electronConsole); import { Changes, GuildMetadata, Resource } from "../../data-types"; import CombinedGuild from "../../guild-combined"; -import React, { DependencyList, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { AutoVerifierChangesType } from "../../auto-verifier"; import { Conflictable, Connectable } from "../../guild-types"; import { EventEmitter } from 'tsee'; diff --git a/src/client/webapp/guild-types.ts b/src/client/webapp/guild-types.ts index b19f348..7bd9ce9 100644 --- a/src/client/webapp/guild-types.ts +++ b/src/client/webapp/guild-types.ts @@ -1,5 +1,4 @@ import { Changes, Channel, GuildMetadata, Member, Message, Resource, Token } from './data-types'; -import { DefaultEventMap, EventEmitter } from 'tsee'; import { AutoVerifierChangesType } from './auto-verifier'; import { IDQuery, PartialMessageListQuery } from './auto-verifier-with-args'; diff --git a/src/client/webapp/message-ram-cache.ts b/src/client/webapp/message-ram-cache.ts index d3f8aa6..a56cf9d 100644 --- a/src/client/webapp/message-ram-cache.ts +++ b/src/client/webapp/message-ram-cache.ts @@ -1,4 +1,3 @@ -import strcmp from "../../strcmp/strcmp"; import { Message, ShouldNeverHappenError } from "./data-types"; import Globals from "./globals"; diff --git a/src/client/webapp/ui.ts b/src/client/webapp/ui.ts index bd30ec2..5978737 100644 --- a/src/client/webapp/ui.ts +++ b/src/client/webapp/ui.ts @@ -17,8 +17,7 @@ import createChannel from './elements/channel'; import createMember from './elements/member'; import GuildsManager from './guilds-manager'; import createMessage from './elements/message'; -import strcmp from '../../strcmp/strcmp'; - + interface SetMessageProps { atTop: boolean; atBottom: boolean; diff --git a/src/server/scripts/create-cordis-file.ts b/src/server/scripts/create-cordis-file.ts index eb3fef1..7052f6b 100644 --- a/src/server/scripts/create-cordis-file.ts +++ b/src/server/scripts/create-cordis-file.ts @@ -1,7 +1,6 @@ import * as fs from 'fs/promises'; import * as path from 'path'; -import * as crypto from 'crypto'; - + import * as FileType from 'file-type'; import { ExitCodes, ExitCode } from '../../exit-codes/exit-codes';