diff --git a/.eslintrc.json b/.eslintrc.json index 6d150389..ce4ce1bf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -13,6 +13,8 @@ "no-unused-expressions": "error", "curly": "error", "class-methods-use-this": "warn", - "no-console": "warn" + "no-console": "warn", + "@typescript-eslint/no-empty-interface": "off", + "no-extra-boolean-cast": "off" } } diff --git a/package-lock.json b/package-lock.json index 4e51cba1..4f8830be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "dotenv": "^16.3.1", "downshift": "6.0.6", "eslint": "^8.33.0", + "eslint-webpack-plugin": "^4.2.0", "fuse.js": "6.5.3", "github-directory-downloader": "^1.3.6", "glob": "^10.3.12", @@ -679,6 +680,35 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", @@ -1650,6 +1680,12 @@ "node": ">=6" } }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, "node_modules/@tailwindcss/forms": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", @@ -1737,9 +1773,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", - "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "dev": true, "dependencies": { "@types/estree": "*", @@ -1822,6 +1858,30 @@ "integrity": "sha512-IwpIMieE55oGWiXkQPSBY1nw1nFs6bsKXTFskNY8sdS17K24vyEBRQZEwlRS7ZmXCWnJcQtbxWzly+cODWGs2A==", "dev": true }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/@types/js-yaml": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", @@ -2126,6 +2186,21 @@ "@types/node": "*" } }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", @@ -3328,6 +3403,21 @@ "node": ">=6.0" } }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -4343,6 +4433,79 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-webpack-plugin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-rsfpFQ01AWQbqtjgPRr2usVRxhWDuG0YDYcG8DJOteD3EFnpeuYuOwk0PQiN7PRBTqS6ElNdtPZPggj8If9WnA==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.10", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^8.0.0 || ^9.0.0", + "webpack": "^5.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/eslint/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -6371,6 +6534,23 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", diff --git a/package.json b/package.json index e094473e..93ba8fec 100644 --- a/package.json +++ b/package.json @@ -2869,6 +2869,7 @@ "dotenv": "^16.3.1", "downshift": "6.0.6", "eslint": "^8.33.0", + "eslint-webpack-plugin": "^4.2.0", "fuse.js": "6.5.3", "github-directory-downloader": "^1.3.6", "glob": "^10.3.12", diff --git a/src/commands/Chatbot.ts b/src/commands/Chatbot.ts index 629d4fa6..ba1e616f 100644 --- a/src/commands/Chatbot.ts +++ b/src/commands/Chatbot.ts @@ -33,26 +33,31 @@ export class Chatbot { const cspSource = webView.webview.cspSource; + const fetchLocalization = async (requestId: string) => { + if (!requestId) { + return; + } + + const fileContents = await getLocalizationFile(); + + webView.webview.postMessage({ + command: GeneralCommands.toVSCode.getLocalization, + requestId, + payload: fileContents + }); + }; + webView.webview.onDidReceiveMessage(async (message) => { - switch (message.command) { + const { command, requestId, payload, data } = message; + + switch (command) { case PreviewCommands.toVSCode.open: - if (message.data) { - commands.executeCommand('vscode.open', message.data); + if (payload || data) { + commands.executeCommand('vscode.open', payload || data); } - return; + break; case GeneralCommands.toVSCode.getLocalization: - const { requestId } = message; - if (!requestId) { - return; - } - - const fileContents = await getLocalizationFile(); - - webView.webview.postMessage({ - command: GeneralCommands.toVSCode.getLocalization, - requestId, - payload: fileContents - }); + fetchLocalization(requestId); return; } }); diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index 82c3dca6..ed46d597 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -401,8 +401,8 @@ export class Folders { folder.locales && folder.locales.length > 0 ? folder.locales : i18nSettings; let defaultLocale; - let sourcePath = folderPath; - let localeFolders: ContentFolder[] = []; + const sourcePath = folderPath; + const localeFolders: ContentFolder[] = []; if (i18nConfig && i18nConfig.length > 0) { for (const i18n of i18nConfig) { diff --git a/src/commands/Preview.ts b/src/commands/Preview.ts index c568d017..d537b37c 100644 --- a/src/commands/Preview.ts +++ b/src/commands/Preview.ts @@ -110,27 +110,32 @@ export class Preview { webView.dispose(); }); + const fetchLocalization = async (requestId: string) => { + if (!requestId) { + return; + } + + const fileContents = await getLocalizationFile(); + + webView.webview.postMessage({ + command: GeneralCommands.toVSCode.getLocalization, + requestId, + payload: fileContents + }); + }; + webView.webview.onDidReceiveMessage(async (message) => { - switch (message.command) { + const { command, payload, requestId } = message; + + switch (command) { case PreviewCommands.toVSCode.open: - if (message.payload) { - commands.executeCommand('vscode.open', message.payload); + if (payload) { + commands.executeCommand('vscode.open', payload); } - return; + break; case GeneralCommands.toVSCode.getLocalization: - const { requestId } = message; - if (!requestId) { - return; - } - - const fileContents = await getLocalizationFile(); - - webView.webview.postMessage({ - command: GeneralCommands.toVSCode.getLocalization, - requestId, - payload: fileContents - }); - return; + fetchLocalization(requestId); + break; } }); diff --git a/src/commands/Project.ts b/src/commands/Project.ts index 19a8bbb9..d78ad23c 100644 --- a/src/commands/Project.ts +++ b/src/commands/Project.ts @@ -42,7 +42,7 @@ categories: [] // Initialize command subscriptions.push( - commands.registerCommand(COMMAND_NAME.init, async (cb: Function) => { + commands.registerCommand(COMMAND_NAME.init, async (cb: () => void) => { await Project.init(); if (cb) { diff --git a/src/commands/i18n.ts b/src/commands/i18n.ts index 845040ac..21aa8704 100644 --- a/src/commands/i18n.ts +++ b/src/commands/i18n.ts @@ -403,8 +403,8 @@ export class i18n { sourceLocale: I18nConfig, targetLocale: I18nConfig ) { - return new Promise(async (resolve) => { - await window.withProgress( + return new Promise((resolve) => { + window.withProgress( { location: ProgressLocation.Notification, title: l10n.t(LocalizationKey.commandsI18nTranslateProgressTitle), diff --git a/src/dashboardWebView/components/App.tsx b/src/dashboardWebView/components/App.tsx index 89bc355f..c65da5eb 100644 --- a/src/dashboardWebView/components/App.tsx +++ b/src/dashboardWebView/components/App.tsx @@ -54,7 +54,7 @@ export const App: React.FunctionComponent = ({ return isAllowed(mode?.features || [], FEATURE_FLAG.dashboard.taxonomy.view); }, [mode?.features]); - const checkDevMode = (retry: number = 0) => { + const checkDevMode = (retry = 0) => { if (!window.fmExternal) { if (retry < 5) { setTimeout(() => checkDevMode(retry + 1), 150); diff --git a/src/dashboardWebView/components/Chatbot/Chatbot.tsx b/src/dashboardWebView/components/Chatbot/Chatbot.tsx index 90d4dea6..413c97d3 100644 --- a/src/dashboardWebView/components/Chatbot/Chatbot.tsx +++ b/src/dashboardWebView/components/Chatbot/Chatbot.tsx @@ -11,10 +11,11 @@ import * as l10n from '@vscode/l10n'; import { LocalizationKey } from '../../../localization'; import { messageHandler } from '@estruyf/vscode/dist/client'; import { GeneralCommands, WEBSITE_LINKS } from '../../../constants'; +import { l10nJsonFormat } from '@vscode/l10n'; export interface IChatbotProps { } -export const Chatbot: React.FunctionComponent = ({ }: React.PropsWithChildren) => { +export const Chatbot: React.FunctionComponent = () => { const { aiUrl } = useSettingsContext(); const [company, setCompany] = React.useState(undefined); const [chatId, setChatId] = React.useState(undefined); @@ -27,7 +28,7 @@ export const Chatbot: React.FunctionComponent = ({ }: React.Props const init = async () => { setLoading(true); - messageHandler.request(GeneralCommands.toVSCode.getLocalization).then((data) => { + messageHandler.request(GeneralCommands.toVSCode.getLocalization).then((data) => { if (data) { l10n.config({ contents: data diff --git a/src/dashboardWebView/components/DataView/DataForm.tsx b/src/dashboardWebView/components/DataView/DataForm.tsx index a3ab5cab..66905fab 100644 --- a/src/dashboardWebView/components/DataView/DataForm.tsx +++ b/src/dashboardWebView/components/DataView/DataForm.tsx @@ -53,7 +53,7 @@ export const DataForm: React.FunctionComponent = ({ }; } catch (error) { setError((error as Error).message); - return () => { }; + return () => void 0; } }; diff --git a/src/dashboardWebView/components/DataView/DataView.tsx b/src/dashboardWebView/components/DataView/DataView.tsx index 58140436..8361ad44 100644 --- a/src/dashboardWebView/components/DataView/DataView.tsx +++ b/src/dashboardWebView/components/DataView/DataView.tsx @@ -68,15 +68,14 @@ export const DataView: React.FunctionComponent = ( ); const onSubmit = useCallback( - (data: any) => { + (data: unknown) => { if (selectedData?.singleEntry) { // Needs to add a single entry updateData(data); return; } - debugger - const dataClone: any[] = Object.assign([], dataEntries); + const dataClone: unknown[] = Object.assign([], dataEntries); if (selectedIndex !== null && selectedIndex !== undefined) { dataClone[selectedIndex] = data; } else { @@ -140,7 +139,7 @@ export const DataView: React.FunctionComponent = ( return dataEntries && selectedIndex !== null && selectedIndex !== undefined ? dataEntries[selectedIndex] : null; - }, [selectedData, , dataEntries, selectedIndex]); + }, [selectedData, dataEntries, selectedIndex]); // Retrieve the data files, check if they have a schema or ID, if not, they shouldn't be shown const dataFiles = useMemo(() => { diff --git a/src/dashboardWebView/components/Filters/LanguageFilter.tsx b/src/dashboardWebView/components/Filters/LanguageFilter.tsx index 1c678f3d..838a801f 100644 --- a/src/dashboardWebView/components/Filters/LanguageFilter.tsx +++ b/src/dashboardWebView/components/Filters/LanguageFilter.tsx @@ -9,7 +9,7 @@ import { LocalizationKey } from '../../../localization'; export interface ILanguageFilterProps { } -export const LanguageFilter: React.FunctionComponent = ({ }: React.PropsWithChildren) => { +export const LanguageFilter: React.FunctionComponent = () => { const locales = useRecoilValue(LocalesAtom); const [crntLocale, setCrntLocale] = useRecoilState(LocaleAtom); diff --git a/src/dashboardWebView/components/Header/ClearFilters.tsx b/src/dashboardWebView/components/Header/ClearFilters.tsx index 7abfa074..c0cc2714 100644 --- a/src/dashboardWebView/components/Header/ClearFilters.tsx +++ b/src/dashboardWebView/components/Header/ClearFilters.tsx @@ -21,16 +21,16 @@ import { useEffect, useMemo } from 'react'; import * as l10n from '@vscode/l10n'; import { LocalizationKey } from '../../../localization'; -export const guardRecoilDefaultValue = (candidate: any): candidate is DefaultValue => { - if (candidate instanceof DefaultValue) return true; +export const guardRecoilDefaultValue = (candidate: unknown): candidate is DefaultValue => { + if (candidate instanceof DefaultValue) { + return true; + } return false; }; export interface IClearFiltersProps { } -export const ClearFilters: React.FunctionComponent = ( - _: React.PropsWithChildren -) => { +export const ClearFilters: React.FunctionComponent = () => { const [show, setShow] = React.useState(false); const folder = useRecoilValue(FolderSelector); @@ -75,7 +75,9 @@ export const ClearFilters: React.FunctionComponent = ( } }, [folder, tag, category, locale, hasCustomFilters]); - if (!show) return null; + if (!show) { + return null; + } return ( diff --git a/src/panelWebView/components/Fields/WysiwygField.tsx b/src/panelWebView/components/Fields/WysiwygField.tsx index cab26527..49a7c1f5 100644 --- a/src/panelWebView/components/Fields/WysiwygField.tsx +++ b/src/panelWebView/components/Fields/WysiwygField.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const ReactQuill = require('react-quill'); import 'react-quill/dist/quill.snow.css'; diff --git a/src/panelWebView/components/Git/GitAction.tsx b/src/panelWebView/components/Git/GitAction.tsx index cdc814b6..4df45e42 100644 --- a/src/panelWebView/components/Git/GitAction.tsx +++ b/src/panelWebView/components/Git/GitAction.tsx @@ -38,8 +38,6 @@ export const GitAction: React.FunctionComponent = ({ if (command === GeneralCommands.toWebview.git.syncingStart) { setIsSyncing(payload || "syncing"); - } else if (command === GeneralCommands.toWebview.git.syncingStart) { - setIsSyncing("syncing"); } else if (command === GeneralCommands.toWebview.git.syncingEnd) { setCommitMessage(undefined); setIsSyncing("idle"); diff --git a/src/panelWebView/components/Icons/AddIcon.tsx b/src/panelWebView/components/Icons/AddIcon.tsx index 07749627..204b8e26 100644 --- a/src/panelWebView/components/Icons/AddIcon.tsx +++ b/src/panelWebView/components/Icons/AddIcon.tsx @@ -1,10 +1,8 @@ import * as React from 'react'; -export interface IAddIconProps {} +export interface IAddIconProps { } -export const AddIcon: React.FunctionComponent = ( - props: React.PropsWithChildren -) => { +export const AddIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const ArchiveIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const BugIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const CenterIcon: React.FunctionComponent = () => { return ( = (props: React.PropsWithChildren) => { +export const CopilotIcon: React.FunctionComponent = () => { return ( diff --git a/src/panelWebView/components/Icons/FileIcon.tsx b/src/panelWebView/components/Icons/FileIcon.tsx index 9609e229..c244006a 100644 --- a/src/panelWebView/components/Icons/FileIcon.tsx +++ b/src/panelWebView/components/Icons/FileIcon.tsx @@ -1,10 +1,8 @@ import * as React from 'react'; -export interface IFileIconProps {} +export interface IFileIconProps { } -export const FileIcon: React.FunctionComponent = ( - props: React.PropsWithChildren -) => { +export const FileIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const FolderOpenedIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const ListUnorderedIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const RocketIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const SettingsIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const SymbolKeywordIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const TagIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const TemplateIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const ToggleIcon: React.FunctionComponent = () => { return ( = ( - props: React.PropsWithChildren -) => { +export const WritingIcon: React.FunctionComponent = () => { return ( void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any onSchemaUpdate: (schema: any) => void; } diff --git a/src/panelWebView/components/Metadata.tsx b/src/panelWebView/components/Metadata.tsx index d84017c0..d4d6da76 100644 --- a/src/panelWebView/components/Metadata.tsx +++ b/src/panelWebView/components/Metadata.tsx @@ -40,6 +40,7 @@ const Metadata: React.FunctionComponent = ({ }); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any const onSendUpdate = React.useCallback((field: string | undefined, value: any, parents: string[]) => { if (!field) { return; @@ -58,6 +59,7 @@ const Metadata: React.FunctionComponent = ({ parent: IMetadata, parentFields: string[] = [], blockData?: BlockFieldData, + // eslint-disable-next-line @typescript-eslint/no-explicit-any onFieldUpdate?: (field: string | undefined, value: any, parents: string[]) => void, parentBlock?: string | null ): (JSX.Element | null)[] | undefined => { diff --git a/src/panelWebView/components/OtherActions.tsx b/src/panelWebView/components/OtherActions.tsx index 5d3401d9..1bfe34d4 100644 --- a/src/panelWebView/components/OtherActions.tsx +++ b/src/panelWebView/components/OtherActions.tsx @@ -26,10 +26,6 @@ const OtherActions: React.FunctionComponent = ({ settings, isBase }: React.PropsWithChildren) => { - const openSettings = () => { - Messenger.send(CommandToCode.openSettings); - }; - const openFile = () => { Messenger.send(CommandToCode.openFile); }; diff --git a/src/panelWebView/components/Preview.tsx b/src/panelWebView/components/Preview.tsx index 60472e9e..8f38e2e5 100644 --- a/src/panelWebView/components/Preview.tsx +++ b/src/panelWebView/components/Preview.tsx @@ -7,7 +7,7 @@ import { LocalizationKey } from '../../localization'; export interface IPreviewProps { } -const Preview: React.FunctionComponent = (_: React.PropsWithChildren) => { +const Preview: React.FunctionComponent = () => { const open = () => { Messenger.send(CommandToCode.openPreview); }; diff --git a/src/panelWebView/components/SeoFieldInfo.tsx b/src/panelWebView/components/SeoFieldInfo.tsx index 8d15a1e4..8b30bde3 100644 --- a/src/panelWebView/components/SeoFieldInfo.tsx +++ b/src/panelWebView/components/SeoFieldInfo.tsx @@ -4,8 +4,8 @@ import { VSCodeTableCell, VSCodeTableRow } from './VSCode/VSCodeTable'; export interface ISeoFieldInfoProps { title: string; - value: any; - recommendation: any; + value: string; + recommendation: string; isValid?: boolean; } diff --git a/src/panelWebView/components/SeoStatus.tsx b/src/panelWebView/components/SeoStatus.tsx index 1e85bc62..f7bf280e 100644 --- a/src/panelWebView/components/SeoStatus.tsx +++ b/src/panelWebView/components/SeoStatus.tsx @@ -14,6 +14,7 @@ import useContentType from '../../hooks/useContentType'; export interface ISeoStatusProps { seo: SEO; + // eslint-disable-next-line @typescript-eslint/no-explicit-any metadata: any; settings: PanelSettings | undefined; focusElm: TagType | null; diff --git a/src/panelWebView/components/SlugAction.tsx b/src/panelWebView/components/SlugAction.tsx index 880f8181..5f7badf0 100644 --- a/src/panelWebView/components/SlugAction.tsx +++ b/src/panelWebView/components/SlugAction.tsx @@ -9,7 +9,7 @@ export interface ISlugActionProps { } const SlugAction: React.FunctionComponent< ISlugActionProps -> = ({ }: React.PropsWithChildren) => { +> = () => { const optimize = () => { Messenger.send(CommandToCode.updateSlug); }; diff --git a/src/panelWebView/components/Spinner.tsx b/src/panelWebView/components/Spinner.tsx index b81380dc..542e162e 100644 --- a/src/panelWebView/components/Spinner.tsx +++ b/src/panelWebView/components/Spinner.tsx @@ -1,12 +1,8 @@ import * as React from 'react'; -import * as l10n from '@vscode/l10n'; -import { LocalizationKey } from '../../localization'; export interface ISpinnerProps { } -const Spinner: React.FunctionComponent = ( - _: React.PropsWithChildren -) => { +const Spinner: React.FunctionComponent = () => { return (
diff --git a/src/panelWebView/components/StartServerButton.tsx b/src/panelWebView/components/StartServerButton.tsx index a33f327d..72441cc0 100644 --- a/src/panelWebView/components/StartServerButton.tsx +++ b/src/panelWebView/components/StartServerButton.tsx @@ -26,7 +26,7 @@ export const StartServerButton: React.FunctionComponent Messenger.send(CommandToCode.stopServer); }; - const messageListener = (message: MessageEvent>) => { + const messageListener = (message: MessageEvent>) => { const { command, payload } = message.data; if (command === Command.serverStarted) { diff --git a/src/panelWebView/hooks/useMessages.tsx b/src/panelWebView/hooks/useMessages.tsx index c72785c3..099693e3 100644 --- a/src/panelWebView/hooks/useMessages.tsx +++ b/src/panelWebView/hooks/useMessages.tsx @@ -12,6 +12,7 @@ import { useRecoilState } from 'recoil'; import { PanelSettingsAtom } from '../state'; export default function useMessages() { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const [metadata, setMetadata] = useState(undefined); const [settings, setSettings] = useRecoilState(PanelSettingsAtom); const [loading, setLoading] = useState(false); @@ -20,6 +21,7 @@ export default function useMessages() { const [mediaSelecting, setMediaSelecting] = useState(undefined); const [mode, setMode] = useState(undefined); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const messageListener = (event: MessageEvent>) => { const message = event.data; diff --git a/src/panelWebView/hooks/useStartCommand.tsx b/src/panelWebView/hooks/useStartCommand.tsx index 9dea38eb..c6a83889 100644 --- a/src/panelWebView/hooks/useStartCommand.tsx +++ b/src/panelWebView/hooks/useStartCommand.tsx @@ -11,7 +11,7 @@ export default function useStartCommand(settings?: PanelSettings) { return; } - let command: string = ''; + let command = ''; if (settings?.framework) { const framework = FrameworkDetectors.find((f) => f.framework.name === settings.framework); if (framework?.commands?.start) { diff --git a/src/panelWebView/index.tsx b/src/panelWebView/index.tsx index f8752ac3..78e1a5a4 100644 --- a/src/panelWebView/index.tsx +++ b/src/panelWebView/index.tsx @@ -9,6 +9,7 @@ import 'vscrui/dist/codicon.css'; import './styles.css'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars declare const acquireVsCodeApi: () => { getState: () => T; setState: (data: T) => void; @@ -43,4 +44,8 @@ if (elm) { } // Webpack HMR -if ((module as any).hot) (module as any).hot.accept(); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +if ((module as any).hot) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (module as any).hot.accept(); +} diff --git a/src/parsers/FrontMatterParser.ts b/src/parsers/FrontMatterParser.ts index 2176bd7a..479a4622 100644 --- a/src/parsers/FrontMatterParser.ts +++ b/src/parsers/FrontMatterParser.ts @@ -42,7 +42,8 @@ export class FrontMatterParser { * @param options * @returns */ - public static toFile(content: string, metadata: Object, originalContent?: string, options?: any) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + public static toFile(content: string, metadata: any, originalContent?: string, options?: any) { // Stringify to YAML if the format was not set const format = getFormatOpts(this.getLanguageFromContent(originalContent)); diff --git a/src/parsers/ParserEngines.ts b/src/parsers/ParserEngines.ts index 39d226ab..97191921 100644 --- a/src/parsers/ParserEngines.ts +++ b/src/parsers/ParserEngines.ts @@ -72,7 +72,7 @@ export const Engines = { // Update all the new values for (const key in obj) { - let value = obj[key]; + const value = obj[key]; docYaml.set(key, removeCarriageReturn(value)); } @@ -83,7 +83,7 @@ export const Engines = { } } - let updatedValue = docYaml.toJSON(); + const updatedValue = docYaml.toJSON(); const quoteStrings = Settings.get(SETTING_QUOTE_STRINGS); @@ -143,6 +143,8 @@ const getMatter = (value: string): string | null => { }; const startsWith = (str: string, substr: string, len: number) => { - if (typeof len !== 'number') len = substr.length; + if (typeof len !== 'number') { + len = substr.length; + } return str.slice(0, len) === substr; }; diff --git a/src/providers/MarkdownFoldingProvider.ts b/src/providers/MarkdownFoldingProvider.ts index 127af00d..2f2758d3 100644 --- a/src/providers/MarkdownFoldingProvider.ts +++ b/src/providers/MarkdownFoldingProvider.ts @@ -6,8 +6,6 @@ import { ThemeColor } from 'vscode'; import { ArticleHelper } from '../helpers'; import { commands, DecorationOptions, languages, TextEditorDecorationType } from 'vscode'; import { - CancellationToken, - FoldingContext, FoldingRange, FoldingRangeKind, FoldingRangeProvider, @@ -49,11 +47,7 @@ export class MarkdownFoldingProvider implements FoldingRangeProvider { } } - public async provideFoldingRanges( - document: TextDocument, - context: FoldingContext, - token: CancellationToken - ): Promise { + public async provideFoldingRanges(document: TextDocument): Promise { const ranges: FoldingRange[] = []; const range = MarkdownFoldingProvider.getFrontMatterRange(document); @@ -66,7 +60,7 @@ export class MarkdownFoldingProvider implements FoldingRangeProvider { return ranges; } - public static triggerHighlighting(configChange: boolean = false) { + public static triggerHighlighting(configChange = false) { const activeDoc = window.activeTextEditor?.document; if (configChange && this.crntDecoration) { diff --git a/src/services/Copilot.ts b/src/services/Copilot.ts index cb31523a..e1123553 100644 --- a/src/services/Copilot.ts +++ b/src/services/Copilot.ts @@ -159,7 +159,7 @@ Example: SEO, website optimization, digital marketing.` ); } - let options = + const options = tagType === TagType.tags ? await TaxonomyHelper.get(TaxonomyType.Tag) : await TaxonomyHelper.get(TaxonomyType.Category); @@ -217,7 +217,7 @@ Example: SEO, website optimization, digital marketing.` return; } - let allFragments = []; + const allFragments = []; for await (const fragment of chatResponse.text) { allFragments.push(fragment); } diff --git a/src/services/ModeSwitch.ts b/src/services/ModeSwitch.ts index 6314b180..5b0c8a08 100644 --- a/src/services/ModeSwitch.ts +++ b/src/services/ModeSwitch.ts @@ -12,7 +12,7 @@ import * as l10n from '@vscode/l10n'; import { LocalizationKey } from '../localization'; export class ModeSwitch { - private static isInit: boolean = false; + private static isInit = false; private static statusBarElm: StatusBarItem; private static currentMode: string; diff --git a/src/services/PagesParser.ts b/src/services/PagesParser.ts index 50de93ec..bd2e339f 100644 --- a/src/services/PagesParser.ts +++ b/src/services/PagesParser.ts @@ -32,7 +32,7 @@ export class PagesParser { public static allPages: Page[] = []; public static cachedPages: Page[] | undefined = undefined; private static parser: Promise | undefined; - private static initialized: boolean = false; + private static initialized = false; private static pagesStatusBar = window.createStatusBarItem(StatusBarAlignment.Left); /** @@ -266,7 +266,7 @@ export class PagesParser { } } // Retrieve the tags from the artilce - let tagParents = ContentType.findFieldsByTypeDeep(contentType.fields, 'tags'); + const tagParents = ContentType.findFieldsByTypeDeep(contentType.fields, 'tags'); if (tagParents.length > 0) { const firstField = tagParents[0]; if (firstField.length > 0) { @@ -279,7 +279,7 @@ export class PagesParser { } // Retrieve the categories from the artilce - let categoryParents = ContentType.findFieldsByTypeDeep(contentType.fields, 'categories'); + const categoryParents = ContentType.findFieldsByTypeDeep(contentType.fields, 'categories'); if (categoryParents.length > 0) { const firstField = categoryParents[0]; if (firstField.length > 0) { @@ -355,7 +355,7 @@ export class PagesParser { } if (previewUri) { - let previewPath: string = ''; + let previewPath = ''; const Webview = Dashboard.getWebview(); if (Webview) { diff --git a/src/services/SponsorAI.ts b/src/services/SponsorAI.ts index 9d5df6ef..bf1abe20 100644 --- a/src/services/SponsorAI.ts +++ b/src/services/SponsorAI.ts @@ -80,6 +80,7 @@ export class SponsorAi { token: token, nrOfCharacters: Settings.get(SETTING_SEO_DESCRIPTION_LENGTH) || 160 }), + // eslint-disable-next-line @typescript-eslint/no-explicit-any signal: signal as any } ); @@ -118,7 +119,7 @@ export class SponsorAi { }, 10000); const signal = controller.signal; - let options = + const options = type === TagType.tags ? await TaxonomyHelper.get(TaxonomyType.Tag) : await TaxonomyHelper.get(TaxonomyType.Category); diff --git a/src/services/Terminal.ts b/src/services/Terminal.ts index ae17710d..fa6b2ff3 100644 --- a/src/services/Terminal.ts +++ b/src/services/Terminal.ts @@ -84,7 +84,7 @@ export class Terminal { * @returns */ public static findLocalServerTerminal() { - let terminals = window.terminals; + const terminals = window.terminals; if (terminals) { const localServerTerminal = terminals.find((t) => t.name === Terminal.terminalName); return localServerTerminal; diff --git a/src/services/Translations.ts b/src/services/Translations.ts index 56a4aa1b..7ac60a06 100644 --- a/src/services/Translations.ts +++ b/src/services/Translations.ts @@ -102,7 +102,7 @@ export class Translations { target_lang: target }); - let host = deeplAuthKey.endsWith(':fx') ? 'api-free.deepl.com' : 'api.deepl.com'; + const host = deeplAuthKey.endsWith(':fx') ? 'api-free.deepl.com' : 'api.deepl.com'; const response = await fetch(`https://${host}/v2/translate`, { method: 'POST', diff --git a/src/utils/fieldWhenClause.ts b/src/utils/fieldWhenClause.ts index 6d3f4c68..807ab89a 100644 --- a/src/utils/fieldWhenClause.ts +++ b/src/utils/fieldWhenClause.ts @@ -14,7 +14,7 @@ export const fieldWhenClause = (field: Field, parent: IMetadata, allFields?: Fie return true; } - let parentField = allFields?.find((f) => f.name === when.fieldRef); + const parentField = allFields?.find((f) => f.name === when.fieldRef); if (parentField && parentField.when) { const renderParent = fieldWhenClause(parentField, parent, allFields); if (!renderParent) { @@ -22,7 +22,7 @@ export const fieldWhenClause = (field: Field, parent: IMetadata, allFields?: Fie } } - let whenValue = parent[when.fieldRef]; + const whenValue = parent[when.fieldRef]; if (when.caseSensitive || typeof when.caseSensitive === 'undefined') { return caseSensitive(when, field, whenValue); } else { @@ -42,7 +42,9 @@ const caseInsensitive = ( field: Field, whenValue: string | IMetadata | string[] | null ) => { - whenValue = lowerValue(whenValue); + if (whenValue) { + whenValue = lowerValue(whenValue); + } const whenClone = Object.assign({}, when); whenClone.value = lowerValue(whenClone.value); @@ -131,7 +133,7 @@ const caseSensitive = ( * @param value - The string or array of strings to convert to lowercase. * @returns The converted string or array of strings. */ -const lowerValue = (value: string | string[] | any) => { +const lowerValue = (value: string | string[] | IMetadata) => { if (typeof value === 'string') { value = value.toLowerCase(); } else if (value instanceof Array) { diff --git a/src/utils/flattenObjectKeys.ts b/src/utils/flattenObjectKeys.ts index 0e129c62..ff891877 100644 --- a/src/utils/flattenObjectKeys.ts +++ b/src/utils/flattenObjectKeys.ts @@ -1,6 +1,7 @@ import { join } from 'path'; -export const flattenObjectKeys = (obj: any, crntKey: string = '') => { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const flattenObjectKeys = (obj: any, crntKey = '') => { let toReturn: string[] = []; const keys = Object.keys(obj); diff --git a/src/utils/sortPages.ts b/src/utils/sortPages.ts index 81d1a2b3..31760513 100644 --- a/src/utils/sortPages.ts +++ b/src/utils/sortPages.ts @@ -9,13 +9,13 @@ export const sortPages = (pages: Page[], sorting: SortingOption | null) => { } else if (sorting && sorting.id === SortOption.FileNameDesc) { pages = pages.sort(Sorting.alphabetically('fmFileName')).reverse(); } else if (sorting && sorting.id === SortOption.PublishedAsc) { - pages = pages.sort(Sorting.number('fmPublished')); + pages = pages.sort(Sorting.numerically('fmPublished')); } else if (sorting && sorting.id === SortOption.LastModifiedAsc) { - pages = pages.sort(Sorting.number('fmModified')); + pages = pages.sort(Sorting.numerically('fmModified')); } else if (sorting && sorting.id === SortOption.PublishedDesc) { - pages = pages.sort(Sorting.number('fmPublished')).reverse(); + pages = pages.sort(Sorting.numerically('fmPublished')).reverse(); } else if (sorting && sorting.id === SortOption.LastModifiedDesc) { - pages = pages.sort(Sorting.number('fmModified')).reverse(); + pages = pages.sort(Sorting.numerically('fmModified')).reverse(); } else if (sorting && sorting.id && sorting.name) { const { order, name, type } = sorting; @@ -24,14 +24,14 @@ export const sortPages = (pages: Page[], sorting: SortingOption | null) => { } else if (type === SortType.date) { pages = pages.sort(Sorting.date(name)); } else if (type === SortType.number) { - pages = pages.sort(Sorting.number(name)); + pages = pages.sort(Sorting.numerically(name)); } if (order === SortOrder.desc) { pages = pages.reverse(); } } else { - pages = pages.sort(Sorting.number('fmModified')).reverse(); + pages = pages.sort(Sorting.numerically('fmModified')).reverse(); } return pages; diff --git a/webpack/dashboard.config.js b/webpack/dashboard.config.js index eb295df8..3e759a10 100644 --- a/webpack/dashboard.config.js +++ b/webpack/dashboard.config.js @@ -1,11 +1,13 @@ 'use strict'; +/* eslint-disable */ const path = require('path'); const { ProvidePlugin } = require('webpack'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const WebpackManifestPlugin = require('webpack-manifest-plugin').WebpackManifestPlugin; +const ESLintPlugin = require('eslint-webpack-plugin'); const config = [{ name: 'dashboard', @@ -60,6 +62,11 @@ const config = [{ new WebpackManifestPlugin({ publicPath: "", fileName: "dashboard.manifest.json" + }), + new ESLintPlugin({ + extensions: ['ts', 'tsx'], + exclude: ['node_modules', 'dist'], + emitWarning: false, }) ], devServer: { diff --git a/webpack/extension.config.js b/webpack/extension.config.js index 1c5b0c3d..b6425d9c 100644 --- a/webpack/extension.config.js +++ b/webpack/extension.config.js @@ -2,9 +2,12 @@ 'use strict'; + +/* eslint-disable */ const path = require('path'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const IgnoreDynamicRequire = require('webpack-ignore-dynamic-require'); +const ESLintPlugin = require('eslint-webpack-plugin'); const config = [ { @@ -58,7 +61,11 @@ const config = [ } }, plugins: [ - new IgnoreDynamicRequire() + new IgnoreDynamicRequire(), + new ESLintPlugin({ + extensions: ['ts'], + emitWarning: false, + }) ] } ]; diff --git a/webpack/panel.config.js b/webpack/panel.config.js index 86fc321f..217dd784 100644 --- a/webpack/panel.config.js +++ b/webpack/panel.config.js @@ -1,8 +1,10 @@ 'use strict'; +/* eslint-disable */ const path = require('path'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const WebpackManifestPlugin = require('webpack-manifest-plugin').WebpackManifestPlugin; +const ESLintPlugin = require('eslint-webpack-plugin'); const config = [{ name: 'panel', @@ -62,6 +64,11 @@ const config = [{ new WebpackManifestPlugin({ publicPath: "", fileName: "panel.manifest.json" + }), + new ESLintPlugin({ + extensions: ['ts', 'tsx'], + exclude: ['node_modules', 'dist'], + emitWarning: false, }) ], devServer: {