fix yarn build and start

This commit is contained in:
Max Leiter 2022-05-04 21:10:12 -07:00
parent a607924a2b
commit 1d2dc40985
No known key found for this signature in database
GPG key ID: A3512F2F2F17EBDA
20 changed files with 173 additions and 90 deletions

View file

@ -1,15 +1,32 @@
module.exports = { module.exports = {
root: true, root: true,
overrides: [
{
files: ["**/*.ts"],
parser: "@typescript-eslint/parser",
parserOptions: {
tsconfigRootDir: __dirname,
parser: "@typescript-eslint/parser",
project: ["./tsconfig.json", "./client/tsconfig.json", "./src/tsconfig.json"],
},
plugins: ["@typescript-eslint"],
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"prettier",
],
},
],
parserOptions: { parserOptions: {
ecmaVersion: 2022, ecmaVersion: 2022,
parser: "@typescript-eslint/parser", // sourceType: "module",
sourceType: "module",
// project: ["./eslint.tsconfig.json"], // project: ["./eslint.tsconfig.json"],
// extraFileExtensions: [".vue", ".cjs"], // extraFileExtensions: [".vue", ".cjs"],
}, },
// TODO: this should just be for client? // TODO: this should just be for client?
parser: "vue-eslint-parser", parser: "vue-eslint-parser",
plugins: ["vue", "@typescript-eslint"], plugins: ["vue"],
env: { env: {
es6: true, es6: true,
browser: true, browser: true,

1
.gitignore vendored
View file

@ -7,3 +7,4 @@ package-lock.json
coverage/ coverage/
public/ public/
client/dist client/dist
src/dist

View file

@ -1,8 +1,7 @@
{ {
"extends": "../tsconfig.base.json", "extends": "../tsconfig.base.json",
"include": ["./**/*", "../src/models/*"], "include": ["./**/*"],
"files": [ "files": [
"../src/types/models/channel.d.ts",
"js/helpers/simplemap.json", "js/helpers/simplemap.json",
"js/helpers/fullnamemap.json", "js/helpers/fullnamemap.json",
"../package.json", "../package.json",

View file

@ -1,4 +0,0 @@
{
"extends": "./tsconfig.base.json",
"include": ["src/**/*.ts", "client/**/*.ts", "test/**/*.ts", "scripts/**/*.{ts,js}"]
}

View file

@ -13,15 +13,16 @@
"homepage": "https://thelounge.chat/", "homepage": "https://thelounge.chat/",
"scripts": { "scripts": {
"build:client": "webpack", "build:client": "webpack",
"build:server": "tsc -p src/tsconfig.json src/index.ts", "build:server": "tsc -p src/tsconfig.json",
"build": "run-p --aggregate-output build:client build:server",
"coverage": "run-s test:* && nyc --nycrc-path=test/.nycrc-report.json report", "coverage": "run-s test:* && nyc --nycrc-path=test/.nycrc-report.json report",
"dev": "ts-node --project src/tsconfig.json src/index.ts start --dev", "dev": "NODE_ENV=development ts-node --project src/tsconfig.json src/index.ts start --dev",
"format:prettier": "prettier --write \"**/*.*\"", "format:prettier": "prettier --write \"**/*.*\"",
"lint:check-eslint": "eslint-config-prettier .eslintrc.cjs", "lint:check-eslint": "eslint-config-prettier .eslintrc.cjs",
"lint:eslint": "eslint . --ext .js,.vue --report-unused-disable-directives --color", "lint:eslint": "eslint . --ext .js,.vue --report-unused-disable-directives --color",
"lint:prettier": "prettier --list-different \"**/*.*\"", "lint:prettier": "prettier --list-different \"**/*.*\"",
"lint:stylelint": "stylelint --color \"client/**/*.css\"", "lint:stylelint": "stylelint --color \"client/**/*.css\"",
"start": "ts-node src/index start", "start": "node src/dist/src/index start",
"test": "run-p --aggregate-output --continue-on-error lint:* test:*", "test": "run-p --aggregate-output --continue-on-error lint:* test:*",
"test:mocha": "webpack --mode=development && nyc --nycrc-path=test/.nycrc-mocha.json mocha --colors --config=test/.mocharc.yml", "test:mocha": "webpack --mode=development && nyc --nycrc-path=test/.nycrc-mocha.json mocha --colors --config=test/.mocharc.yml",
"watch": "webpack --watch" "watch": "webpack --watch"
@ -84,6 +85,7 @@
"@textcomplete/textarea": "0.1.10", "@textcomplete/textarea": "0.1.10",
"@types/bcryptjs": "2.4.2", "@types/bcryptjs": "2.4.2",
"@types/chai": "4.3.1", "@types/chai": "4.3.1",
"@types/cheerio": "0.22.31",
"@types/content-disposition": "0.5.4", "@types/content-disposition": "0.5.4",
"@types/express": "4.17.13", "@types/express": "4.17.13",
"@types/is-utf8": "0.2.0", "@types/is-utf8": "0.2.0",
@ -102,6 +104,7 @@
"@types/uuid": "8.3.4", "@types/uuid": "8.3.4",
"@types/web-push": "3.3.2", "@types/web-push": "3.3.2",
"@types/webpack-env": "1.16.4", "@types/webpack-env": "1.16.4",
"@types/webpack-hot-middleware": "2.25.6",
"@types/ws": "8.5.3", "@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "5.22.0", "@typescript-eslint/eslint-plugin": "5.22.0",
"@typescript-eslint/parser": "5.22.0", "@typescript-eslint/parser": "5.22.0",

View file

@ -8,7 +8,6 @@ import Helper from "../helper";
import Config from "../config"; import Config from "../config";
import path from "path"; import path from "path";
import {spawn} from "child_process"; import {spawn} from "child_process";
let home: string; let home: string;
class Utils { class Utils {
@ -28,46 +27,58 @@ class Utils {
return home; return home;
} }
const distConfig = path.resolve(path.join(__dirname, "..", "..", ".thelounge_home")); const distConfig = Utils.getFileFromRelativeToRoot(".thelounge_home");
home = fs.readFileSync(distConfig, "utf-8").trim(); home = fs.readFileSync(distConfig, "utf-8").trim();
return home; return home;
} }
// TODO: handle this more elegantly?
static getFileFromRelativeToRoot(...fileName: string[]) {
if (process.env.NODE_ENV === "test" || process.env.NODE_ENV === "development") {
return path.resolve(path.join(__dirname, "..", "..", ...fileName));
} else {
return path.resolve(path.join(__dirname, "..", "..", "..", "..", ...fileName));
}
}
// Parses CLI options such as `-c public=true`, `-c debug.raw=true`, etc. // Parses CLI options such as `-c public=true`, `-c debug.raw=true`, etc.
static parseConfigOptions(val, memo) { static parseConfigOptions(val: string, memo) {
// Invalid option that is not of format `key=value`, do nothing // Invalid option that is not of format `key=value`, do nothing
if (!val.includes("=")) { if (!val.includes("=")) {
return memo; return memo;
} }
const parseValue = (value) => { const parseValue = (value: string) => {
if (value === "true") { switch (value) {
return true; case "true":
} else if (value === "false") { return true;
return false; case "false":
} else if (value === "undefined") { return false;
return undefined; case "undefined":
} else if (value === "null") { return undefined;
return null; case "null":
} else if (/^-?[0-9]+$/.test(value)) { return null;
// Numbers like port default:
value = parseInt(value, 10); if (/^-?[0-9]+$/.test(value)) {
} else if (/^\[.*\]$/.test(value)) { // Numbers like port
// Arrays return parseInt(value, 10);
// Supporting arrays `[a,b]` and `[a, b]` } else if (/^\[.*\]$/.test(value)) {
const array = value.slice(1, -1).split(/,\s*/); // Arrays
// Supporting arrays `[a,b]` and `[a, b]`
const array = value.slice(1, -1).split(/,\s*/);
// If [] is given, it will be parsed as `[ "" ]`, so treat this as empty // If [] is given, it will be parsed as `[ "" ]`, so treat this as empty
if (array.length === 1 && array[0] === "") { if (array.length === 1 && array[0] === "") {
return []; return [];
} }
return array.map(parseValue); // Re-parses all values of the array return array.map(parseValue); // Re-parses all values of the array
}
return value;
} }
return value;
}; };
// First time the option is parsed, memo is not set // First time the option is parsed, memo is not set

View file

@ -5,8 +5,10 @@ import fs, {Stats} from "fs";
import os from "os"; import os from "os";
import _ from "lodash"; import _ from "lodash";
import colors from "chalk"; import colors from "chalk";
import log from "./log"; import log from "./log";
import Helper from "./helper"; import Helper from "./helper";
import Utils from "./command-line/utils";
// TODO: Type this // TODO: Type this
export type WebIRC = { export type WebIRC = {
@ -224,9 +226,7 @@ class Config {
} }
} }
const manifestPath = path.resolve( const manifestPath = Utils.getFileFromRelativeToRoot("public", "thelounge.webmanifest");
path.join(__dirname, "..", "public", "thelounge.webmanifest")
);
// Check if manifest exists, if not, the app most likely was not built // Check if manifest exists, if not, the app most likely was not built
if (!fs.existsSync(manifestPath)) { if (!fs.existsSync(manifestPath)) {

View file

@ -78,7 +78,7 @@ class Msg {
raw_modes!: any; raw_modes!: any;
when!: Date; when!: Date;
whois!: any; whois!: any;
users!: UserInMessage[]; users!: UserInMessage[] | string[];
statusmsgGroup!: string; statusmsgGroup!: string;
params!: string[]; params!: string[];
@ -104,7 +104,7 @@ class Msg {
self: false, self: false,
}); });
if (this.time?.getTime() > 0) { if (this.time) {
this.time = new Date(this.time); this.time = new Date(this.time);
} else { } else {
this.time = new Date(); this.time = new Date();

View file

@ -282,7 +282,9 @@ class Network {
// Exponential backoff maxes out at 300 seconds after 9 reconnects, // Exponential backoff maxes out at 300 seconds after 9 reconnects,
// it will keep trying for well over an hour (plus the timeouts) // it will keep trying for well over an hour (plus the timeouts)
auto_reconnect_max_retries: 30, auto_reconnect_max_retries: 30,
});
// TODO: this type should be set after setIrcFrameworkOptions
}) as NetworkWithIrcFramework["irc"];
this.setIrcFrameworkOptions(client); this.setIrcFrameworkOptions(client);
@ -473,7 +475,7 @@ class Network {
} }
// TODO: setNick is called in validate() before irc exists. Is that a problem? // TODO: setNick is called in validate() before irc exists. Is that a problem?
if (this.irc) { if (this.irc?.options) {
this.irc.options.nick = nick; this.irc.options.nick = nick;
} }
} }

View file

@ -1,8 +1,11 @@
"use strict"; "use strict";
import log from "../log";
import webpackDevMiddleware from "webpack-dev-middleware"; import webpackDevMiddleware from "webpack-dev-middleware";
import webpackHotMiddleware from "webpack-hot-middleware";
import express from "express";
export default (app) => { import log from "../log";
export default (app: express.Application) => {
log.debug("Starting server in development mode"); log.debug("Starting server in development mode");
const webpack = require("webpack"); const webpack = require("webpack");
@ -23,8 +26,9 @@ export default (app) => {
publicPath: webpackConfig.output?.publicPath, publicPath: webpackConfig.output?.publicPath,
}) })
).use( ).use(
webpackDevMiddleware(compiler, { // TODO: Fix compiler type
publicPath: "/storage/__webpack_hmr", webpackHotMiddleware(compiler as any, {
path: "/storage/__webpack_hmr",
}) })
); );
}; };

