From 117c5fa3fdbd2787bc1df521627b7b07fc1522c6 Mon Sep 17 00:00:00 2001 From: Antonio Mika Date: Tue, 23 Aug 2022 03:26:07 -0400 Subject: [PATCH] Added client type checking to webpack (#4619) * Added client type checking * Fixed client-side typescript issues --- client/js/helpers/collapseNetwork.ts | 4 +- client/js/helpers/contextMenu.ts | 13 ++++-- client/js/helpers/parseIrcUri.ts | 14 ++++--- client/js/store.ts | 6 +-- client/tsconfig.json | 33 ++++++++++++++- package.json | 1 + server/plugins/changelog.ts | 2 + webpack.config.ts | 31 ++++++++++---- yarn.lock | 61 +++++++++++++++++++++++++--- 9 files changed, 137 insertions(+), 28 deletions(-) diff --git a/client/js/helpers/collapseNetwork.ts b/client/js/helpers/collapseNetwork.ts index dd598e92..5432bb0e 100644 --- a/client/js/helpers/collapseNetwork.ts +++ b/client/js/helpers/collapseNetwork.ts @@ -1,7 +1,9 @@ import storage from "../localStorage"; export default (network, isCollapsed) => { - const networks = new Set(JSON.parse(storage.get("thelounge.networks.collapsed"))); + const stored = storage.get("thelounge.networks.collapsed"); + const networks = stored ? new Set(JSON.parse(stored)) : new Set(); + network.isCollapsed = isCollapsed; if (isCollapsed) { diff --git a/client/js/helpers/contextMenu.ts b/client/js/helpers/contextMenu.ts index 73db9692..66ce5d2b 100644 --- a/client/js/helpers/contextMenu.ts +++ b/client/js/helpers/contextMenu.ts @@ -250,10 +250,15 @@ export function generateInlineChannelContextMenu( switchToChannel(channel); } - socket.emit("input", { - target: store.state.activeChannel.channel.id, - text: "/join " + chan, - }); + if (store.state.activeChannel) { + socket.emit("input", { + target: store.state.activeChannel.channel.id, + text: "/join " + chan, + }); + } else { + // eslint-disable-next-line no-console + console.error("Unable to join channel: activeChannel is undefined"); + } }; const channel = network.channels.find((c) => c.name === chan); diff --git a/client/js/helpers/parseIrcUri.ts b/client/js/helpers/parseIrcUri.ts index 22ed3c56..05d6d067 100644 --- a/client/js/helpers/parseIrcUri.ts +++ b/client/js/helpers/parseIrcUri.ts @@ -1,5 +1,11 @@ export default (stringUri: string) => { - const data = {}; + const data = { + name: "", + host: "", + port: "", + join: "", + tls: false, + }; try { // https://tools.ietf.org/html/draft-butcher-irc-url-04 @@ -11,15 +17,13 @@ export default (stringUri: string) => { uri.protocol = "http:"; if (!uri.port) { - uri.port = 6667; + uri.port = "6667"; } - - data.tls = false; } else if (uri.protocol === "ircs:") { uri.protocol = "https:"; if (!uri.port) { - uri.port = 6697; + uri.port = "6697"; } data.tls = true; diff --git a/client/js/store.ts b/client/js/store.ts index d105a5d9..171a8c56 100644 --- a/client/js/store.ts +++ b/client/js/store.ts @@ -67,16 +67,16 @@ export type State = { | null | undefined | { - latest: { + latest?: { version: string; prerelease: boolean; url: string; }; - current: { + current?: { version: string; prerelease: boolean; url: string; - changelog: string; + changelog?: string; }; }; versionStatus: "loading" | "new-version" | "new-packages" | "up-to-date" | "error"; diff --git a/client/tsconfig.json b/client/tsconfig.json index d29fc35e..f5434d2c 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -6,9 +6,38 @@ "files": [ "../package.json", "../server/types/socket-events.d.ts", + "../server/helper.ts", + "../server/log.ts", + "../server/config.ts", + "../server/client.ts", + "../server/clientManager.ts", + "../server/identification.ts", + "../server/plugins/changelog.ts", + "../server/plugins/uploader.ts", + "../server/plugins/storage.ts", + "../server/plugins/inputs/index.ts", + "../server/plugins/messageStorage/sqlite.ts", + "../server/plugins/messageStorage/text.ts", + "../server/plugins/packages/index.ts", + "../server/plugins/packages/publicClient.ts", + "../server/plugins/packages/themes.ts", + "../server/plugins/dev-server.ts", + "../server/plugins/webpush.ts", + "../server/plugins/sts.ts", + "../server/plugins/clientCertificate.ts", + "../server/plugins/auth.ts", + "../server/plugins/auth/local.ts", + "../server/plugins/auth/ldap.ts", + "../server/plugins/irc-events/link.ts", + "../server/command-line/utils.ts", + "../server/models/network.ts", + "../server/models/user.ts", + "../server/models/msg.ts", + "../server/models/prefix.ts", "./js/helpers/fullnamemap.json", "./js/helpers/simplemap.json", - "../server/helper.ts" + "../webpack.config.ts", + "../babel.config.cjs" ] /* If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. When a 'files' property is specified, only those files and those specified by 'include' are included. */, // "exclude": [], "compilerOptions": { @@ -19,7 +48,7 @@ // this enables stricter inference for data properties on `this` "strict": true, // if using webpack 2+ or rollup, to leverage tree shaking: - "module": "es2015", + "module": "es2020", "moduleResolution": "node", // TODO: Remove eventually diff --git a/package.json b/package.json index 6d32570e..200cf5ad 100644 --- a/package.json +++ b/package.json @@ -123,6 +123,7 @@ "eslint-config-prettier": "8.3.0", "eslint-define-config": "1.5.1", "eslint-plugin-vue": "9.0.1", + "fork-ts-checker-webpack-plugin": "7.2.13", "fuzzy": "0.1.3", "husky": "4.3.8", "mini-css-extract-plugin": "2.5.3", diff --git a/server/plugins/changelog.ts b/server/plugins/changelog.ts index 01e4039b..900c1d1f 100644 --- a/server/plugins/changelog.ts +++ b/server/plugins/changelog.ts @@ -13,8 +13,10 @@ export default { }; export type ChangelogData = { current: { + prerelease: boolean; version: string; changelog?: string; + url: string; }; expiresAt: number; latest?: { diff --git a/webpack.config.ts b/webpack.config.ts index 2c412c73..b103b2a4 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -1,11 +1,28 @@ import * as webpack from "webpack"; import * as path from "path"; import CopyPlugin from "copy-webpack-plugin"; +import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin"; import MiniCssExtractPlugin from "mini-css-extract-plugin"; import {VueLoaderPlugin} from "vue-loader"; import babelConfig from "./babel.config.cjs"; import Helper from "./server/helper"; +const tsCheckerPlugin = new ForkTsCheckerWebpackPlugin({ + typescript: { + diagnosticOptions: { + semantic: true, + syntactic: true, + }, + build: true, + }, +}); + +const vueLoaderPlugin = new VueLoaderPlugin(); + +const miniCssExtractPlugin = new MiniCssExtractPlugin({ + filename: "css/style.css", +}); + const isProduction = process.env.NODE_ENV === "production"; const config: webpack.Configuration = { mode: isProduction ? "production" : "development", @@ -90,14 +107,13 @@ const config: webpack.Configuration = { json3: "JSON", // socket.io uses json3.js, but we do not target any browsers that need it }, plugins: [ - new VueLoaderPlugin(), + tsCheckerPlugin, + vueLoaderPlugin, new webpack.DefinePlugin({ __VUE_PROD_DEVTOOLS__: false, __VUE_OPTIONS_API__: false, }), - new MiniCssExtractPlugin({ - filename: "css/style.css", - }), + miniCssExtractPlugin, new CopyPlugin({ patterns: [ { @@ -183,10 +199,9 @@ export default (env: any, argv: any) => { // Disable plugins like copy files, it is not required config.plugins = [ - new VueLoaderPlugin(), - new MiniCssExtractPlugin({ - filename: "css/style.css", - }), + tsCheckerPlugin, + vueLoaderPlugin, + miniCssExtractPlugin, // Client tests that require Vue may end up requireing socket.io new webpack.NormalModuleReplacementPlugin( /js(\/|\\)socket\.js/, diff --git a/yarn.lock b/yarn.lock index 8a38431b..81246656 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2602,7 +2602,7 @@ chai@4.3.6: pathval "^1.1.1" type-detect "^4.0.5" -chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0: +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2656,7 +2656,7 @@ cheerio@1.0.0-rc.10: parse5-htmlparser2-tree-adapter "^6.0.1" tslib "^2.2.0" -chokidar@3.5.3: +chokidar@3.5.3, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -3130,6 +3130,11 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + default-require-extensions@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-3.0.0.tgz#e03f93aac9b2b6443fc52e5e4a37b3ad9ad8df96" @@ -3815,6 +3820,24 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" +fork-ts-checker-webpack-plugin@7.2.13: + version "7.2.13" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.13.tgz#51ffd6a2f96f03ab64b92f8aedf305dbf3dee0f1" + integrity sha512-fR3WRkOb4bQdWB/y7ssDUlVdrclvwtyCUIHCfivAoYxq9dF7XfrDKbMdZIfwJ7hxIAqkYSGeU7lLJE6xrxIBdg== + dependencies: + "@babel/code-frame" "^7.16.7" + chalk "^4.1.2" + chokidar "^3.5.3" + cosmiconfig "^7.0.1" + deepmerge "^4.2.2" + fs-extra "^10.0.0" + memfs "^3.4.1" + minimatch "^3.0.4" + node-abort-controller "^3.0.1" + schema-utils "^3.1.1" + semver "^7.3.5" + tapable "^2.2.1" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -3835,6 +3858,15 @@ fromentries@^1.2.0: resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -4087,7 +4119,7 @@ got@11.8.5, got@^11.8.2: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -4785,6 +4817,15 @@ json5@^2.1.2, json5@^2.2.1: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + just-extend@^4.0.2: version "4.2.1" resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" @@ -5047,7 +5088,7 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -memfs@^3.2.2: +memfs@^3.2.2, memfs@^3.4.1: version "3.4.7" resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== @@ -5381,6 +5422,11 @@ nise@^5.1.0: just-extend "^4.0.2" path-to-regexp "^1.7.0" +node-abort-controller@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.0.1.tgz#f91fa50b1dee3f909afabb7e261b1e1d6b0cb74e" + integrity sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw== + node-addon-api@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" @@ -7395,7 +7441,7 @@ table@^6.8.0: string-width "^4.2.3" strip-ansi "^6.0.1" -tapable@^2.1.1, tapable@^2.2.0: +tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== @@ -7674,6 +7720,11 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"