View file

@ -11,11 +11,10 @@ import {findLinksWithSchema} from "../../../client/js/helpers/ircmessageparser/f
import storage from "../storage"; import storage from "../storage";
import Client, {IrcEventHandler} from "../../client"; import Client, {IrcEventHandler} from "../../client";
import Chan from "../../models/chan"; import Chan from "../../models/chan";
import Msg from "../../models/msg"; import Msg, {MessagePreview} from "../../models/msg";
import {Cheerio} from "cheerio";
type FetchRequest = { type FetchRequest = {
data: Record<string, any>; data: Buffer;
type: string; type: string;
size: number; size: number;
}; };
@ -23,7 +22,7 @@ const currentFetchPromises = new Map<string, Promise<FetchRequest>>();
const imageTypeRegex = /^image\/.+/; const imageTypeRegex = /^image\/.+/;
const mediaTypeRegex = /^(audio|video)\/.+/; const mediaTypeRegex = /^(audio|video)\/.+/;
type Preview = { type LinkPreview = {
type: string; type: string;
head: string; head: string;
body: string; body: string;
@ -40,11 +39,11 @@ export default function (client: Client, chan: Chan, msg: Msg, cleanText: string
return; return;
} }
msg.previews = findLinksWithSchema(cleanText).reduce((cleanLinks: Preview[], link) => { msg.previews = findLinksWithSchema(cleanText).reduce((cleanLinks: LinkPreview[], link) => {
const url = normalizeURL(link.link); const url = normalizeURL(link.link);
// If the URL is invalid and cannot be normalized, don't fetch it // If the URL is invalid and cannot be normalized, don't fetch it
if (url === null) { if (!url) {
return cleanLinks; return cleanLinks;
} }
@ -58,7 +57,7 @@ export default function (client: Client, chan: Chan, msg: Msg, cleanText: string
return cleanLinks; return cleanLinks;
} }
const preview: Preview = { const preview: LinkPreview = {
type: "loading", type: "loading",
head: "", head: "",
body: "", body: "",
@ -74,7 +73,7 @@ export default function (client: Client, chan: Chan, msg: Msg, cleanText: string
fetch(url, { fetch(url, {
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
language: client.config.browser?.language, language: client.config.browser?.language || "",
}) })
.then((res) => { .then((res) => {
parse(msg, chan, preview, res, client); parse(msg, chan, preview, res, client);
@ -133,7 +132,7 @@ function parseHtml(preview, res, client: Client) {
// Verify that thumbnail pic exists and is under allowed size // Verify that thumbnail pic exists and is under allowed size
if (thumb.length) { if (thumb.length) {
fetch(thumb, {language: client.config.browser?.language}) fetch(thumb, {language: client.config.browser?.language || ""})
.then((resThumb) => { .then((resThumb) => {
if ( if (
resThumb !== null && resThumb !== null &&
@ -153,7 +152,8 @@ function parseHtml(preview, res, client: Client) {
}); });
} }
function parseHtmlMedia($: Cheerio, preview, client: Client) { // TODO: type $
function parseHtmlMedia($: any, preview, client: Client) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (Config.values.disableMediaPreview) { if (Config.values.disableMediaPreview) {
reject(); reject();
@ -180,7 +180,7 @@ function parseHtmlMedia($: Cheerio, preview, client: Client) {
return; return;
} }
$(`meta[property="og:${type}:type"]`).each(function (i) { $(`meta[property="og:${type}:type"]`).each(function (this: cheerio.Element, i: number) {
const mimeType = $(this).attr("content"); const mimeType = $(this).attr("content");
if (!mimeType) { if (!mimeType) {
@ -210,7 +210,7 @@ function parseHtmlMedia($: Cheerio, preview, client: Client) {
type === "video" type === "video"
? "video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5" ? "video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5"
: "audio/webm, audio/ogg, audio/wav, audio/*;q=0.9, application/ogg;q=0.7, video/*;q=0.6; */*;q=0.5", : "audio/webm, audio/ogg, audio/wav, audio/*;q=0.9, application/ogg;q=0.7, video/*;q=0.6; */*;q=0.5",
language: client.config.browser?.language, language: client.config.browser?.language || "",
}) })
.then((resMedia) => { .then((resMedia) => {
if (resMedia === null || !mediaTypeRegex.test(resMedia.type)) { if (resMedia === null || !mediaTypeRegex.test(resMedia.type)) {
@ -361,7 +361,7 @@ function handlePreview(client, chan, msg, preview, res) {
}); });
} }
function emitPreview(client, chan, msg, preview) { function emitPreview(client: Client, chan: Chan, msg: Msg, preview: LinkPreview) {
// If there is no title but there is preview or description, set title // If there is no title but there is preview or description, set title
// otherwise bail out and show no preview // otherwise bail out and show no preview
if (!preview.head.length && preview.type === "link") { if (!preview.head.length && preview.type === "link") {
@ -389,7 +389,7 @@ function removePreview(msg, preview) {
} }
} }
function getRequestHeaders(headers) { function getRequestHeaders(headers: Record<string, string>) {
const formattedHeaders = { const formattedHeaders = {
// Certain websites like Amazon only add <meta> tags to known bots, // Certain websites like Amazon only add <meta> tags to known bots,
// lets pretend to be them to get the metadata // lets pretend to be them to get the metadata
@ -407,7 +407,7 @@ function getRequestHeaders(headers) {
return formattedHeaders; return formattedHeaders;
} }
function fetch(uri, headers) { function fetch(uri: string, headers: Record<string, string>) {
// Stringify the object otherwise the objects won't compute to the same value // Stringify the object otherwise the objects won't compute to the same value
const cacheKey = JSON.stringify([uri, headers]); const cacheKey = JSON.stringify([uri, headers]);
let promise = currentFetchPromises.get(cacheKey); let promise = currentFetchPromises.get(cacheKey);
@ -476,13 +476,13 @@ function fetch(uri, headers) {
}) })
.on("end", () => gotStream.destroy()) .on("end", () => gotStream.destroy())
.on("close", () => { .on("close", () => {
let type = ""; let type: string = "";
// If we downloaded more data then specified in Content-Length, use real data size // If we downloaded more data then specified in Content-Length, use real data size
const size = contentLength > buffer.length ? contentLength : buffer.length; const size = contentLength > buffer.length ? contentLength : buffer.length;
if (contentType) { if (contentType) {
type = contentType.split(/ *; */).shift(); type = contentType.split(/ *; */).shift() || "";
} }
resolve({data: buffer, type, size}); resolve({data: buffer, type, size});

View file

@ -145,10 +145,11 @@ export default <IrcEventHandler>function (irc, network) {
msg.statusmsgGroup = data.group; msg.statusmsgGroup = data.group;
} }
let match; let match: RegExpExecArray | null;
while ((match = nickRegExp.exec(data.message))) { while ((match = nickRegExp.exec(data.message))) {
if (chan.findUser(match[1])) { if (chan.findUser(match[1])) {
// @ts-ignore TODO: fix this
msg.users.push(match[1]); msg.users.push(match[1]);
} }
} }

View file

@ -75,7 +75,7 @@ export default <IrcEventHandler>function (irc, network) {
self: data.nick === irc.user.nick, self: data.nick === irc.user.nick,
}); });
const users: User[] = []; const users: string[] = [];
for (const param of data.raw_params) { for (const param of data.raw_params) {
if (targetChan.findUser(param)) { if (targetChan.findUser(param)) {

View file

@ -5,6 +5,7 @@ import path from "path";
import _ from "lodash"; import _ from "lodash";
import Config from "../../config"; import Config from "../../config";
import Utils from "../../command-line/utils";
type Module = { type Module = {
type: string; type: string;
@ -33,9 +34,7 @@ export default {
}; };
function loadLocalThemes() { function loadLocalThemes() {
const builtInThemes = fs.readdirSync( const builtInThemes = fs.readdirSync(Utils.getFileFromRelativeToRoot("public", "themes"));
path.join(__dirname, "..", "..", "..", "public", "themes")
);
builtInThemes builtInThemes
.filter((theme) => theme.endsWith(".css")) .filter((theme) => theme.endsWith(".css"))

View file

@ -28,6 +28,7 @@ themes.loadLocalThemes();
import packages from "./plugins/packages/index"; import packages from "./plugins/packages/index";
import {NetworkWithIrcFramework} from "./models/network"; import {NetworkWithIrcFramework} from "./models/network";
import {ChanType} from "./models/chan"; import {ChanType} from "./models/chan";
import Utils from "./command-line/utils";
type ServerOptions = { type ServerOptions = {
dev: boolean; dev: boolean;
@ -96,7 +97,7 @@ export default async function (
.get("/service-worker.js", forceNoCacheRequest) .get("/service-worker.js", forceNoCacheRequest)
.get("/js/bundle.js.map", forceNoCacheRequest) .get("/js/bundle.js.map", forceNoCacheRequest)
.get("/css/style.css.map", forceNoCacheRequest) .get("/css/style.css.map", forceNoCacheRequest)
.use(express.static(path.join(__dirname, "..", "public"), staticOptions)) .use(express.static(Utils.getFileFromRelativeToRoot("public"), staticOptions))
.use("/storage/", express.static(Config.getStoragePath(), staticOptions)); .use("/storage/", express.static(Config.getStoragePath(), staticOptions));
if (Config.values.fileUpload.enable) { if (Config.values.fileUpload.enable) {
@ -382,7 +383,7 @@ function indexRequest(req, res) {
res.setHeader("Content-Type", "text/html"); res.setHeader("Content-Type", "text/html");
return fs.readFile( return fs.readFile(
path.join(__dirname, "..", "client", "index.html.tpl"), Utils.getFileFromRelativeToRoot("client/index.html.tpl"),
"utf-8", "utf-8",
(err, file) => { (err, file) => {
if (err) { if (err) {

View file

@ -2,6 +2,9 @@
"extends": "../tsconfig.base.json", "extends": "../tsconfig.base.json",
"files": [ "files": [
"../package.json", "../package.json",
"../webpack.config.ts",
"../babel.config.cjs",
"../defaults/config.js",
"../client/js/constants.ts", "../client/js/constants.ts",
"../client/js/helpers/ircmessageparser/findLinks.ts", "../client/js/helpers/ircmessageparser/findLinks.ts",
"../client/js/helpers/ircmessageparser/cleanIrcMessage.ts" "../client/js/helpers/ircmessageparser/cleanIrcMessage.ts"
@ -11,13 +14,15 @@
}, },
// TODO: these should be imported from the base config, // TODO: these should be imported from the base config,
// but ts-node doesn't seem to care. // but ts-node doesn't seem to care.
// "include": ["**/*"], "include": ["**/*"],
// "typeRoots": ["./types/"], // "typeRoots": ["./types/"],
"compilerOptions": { "compilerOptions": {
"types": ["node"], "types": ["node"],
"baseUrl": ".", "baseUrl": ".",
"noImplicitAny": false "noImplicitAny": false,
"outDir": "./dist",
"noEmit": false
} }
// "references": [{"path": "../"}] // "references": [{"path": "../"}]
} }

View file

@ -7,18 +7,16 @@
"rootDir": ".", "rootDir": ".",
"baseUrl": ".", "baseUrl": ".",
"allowJs": true, "allowJs": true,
"noImplicitAny": false,
"checkJs": true, "checkJs": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"composite": true, "composite": true,
"strict": true /* Enable all strict type-checking options. */, "strict": true /* Enable all strict type-checking options. */,
"typeRoots": ["./src/types/"], // "typeRoots": ["./src/types/"],
"moduleResolution": "node", "moduleResolution": "node",
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"esModuleInterop": true, "esModuleInterop": true,
"skipLibCheck": true, "skipLibCheck": true,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}, },
"files": ["./package.json"], "files": ["./package.json"]
"include": ["./src/types/*"]
} }

View file

@ -1,5 +1,9 @@
{ {
"extends": "./tsconfig.base.json", "extends": "./tsconfig.base.json",
"compilerOptions": {
// TODO: enable
"noImplicitAny": false
},
"files": ["./webpack.config.ts", "./babel.config.cjs", "./src/helper.ts"], "files": ["./webpack.config.ts", "./babel.config.cjs", "./src/helper.ts"],
"references": [ "references": [
{ {

View file

@ -104,22 +104,25 @@ const config: webpack.Configuration = {
new CopyPlugin({ new CopyPlugin({
patterns: [ patterns: [
{ {
from: "./node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff*", from: path.resolve(
__dirname,
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff"
),
to: "fonts/[name][ext]", to: "fonts/[name][ext]",
}, },
{ {
from: "./client/js/loading-error-handlers.js", from: path.resolve(__dirname, "./client/js/loading-error-handlers.js"),
to: "js/[name][ext]", to: "js/[name][ext]",
}, },
{ {
from: "./client/*", from: path.resolve(__dirname, "./client/*"),
to: "[name][ext]", to: "[name][ext]",
globOptions: { globOptions: {
ignore: ["**/index.html.tpl", "**/service-worker.js"], ignore: ["**/index.html.tpl", "**/service-worker.js"],
}, },
}, },
{ {
from: "./client/service-worker.js", from: path.resolve(__dirname, "./client/service-worker.js"),
to: "[name][ext]", to: "[name][ext]",
transform(content) { transform(content) {
return content return content
@ -131,15 +134,15 @@ const config: webpack.Configuration = {
}, },
}, },
{ {
from: "./client/audio/*", from: path.resolve(__dirname, "./client/audio/*"),
to: "audio/[name][ext]", to: "audio/[name][ext]",
}, },
{ {
from: "./client/img/*", from: path.resolve(__dirname, "./client/img/*"),
to: "img/[name][ext]", to: "img/[name][ext]",
}, },
{ {
from: "./client/themes/*", from: path.resolve(__dirname, "./client/themes/*"),
to: "themes/[name][ext]", to: "themes/[name][ext]",
}, },
], ],

View file

@ -1414,7 +1414,7 @@
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04"
integrity sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ== integrity sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==
"@types/cheerio@^0.22.10": "@types/cheerio@0.22.31", "@types/cheerio@^0.22.10":
version "0.22.31" version "0.22.31"
resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.31.tgz#b8538100653d6bb1b08a1e46dec75b4f2a5d5eb6" resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.31.tgz#b8538100653d6bb1b08a1e46dec75b4f2a5d5eb6"
integrity sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw== integrity sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw==
@ -1448,7 +1448,7 @@
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080"
integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==
"@types/eslint-scope@^3.7.0": "@types/eslint-scope@^3.7.0", "@types/eslint-scope@^3.7.3":
version "3.7.3" version "3.7.3"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224"
integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==
@ -1464,7 +1464,7 @@
"@types/estree" "*" "@types/estree" "*"
"@types/json-schema" "*" "@types/json-schema" "*"
"@types/estree@*": "@types/estree@*", "@types/estree@^0.0.51":
version "0.0.51" version "0.0.51"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40"
integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
@ -1670,6 +1670,15 @@
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.4.tgz#1f4969042bf76d7ef7b5914f59b3b60073f4e1f4" resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.4.tgz#1f4969042bf76d7ef7b5914f59b3b60073f4e1f4"
integrity sha512-llS8qveOUX3wxHnSykP5hlYFFuMfJ9p5JvIyCiBgp7WTfl6K5ZcyHj8r8JsN/J6QODkAsRRCLIcTuOCu8etkUw== integrity sha512-llS8qveOUX3wxHnSykP5hlYFFuMfJ9p5JvIyCiBgp7WTfl6K5ZcyHj8r8JsN/J6QODkAsRRCLIcTuOCu8etkUw==
"@types/webpack-hot-middleware@2.25.6":
version "2.25.6"
resolved "https://registry.yarnpkg.com/@types/webpack-hot-middleware/-/webpack-hot-middleware-2.25.6.tgz#4336abd668dc73284a777907cfd00147e794354a"
integrity sha512-1Q9ClNvZR30HIsEAHYQL3bXJK1K7IsrqjGMTfIureFjphsGOZ3TkbeoCupbCmi26pSLjVTPHp+pFrJNpOkBSVg==
dependencies:
"@types/connect" "*"
tapable "^2.2.0"
webpack "^5"
"@types/ws@8.5.3": "@types/ws@8.5.3":
version "8.5.3" version "8.5.3"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d"
@ -3604,7 +3613,7 @@ engine.io@~6.1.0:
engine.io-parser "~5.0.3" engine.io-parser "~5.0.3"
ws "~8.2.3" ws "~8.2.3"
enhanced-resolve@^5.0.0, enhanced-resolve@^5.7.0, enhanced-resolve@^5.8.3: enhanced-resolve@^5.0.0, enhanced-resolve@^5.7.0, enhanced-resolve@^5.8.3, enhanced-resolve@^5.9.2:
version "5.9.3" version "5.9.3"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88"
integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow== integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==
@ -9163,6 +9172,36 @@ webpack@5.68.0:
watchpack "^2.3.1" watchpack "^2.3.1"
webpack-sources "^3.2.3" webpack-sources "^3.2.3"
webpack@^5:
version "5.72.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.72.0.tgz#f8bc40d9c6bb489a4b7a8a685101d6022b8b6e28"
integrity sha512-qmSmbspI0Qo5ld49htys8GY9XhS9CGqFoHTsOVAnjBdg0Zn79y135R+k4IR4rKK6+eKaabMhJwiVB7xw0SJu5w==
dependencies:
"@types/eslint-scope" "^3.7.3"
"@types/estree" "^0.0.51"
"@webassemblyjs/ast" "1.11.1"
"@webassemblyjs/wasm-edit" "1.11.1"
"@webassemblyjs/wasm-parser" "1.11.1"
acorn "^8.4.1"
acorn-import-assertions "^1.7.6"
browserslist "^4.14.5"
chrome-trace-event "^1.0.2"
enhanced-resolve "^5.9.2"
es-module-lexer "^0.9.0"
eslint-scope "5.1.1"
events "^3.2.0"
glob-to-regexp "^0.4.1"
graceful-fs "^4.2.9"
json-parse-better-errors "^1.0.2"
loader-runner "^4.2.0"
mime-types "^2.1.27"
neo-async "^2.6.2"
schema-utils "^3.1.0"
tapable "^2.1.1"
terser-webpack-plugin "^5.1.3"
watchpack "^2.3.1"
webpack-sources "^3.2.3"
whatwg-url@^5.0.0: whatwg-url@^5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"