Merge branch 'thelounge:master' into newts

This commit is contained in:
MobiDev 2023-03-18 23:06:13 +00:00 committed by GitHub
commit 7bbb4a4b7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 560 additions and 354 deletions

View file

@ -7,6 +7,7 @@ const projects = defineConfig({
"./tsconfig.json",
"./client/tsconfig.json",
"./server/tsconfig.json",
"./shared/tsconfig.json",
"./test/tsconfig.json",
],
},

View file

@ -1,25 +0,0 @@
# This file must not contain generated assets listed in .gitignore.
# npm-debug.log and node_modules/ are ignored by default.
# See https://docs.npmjs.com/misc/developers#keeping-files-out-of-your-package
# Ignore all dot files except for .thelounge_home
.*
!.thelounge_home
# Ignore client folder as it's being built into public/ folder
# except for the specified files which are used by the server
client/**
!client/js/constants.ts
!client/js/helpers/ircmessageparser/findLinks.ts
!client/js/helpers/ircmessageparser/cleanIrcMessage.ts
!client/index.html.tpl
public/js/bundle.vendor.js.map
coverage/
scripts/
test/
appveyor.yml
webpack.config*.js
postcss.config.js
renovate.json

View file

@ -19,7 +19,7 @@
<script lang="ts">
import {computed, defineComponent, PropType, ref} from "vue";
import constants from "../js/constants";
import {condensedTypes} from "../../shared/irc";
import {ClientMessage, ClientNetwork} from "../js/types";
import Message from "./Message.vue";
@ -51,7 +51,7 @@ export default defineComponent({
const condensedText = computed(() => {
const obj: Record<string, number> = {};
constants.condensedTypes.forEach((type) => {
condensedTypes.forEach((type) => {
obj[type] = 0;
});
@ -75,7 +75,7 @@ export default defineComponent({
obj.part += obj.quit;
const strings: string[] = [];
constants.condensedTypes.forEach((type) => {
condensedTypes.forEach((type) => {
if (obj[type]) {
switch (type) {
case "chghost":

View file

@ -58,7 +58,7 @@
</template>
<script lang="ts">
import constants from "../js/constants";
import {condensedTypes} from "../../shared/irc";
import eventbus from "../js/eventbus";
import clipboard from "../js/clipboard";
import socket from "../js/socket";
@ -184,7 +184,7 @@ export default defineComponent({
// If actions are hidden, just return a message list with them excluded
if (store.state.settings.statusMessages === "hidden") {
return props.channel.messages.filter(
(message) => !constants.condensedTypes.has(message.type)
(message) => !condensedTypes.has(message.type)
);
}
@ -200,11 +200,7 @@ export default defineComponent({
for (const message of props.channel.messages) {
// If this message is not condensable, or its an action affecting our user,
// then just append the message to container and be done with it
if (
message.self ||
message.highlight ||
!constants.condensedTypes.has(message.type)
) {
if (message.self || message.highlight || !condensedTypes.has(message.type)) {
lastCondensedContainer = null;
condensed.push(message);

View file

@ -17,18 +17,6 @@ const colorCodeMap = [
["15", "Light Grey"],
];
const condensedTypes = new Set([
"away",
"back",
"chghost",
"join",
"kick",
"mode",
"nick",
"part",
"quit",
]);
const timeFormats = {
msgDefault: "HH:mm",
msgWithSeconds: "HH:mm:ss",
@ -39,7 +27,6 @@ const timeFormats = {
export default {
colorCodeMap,
commands: [] as string[],
condensedTypes,
timeFormats,
// Same value as media query in CSS that forces sidebars to become overlays
mobileViewportPixels: 768,

View file

@ -1,4 +0,0 @@
const matchFormatting =
/\x02|\x1D|\x1F|\x16|\x0F|\x11|\x1E|\x03(?:[0-9]{1,2}(?:,[0-9]{1,2})?)?|\x04(?:[0-9a-f]{6}(?:,[0-9a-f]{6})?)?/gi;
export default (message: string) => message.replace(matchFormatting, "").trim();

View file

@ -2,7 +2,7 @@ import anyIntersection from "./anyIntersection";
import fill from "./fill";
import {ChannelPart} from "./findChannels";
import {EmojiPart} from "./findEmoji";
import {LinkPart} from "./findLinks";
import {LinkPart} from "../../../../shared/linkify";
import {NamePart} from "./findNames";
export type Part = {

View file

@ -3,11 +3,11 @@
import {h as createElement, VNode} from "vue";
import parseStyle from "./ircmessageparser/parseStyle";
import findChannels, {ChannelPart} from "./ircmessageparser/findChannels";
import {findLinks, LinkPart} from "./ircmessageparser/findLinks";
import findEmoji, {EmojiPart} from "./ircmessageparser/findEmoji";
import findNames, {NamePart} from "./ircmessageparser/findNames";
import merge, {MergedParts, Part} from "./ircmessageparser/merge";
import findChannels from "./ircmessageparser/findChannels";
import {findLinks} from "../../../shared/linkify";
import findEmoji from "./ircmessageparser/findEmoji";
import findNames from "./ircmessageparser/findNames";
import merge, {MergedParts} from "./ircmessageparser/merge";
import emojiMap from "./fullnamemap.json";
import LinkPreviewToggle from "../../components/LinkPreviewToggle.vue";
import LinkPreviewFileSize from "../../components/LinkPreviewFileSize.vue";

View file

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/restrict-plus-operands */
import socket from "../socket";
import cleanIrcMessage from "../helpers/ircmessageparser/cleanIrcMessage";
import {cleanIrcMessage} from "../../../shared/irc";
import {store} from "../store";
import {switchToChannel} from "../router";
import {ClientChan, ClientMention, ClientMessage, NetChan} from "../types";

View file

@ -1,7 +1,8 @@
{
"extends": "../tsconfig.base.json" /* Path to base configuration file to inherit from. Requires TypeScript version 2.1 or later. */,
"include": [
"./**/*"
"./**/*",
"../shared"
] /* Specifies a list of glob patterns that match files to be included in compilation. 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'. Requires TypeScript version 2.0 or later. */,
"files": [
"../package.json",

View file

@ -42,6 +42,15 @@
"engines": {
"node": ">=14.0.0"
},
"files": [
"./.thelounge_home",
"./index.js",
"./yarn.lock",
"./client/index.html.tpl",
"./dist/package.json",
"./dist/**/*.js",
"./public/**"
],
"dependencies": {
"@fastify/busboy": "1.0.0",
"bcryptjs": "2.4.3",
@ -72,7 +81,7 @@
"yarn": "1.22.17"
},
"optionalDependencies": {
"sqlite3": "5.1.4"
"sqlite3": "5.1.6"
},
"devDependencies": {
"@babel/core": "7.17.10",
@ -108,7 +117,7 @@
"@typescript-eslint/eslint-plugin": "5.22.0",
"@typescript-eslint/parser": "5.22.0",
"@vue/runtime-dom": "3.2.33",
"@vue/test-utils": "2.2.7",
"@vue/test-utils": "2.3.1",
"babel-loader": "8.2.5",
"babel-plugin-istanbul": "6.1.1",
"babel-preset-typescript-vue3": "2.0.17",
@ -132,14 +141,14 @@
"normalize.css": "8.0.1",
"npm-run-all": "4.1.5",
"nyc": "15.1.0",
"postcss": "8.4.19",
"postcss": "8.4.21",
"postcss-import": "14.0.2",
"postcss-loader": "6.2.1",
"postcss-preset-env": "7.3.0",
"prettier": "2.5.1",
"pretty-quick": "3.1.3",
"primer-tooltips": "2.0.0",
"sinon": "13.0.0",
"sinon": "13.0.2",
"socket.io-client": "4.5.0",
"sortablejs": "1.15.0",
"stylelint": "14.3.0",
@ -151,12 +160,12 @@
"undate": "0.3.0",
"vue": "3.2.35",
"vue-eslint-parser": "8.3.0",
"vue-loader": "17.0.0",
"vue-loader": "17.0.1",
"vue-router": "4.0.15",
"vuex": "4.0.2",
"webpack": "5.68.0",
"webpack": "5.76.0",
"webpack-cli": "4.9.2",
"webpack-dev-middleware": "5.3.0",
"webpack-dev-middleware": "5.3.3",
"webpack-hot-middleware": "2.25.1"
},
"husky": {

View file

@ -9,13 +9,13 @@ import log from "./log";
import Chan, {Channel, ChanType} from "./models/chan";
import Msg, {MessageType, UserInMessage} from "./models/msg";
import Config from "./config";
import constants from "../client/js/constants";
import {condensedTypes} from "../shared/irc";
import inputs from "./plugins/inputs";
import PublicClient from "./plugins/packages/publicClient";
import SqliteMessageStorage from "./plugins/messageStorage/sqlite";
import TextFileMessageStorage from "./plugins/messageStorage/text";
import Network, {IgnoreListItem, NetworkWithIrcFramework} from "./models/network";
import Network, {IgnoreListItem, NetworkConfig, NetworkWithIrcFramework} from "./models/network";
import ClientManager from "./clientManager";
import {MessageStorage, SearchQuery, SearchResponse} from "./plugins/messageStorage/types";
@ -78,6 +78,7 @@ export type UserConfig = {
hostname?: string;
isSecure?: boolean;
};
networks?: NetworkConfig[];
};
export type Mention = {
@ -95,9 +96,7 @@ class Client {
attachedClients!: {
[socketId: string]: {token: string; openChannel: number};
};
config!: UserConfig & {
networks?: Network[];
};
config!: UserConfig;
id!: number;
idMsg!: number;
idChan!: number;
@ -176,8 +175,16 @@ class Client {
this.registerPushSubscription(session, session.pushSubscription, true);
}
});
}
(client.config.networks || []).forEach((network) => client.connect(network, true));
connect() {
const client = this;
if (client.networks.length !== 0) {
throw new Error(`${client.name} is already connected`);
}
(client.config.networks || []).forEach((network) => client.connectToNetwork(network, true));
// Networks are stored directly in the client object
// We don't need to keep it in the config object
@ -188,7 +195,7 @@ class Client {
// Networks are created instantly, but to reduce server load on startup
// We randomize the IRC connections and channel log loading
let delay = manager.clients.length * 500;
let delay = client.manager.clients.length * 500;
client.networks.forEach((network) => {
setTimeout(() => {
network.channels.forEach((channel) => channel.loadMessages(client, network));
@ -201,7 +208,7 @@ class Client {
delay += 1000 + Math.floor(Math.random() * 1000);
});
client.fileHash = manager.getDataToSave(client).newHash;
client.fileHash = client.manager.getDataToSave(client).newHash;
}
}
@ -238,12 +245,10 @@ class Client {
return false;
}
connect(args: Record<string, any>, isStartup = false) {
networkFromConfig(args: Record<string, any>): Network {
const client = this;
let channels: Chan[] = [];
// Get channel id for lobby before creating other channels for nicer ids
const lobbyChannelId = client.idChan++;
let channels: Chan[] = [];
if (Array.isArray(args.channels)) {
let badName = false;
@ -291,7 +296,7 @@ class Client {
}
// TODO; better typing for args
const network = new Network({
return new Network({
uuid: args.uuid,
name: String(
args.name || (Config.values.lockNetwork ? Config.values.defaults.name : "") || ""
@ -319,9 +324,18 @@ class Client {
proxyUsername: String(args.proxyUsername || ""),
proxyPassword: String(args.proxyPassword || ""),
});
}
connectToNetwork(args: Record<string, any>, isStartup = false) {
const client = this;
// Get channel id for lobby before creating other channels for nicer ids
const lobbyChannelId = client.idChan++;
const network = this.networkFromConfig(args);
// Set network lobby channel id
network.channels[0].id = lobbyChannelId;
network.getLobby().id = lobbyChannelId;
client.networks.push(network);
client.emit("network", {
@ -344,7 +358,7 @@ class Client {
});
if (network.userDisconnected) {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
text: "You have manually disconnected from this network before, use the /connect command to connect again.",
@ -359,7 +373,7 @@ class Client {
if (!isStartup) {
client.save();
channels.forEach((channel) => channel.loadMessages(client, network));
network.channels.forEach((channel) => channel.loadMessages(client, network));
}
}
@ -569,7 +583,7 @@ class Client {
startIndex--;
// Do not count condensed messages towards the 100 messages
if (constants.condensedTypes.has(chan.messages[i].type)) {
if (condensedTypes.has(chan.messages[i].type)) {
continue;
}

View file

@ -7,6 +7,7 @@ import path from "path";
import Auth from "./plugins/auth";
import Client, {UserConfig} from "./client";
import Config from "./config";
import {NetworkConfig} from "./models/network";
import WebPush from "./plugins/webpush";
import log from "./log";
import {Server} from "socket.io";
@ -144,6 +145,7 @@ class ClientManager {
}
} else {
client = new Client(this, name, userConfig);
client.connect();
this.clients.push(client);
}

View file

@ -116,9 +116,15 @@ class Identification {
refresh() {
let file = "# Warning: file generated by The Lounge: changes will be overwritten!\n";
this.connections.forEach((connection) => {
this.connections.forEach((connection, id) => {
if (!connection.socket.remotePort || !connection.socket.localPort) {
throw new Error("Socket has no remote or local port");
// Race condition: this can happen when more than one socket gets disconnected at
// once, since we `refresh()` for each one being added/removed. This results
// in there possibly being one or more disconnected sockets remaining when we get here.
log.warn(
`oidentd: socket has no remote or local port (id=${id}). See https://github.com/thelounge/thelounge/pull/4695.`
);
return;
}
file +=

View file

@ -33,20 +33,26 @@ export type FilteredChannel = Chan & {
totalMessages: number;
};
export type ChanConfig = {
name: string;
key?: string;
muted?: boolean;
type?: string;
};
class Chan {
// TODO: don't force existence, figure out how to make TS infer it.
id!: number;
messages!: Msg[];
name!: string;
key!: string;
topic!: string;
firstUnread!: number;
unread!: number;
highlight!: number;
users!: Map<string, User>;
muted!: boolean;
type!: ChanType;
state!: ChanState;
id: number;
messages: Msg[];
name: string;
key: string;
topic: string;
firstUnread: number;
unread: number;
highlight: number;
users: Map<string, User>;
muted: boolean;
type: ChanType;
state: ChanState;
userAway?: boolean;
special?: SpecialChanType;
@ -56,20 +62,22 @@ class Chan {
static optionalProperties = ["userAway", "special", "data", "closed", "num_users"];
constructor(attr?: Partial<Chan>) {
_.defaults(this, attr, {
id: 0,
messages: [],
name: "",
key: "",
topic: "",
type: ChanType.CHANNEL,
state: ChanState.PARTED,
firstUnread: 0,
unread: 0,
highlight: 0,
users: new Map(),
muted: false,
});
this.id = 0;
this.messages = [];
this.name = "";
this.key = "";
this.topic = "";
this.type = ChanType.CHANNEL;
this.state = ChanState.PARTED;
this.firstUnread = 0;
this.unread = 0;
this.highlight = 0;
this.users = new Map();
this.muted = false;
if (attr) {
Object.assign(this, attr);
}
}
destroy() {

View file

@ -1,7 +1,7 @@
import _ from "lodash";
import {v4 as uuidv4} from "uuid";
import IrcFramework, {Client as IRCClient} from "irc-framework";
import Chan, {Channel, ChanType} from "./chan";
import Chan, {ChanConfig, Channel, ChanType} from "./chan";
import Msg, {MessageType} from "./msg";
import Prefix from "./prefix";
import Helper, {Hostmask} from "../helper";
@ -67,94 +67,125 @@ export type NetworkWithIrcFramework = Network & {
};
};
export type NetworkConfig = {
nick: string;
name: string;
host: string;
port: number;
tls: boolean;
userDisconnected: boolean;
rejectUnauthorized: boolean;
password: string;
awayMessage: string;
commands: any[];
username: string;
realname: string;
leaveMessage: string;
sasl: string;
saslAccount: string;
saslPassword: string;
channels: ChanConfig[];
uuid: string;
proxyHost: string;
proxyPort: number;
proxyUsername: string;
proxyPassword: string;
proxyEnabled: boolean;
highlightRegex?: string;
ignoreList: any[];
};
class Network {
nick!: string;
name!: string;
host!: string;
port!: number;
tls!: boolean;
userDisconnected!: boolean;
rejectUnauthorized!: boolean;
password!: string;
awayMessage!: string;
commands!: any[];
username!: string;
realname!: string;
leaveMessage!: string;
sasl!: string;
saslAccount!: string;
saslPassword!: string;
channels!: Chan[];
uuid!: string;
proxyHost!: string;
proxyPort!: number;
proxyUsername!: string;
proxyPassword!: string;
proxyEnabled!: boolean;
nick: string;
name: string;
host: string;
port: number;
tls: boolean;
userDisconnected: boolean;
rejectUnauthorized: boolean;
password: string;
awayMessage: string;
commands: any[];
username: string;
realname: string;
leaveMessage: string;
sasl: string;
saslAccount: string;
saslPassword: string;
channels: Chan[];
uuid: string;
proxyHost: string;
proxyPort: number;
proxyUsername: string;
proxyPassword: string;
proxyEnabled: boolean;
highlightRegex?: RegExp;
irc?: IrcFramework.Client & {
options?: NetworkIrcOptions;
};
chanCache!: Chan[];
ignoreList!: IgnoreList;
keepNick!: string | null;
chanCache: Chan[];
ignoreList: IgnoreList;
keepNick: string | null;
status!: NetworkStatus;
serverOptions!: {
serverOptions: {
CHANTYPES: string[];
PREFIX: Prefix;
NETWORK: string;
};
// TODO: this is only available on export
hasSTSPolicy!: boolean;
hasSTSPolicy: boolean;
status: NetworkStatus;
constructor(attr?: Partial<Network>) {
_.defaults(this, attr, {
name: "",
nick: "",
host: "",
port: 6667,
tls: false,
userDisconnected: false,
rejectUnauthorized: false,
password: "",
awayMessage: "",
commands: [],
username: "",
realname: "",
leaveMessage: "",
sasl: "",
saslAccount: "",
saslPassword: "",
channels: [],
irc: null,
serverOptions: {
CHANTYPES: ["#", "&"],
PREFIX: new Prefix([
{symbol: "!", mode: "Y"},
{symbol: "@", mode: "o"},
{symbol: "%", mode: "h"},
{symbol: "+", mode: "v"},
]),
NETWORK: "",
},
this.name = "";
this.nick = "";
this.host = "";
this.port = 6667;
this.tls = false;
this.userDisconnected = false;
this.rejectUnauthorized = false;
this.password = "";
this.awayMessage = "";
this.commands = [];
this.username = "";
this.realname = "";
this.leaveMessage = "";
this.sasl = "";
this.saslAccount = "";
this.saslPassword = "";
this.channels = [];
this.serverOptions = {
CHANTYPES: ["#", "&"],
PREFIX: new Prefix([
{symbol: "!", mode: "Y"},
{symbol: "@", mode: "o"},
{symbol: "%", mode: "h"},
{symbol: "+", mode: "v"},
]),
NETWORK: "",
};
this.proxyHost = "";
this.proxyPort = 1080;
this.proxyUsername = "";
this.proxyPassword = "";
this.proxyEnabled = false;
proxyHost: "",
proxyPort: 1080,
proxyUsername: "",
proxyPassword: "",
proxyEnabled: false,
this.chanCache = [];
this.ignoreList = [];
this.keepNick = null;
this.hasSTSPolicy = false;
this.uuid = "invalid"; // sentinel value that makes us generate a new one
chanCache: [],
ignoreList: [],
keepNick: null,
});
this.status = {connected: false, secure: false};
if (!this.uuid) {
if (attr) {
Object.assign(this, attr);
}
if (this.uuid === "invalid" || !this.uuid) {
this.uuid = uuidv4();
}
@ -205,7 +236,7 @@ class Network {
this.proxyEnabled = !!this.proxyEnabled;
const error = function (network: Network, text: string) {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
type: MessageType.ERROR,
@ -238,7 +269,7 @@ class Network {
if (Config.values.public) {
this.name = Config.values.defaults.name;
// Sync lobby channel name
this.channels[0].name = Config.values.defaults.name;
this.getLobby().name = Config.values.defaults.name;
}
this.host = Config.values.defaults.host;
@ -398,7 +429,7 @@ class Network {
.filter((command) => command.length > 0);
// Sync lobby channel name
this.channels[0].name = this.name;
this.getLobby().name = this.name;
if (this.name !== oldNetworkName) {
// Send updated network name to all connected clients
@ -648,6 +679,10 @@ class Network {
return i > 0 && that.name.toLowerCase() === name;
});
}
getLobby() {
return this.channels[0];
}
}
export default Network;

View file

@ -1,32 +1,29 @@
import _ from "lodash";
import Prefix from "./prefix";
class User {
modes!: string[];
modes: string[];
// Users in the channel have only one mode assigned
mode!: string;
away!: string;
nick!: string;
lastMessage!: number;
away: string;
nick: string;
lastMessage: number;
constructor(attr: Partial<User>, prefix?: Prefix) {
_.defaults(this, attr, {
modes: [],
away: "",
nick: "",
lastMessage: 0,
});
this.modes = [];
this.away = "";
this.nick = "";
this.lastMessage = 0;
Object.defineProperty(this, "mode", {
get() {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return this.modes[0] || "";
},
});
if (attr) {
Object.assign(this, attr);
}
this.setModes(this.modes, prefix || new Prefix([]));
}
get mode() {
return this.modes[0] || "";
}
setModes(modes: string[], prefix: Prefix) {
// irc-framework sets character mode, but The Lounge works with symbols
this.modes = modes.map((mode) => prefix.modeToSymbol[mode]);

View file

@ -39,7 +39,7 @@ const input: PluginInputHandler = function (network, chan, cmd, args) {
}
const host = args[0];
this.connect({host, port, tls});
this.connectToNetwork({host, port, tls});
return true;
};

View file

@ -19,7 +19,7 @@ export default <IrcEventHandler>function (irc, network) {
time: data.time,
});
network.channels[0].pushMessage(client, msg, true);
network.getLobby().pushMessage(client, msg, true);
return;
}

View file

@ -42,7 +42,7 @@ export default <IrcEventHandler>function (irc, network) {
return;
}
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
text: `Server sent a strict transport security policy, reconnecting to ${network.host}:${port}`,

View file

@ -11,7 +11,7 @@ import {ChanType, ChanState} from "../../models/chan";
export default <IrcEventHandler>function (irc, network) {
const client = this;
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
text: "Network created, connecting to " + network.host + ":" + network.port + "...",
@ -21,7 +21,7 @@ export default <IrcEventHandler>function (irc, network) {
irc.on("registered", function () {
if (network.irc.network.cap.enabled.length > 0) {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
text: "Enabled capabilities: " + network.irc.network.cap.enabled.join(", "),
@ -44,7 +44,7 @@ export default <IrcEventHandler>function (irc, network) {
network.commands.forEach((cmd) => {
setTimeout(function () {
client.input({
target: network.channels[0].id,
target: network.getLobby().id,
text: cmd,
});
}, delay);
@ -69,7 +69,7 @@ export default <IrcEventHandler>function (irc, network) {
network.serverOptions.PREFIX.update(irc.network.options.PREFIX);
}
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
text: "Connected to the network.",
@ -81,7 +81,7 @@ export default <IrcEventHandler>function (irc, network) {
});
irc.on("close", function () {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
text: "Disconnected from the network, and will not reconnect. Use /connect to reconnect again.",
@ -114,7 +114,7 @@ export default <IrcEventHandler>function (irc, network) {
});
if (error) {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
type: MessageType.ERROR,
@ -151,7 +151,7 @@ export default <IrcEventHandler>function (irc, network) {
if (Config.values.debug.raw) {
irc.on("raw", function (message) {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
self: !message.from_server,
@ -164,7 +164,7 @@ export default <IrcEventHandler>function (irc, network) {
}
irc.on("socket error", function (err) {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
type: MessageType.ERROR,
@ -175,7 +175,7 @@ export default <IrcEventHandler>function (irc, network) {
});
irc.on("reconnecting", function (data) {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
text: `Disconnected from the network. Reconnecting in ${Math.round(
@ -187,7 +187,7 @@ export default <IrcEventHandler>function (irc, network) {
});
irc.on("ping timeout", function () {
network.channels[0].pushMessage(
network.getLobby().pushMessage(
client,
new Msg({
text: "Ping timeout, disconnecting…",

View file

@ -17,7 +17,7 @@ const ctcpResponses = {
export default <IrcEventHandler>function (irc, network) {
const client = this;
const lobby = network.channels[0];
const lobby = network.getLobby();
irc.on("ctcp response", function (data) {
const shouldIgnore = network.ignoreList.some(function (entry) {

View file

@ -17,7 +17,7 @@ export default <IrcEventHandler>function (irc, network) {
command: data.command,
});
let target = network.channels[0];
let target = network.getLobby();
// If this error is channel specific and a channel
// with this name exists, put this error in that channel
@ -46,7 +46,7 @@ export default <IrcEventHandler>function (irc, network) {
network.keepNick = irc.user.nick;
}
const lobby = network.channels[0];
const lobby = network.getLobby();
const msg = new Msg({
type: MessageType.ERROR,
text: message,
@ -74,7 +74,7 @@ export default <IrcEventHandler>function (irc, network) {
});
irc.on("nick invalid", function (data) {
const lobby = network.channels[0];
const lobby = network.getLobby();
const msg = new Msg({
type: MessageType.ERROR,
text: data.nick + ": " + (data.reason || "Nickname is invalid."),

View file

@ -5,7 +5,7 @@ export default <IrcEventHandler>function (irc, network) {
const client = this;
irc.on("help", function (data) {
const lobby = network.channels[0];
const lobby = network.getLobby();
if (data.help) {
const msg = new Msg({

View file

@ -5,7 +5,7 @@ export default <IrcEventHandler>function (irc, network) {
const client = this;
irc.on("info", function (data) {
const lobby = network.channels[0];
const lobby = network.getLobby();
if (data.info) {
const msg = new Msg({

View file

@ -9,7 +9,7 @@ export default <IrcEventHandler>function (irc, network) {
let chan = network.getChannel(data.channel);
if (typeof chan === "undefined") {
chan = network.channels[0];
chan = network.getLobby();
}
const invitedYou = data.invited === irc.user.nick;

View file

@ -5,7 +5,7 @@ import mime from "mime-types";
import log from "../../log";
import Config from "../../config";
import {findLinksWithSchema} from "../../../client/js/helpers/ircmessageparser/findLinks";
import {findLinksWithSchema} from "../../../shared/linkify";
import storage from "../storage";
import Client from "../../client";
import Chan from "../../models/chan";

View file

@ -1,6 +1,6 @@
import Msg, {MessageType} from "../../models/msg";
import LinkPrefetch from "./link";
import cleanIrcMessage from "../../../client/js/helpers/ircmessageparser/cleanIrcMessage";
import {cleanIrcMessage} from "../../../shared/irc";
import Helper from "../../helper";
import {IrcEventHandler} from "../../client";
import Chan, {ChanType} from "../../models/chan";
@ -75,7 +75,7 @@ export default <IrcEventHandler>function (irc, network) {
!network.getChannel(data.target) ||
network.getChannel(data.target)?.type !== ChanType.CHANNEL)
) {
chan = network.channels[0];
chan = network.getLobby();
from = chan.getUser(data.nick);
} else {
if (shouldIgnore) {
@ -95,7 +95,7 @@ export default <IrcEventHandler>function (irc, network) {
// Send notices that are not targeted at us into the server window
if (data.type === MessageType.NOTICE) {
showInActive = true;
chan = network.channels[0];
chan = network.getLobby();
} else {
chan = client.createChannel({
type: ChanType.QUERY,

View file

@ -41,7 +41,7 @@ export default <IrcEventHandler>function (irc, network) {
});
irc.on("user info", function (data) {
const serverChan = network.channels[0];
const serverChan = network.getLobby();
const msg = new Msg({
type: MessageType.MODE_USER,
@ -56,7 +56,7 @@ export default <IrcEventHandler>function (irc, network) {
let targetChan;
if (data.target === irc.user.nick) {
targetChan = network.channels[0];
targetChan = network.getLobby();
} else {
targetChan = network.getChannel(data.target);

View file

@ -47,7 +47,7 @@ export default <IrcEventHandler>function (irc, network) {
// Send error to lobby if we receive empty list for a channel we're not in
if (typeof chan === "undefined") {
msg.showInActive = true;
chan = network.channels[0];
chan = network.getLobby();
}
chan.pushMessage(client, msg, true);

View file

@ -6,7 +6,7 @@ export default <IrcEventHandler>function (irc, network) {
const client = this;
irc.on("motd", function (data) {
const lobby = network.channels[0];
const lobby = network.getLobby();
if (data.motd) {
const msg = new Msg({

View file

@ -11,7 +11,7 @@ export default <IrcEventHandler>function (irc, network) {
if (self) {
network.setNick(data.new_nick);
const lobby = network.channels[0];
const lobby = network.getLobby();
const msg = new Msg({
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
text: `You're now known as ${data.new_nick}`,

View file

@ -6,7 +6,7 @@ export default <IrcEventHandler>function (irc, network) {
const client = this;
irc.on("loggedin", (data) => {
const lobby = network.channels[0];
const lobby = network.getLobby();
const msg = new Msg({
type: MessageType.LOGIN,
@ -17,7 +17,7 @@ export default <IrcEventHandler>function (irc, network) {
});
irc.on("loggedout", () => {
const lobby = network.channels[0];
const lobby = network.getLobby();
const msg = new Msg({
type: MessageType.LOGOUT,

View file

@ -6,7 +6,7 @@ export default <IrcEventHandler>function (irc, network) {
const client = this;
irc.on("unknown command", function (command) {
let target = network.channels[0];
let target = network.getLobby();
// Do not display users own name
if (command.params.length > 0 && command.params[0] === network.irc.user.nick) {

View file

@ -8,7 +8,7 @@ export default <IrcEventHandler>function (irc, network) {
irc.on("registered", function (data) {
network.setNick(data.nick);
const lobby = network.channels[0];
const lobby = network.getLobby();
const msg = new Msg({
text: "You're now known as " + data.nick,
});

View file

@ -20,7 +20,7 @@ export default <IrcEventHandler>function (irc, network) {
if (typeof chan === "undefined") {
// Do not create new windows for errors as they may contain illegal characters
if (data.error) {
chan = network.channels[0];
chan = network.getLobby();
} else {
chan = client.createChannel({
type: ChanType.QUERY,

View file

@ -485,7 +485,7 @@ function initializeClient(
data.commands = null;
data.ignoreList = null;
client.connect(data);
client.connectToNetwork(data);
}
});
@ -948,6 +948,7 @@ function performAuthentication(this: Socket, data) {
if (Config.values.public) {
client = new Client(manager!);
client.connect();
manager!.clients.push(client);
socket.on("disconnect", function () {

View file

@ -2,10 +2,9 @@
"extends": "../tsconfig.base.json" /* Path to base configuration file to inherit from. Requires TypeScript version 2.1 or later. */,
"include": [
"**/*",
"../client/js/helpers/ircmessageparser/*.ts"
"../shared/"
] /* Specifies a list of glob patterns that match files to be included in compilation. 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'. Requires TypeScript version 2.0 or later. */,
"files": [
"../client/js/constants.ts",
"../babel.config.cjs",
"../defaults/config.js",
"../package.json",
@ -15,13 +14,8 @@
"files": true
},
"compilerOptions": {
"outDir": "../dist" /* Specify an output folder for all emitted files. See more: https://www.typescriptlang.org/tsconfig#outDir */,
"noEmit": false /* Disable emitting file from a compilation. See more: https://www.typescriptlang.org/tsconfig#noEmit */,
// TODO: Remove eventually
"noImplicitAny": false /*Enable error reporting for expressions and declarations with an implied any type. See more: https://www.typescriptlang.org/tsconfig#noImplicitAny */
} /* Instructs the TypeScript compiler how to compile .ts files. */,
"exclude": [
"./dist"
] /* Specifies a list of glob patterns that match files to be excluded from compilation. Requires TypeScript version 2.0 or later. */
} /* Instructs the TypeScript compiler how to compile .ts files. */
}

18
shared/irc.ts Normal file
View file

@ -0,0 +1,18 @@
const matchFormatting =
/\x02|\x1D|\x1F|\x16|\x0F|\x11|\x1E|\x03(?:[0-9]{1,2}(?:,[0-9]{1,2})?)?|\x04(?:[0-9a-f]{6}(?:,[0-9a-f]{6})?)?/gi;
export function cleanIrcMessage(message: string) {
return message.replace(matchFormatting, "").trim();
}
export const condensedTypes = new Set([
"away",
"back",
"chghost",
"join",
"kick",
"mode",
"nick",
"part",
"quit",
]);

View file

@ -1,15 +1,19 @@
import LinkifyIt, {Match} from "linkify-it";
import {Part} from "./merge";
import tlds from "tlds";
export type LinkPart = Part & {
export type NoSchemaMatch = Match & {
noschema: boolean;
};
export type LinkPart = {
start: number;
end: number;
link: string;
};
type OurMatch = Match & {
noschema?: boolean;
};
LinkifyIt.prototype.normalize = function normalize(match: NoSchemaMatch) {
match.noschema = false;
LinkifyIt.prototype.normalize = function normalize(match: OurMatch) {
if (!match.schema) {
match.schema = "http:";
match.url = "http://" + match.url;
@ -27,7 +31,6 @@ LinkifyIt.prototype.normalize = function normalize(match: OurMatch) {
}
};
import tlds from "tlds";
const linkify = LinkifyIt().tlds(tlds).tlds("onion", true);
// Known schemes to detect in text
@ -52,32 +55,30 @@ for (const schema of commonSchemes) {
linkify.add(schema + ":", "http:");
}
function findLinks(text: string) {
const matches = linkify.match(text) as OurMatch[];
export function findLinks(text: string) {
const matches = linkify.match(text) as NoSchemaMatch[];
if (!matches) {
return [];
}
return matches.map(returnUrl);
return matches.map(makeLinkPart);
}
function findLinksWithSchema(text: string) {
const matches = linkify.match(text) as OurMatch[];
export function findLinksWithSchema(text: string) {
const matches = linkify.match(text) as NoSchemaMatch[];
if (!matches) {
return [];
}
return matches.filter((url) => !url.noschema).map(returnUrl);
return matches.filter((url) => !url.noschema).map(makeLinkPart);
}
function returnUrl(url: OurMatch): LinkPart {
function makeLinkPart(url: NoSchemaMatch): LinkPart {
return {
start: url.index,
end: url.lastIndex,
link: url.url,
};
}
export {findLinks, findLinksWithSchema};

13
shared/tsconfig.json Normal file
View file

@ -0,0 +1,13 @@
{
"extends": "../tsconfig.base.json" /* Path to base configuration file to inherit from. Requires TypeScript version 2.1 or later. */,
"include": [
"*"
] /* Specifies a list of glob patterns that match files to be included in compilation. 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'. Requires TypeScript version 2.0 or later. */,
"files": [] /* 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. */,
"ts-node": {
"files": true
},
"compilerOptions": {
"noEmit": false /* Disable emitting file from a compilation. See more: https://www.typescriptlang.org/tsconfig#noEmit */
}
}

View file

@ -18,19 +18,6 @@ describe("client-side constants", function () {
});
});
describe(".condensedTypes", function () {
it("should be a non-empty array", function () {
expect(constants.condensedTypes).to.be.an.instanceof(Set).that.is.not.empty;
});
it("should only contain ASCII strings", function () {
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'type' implicitly has an 'any' type.
constants.condensedTypes.forEach((type) => {
expect(type).to.be.a("string").that.does.match(/^\w+$/);
});
});
});
describe(".timeFormats", function () {
it("should be objects of strings", function () {
expect(constants.timeFormats.msgDefault).to.be.an("string").that.is.not.empty;

View file

@ -30,7 +30,7 @@ describe("Network", function () {
expect(network1.uuid).to.not.equal(network2.uuid);
});
it("lobby should be at the top", function () {
it("should keep the lobby at the top", function () {
const network = new Network({
name: "Super Nice Network",
channels: [

View file

@ -74,7 +74,7 @@ describe("SQLite Message Storage", function () {
it("should insert schema version to options table", function (done) {
store.database.get(
"SELECT value FROM options WHERE name = 'schema_version'",
(err, row) => {
(err, row: {value: string}) => {
expect(err).to.be.null;
// Should be sqlite.currentSchemaVersion,

View file

@ -1,5 +1,5 @@
import {expect} from "chai";
import cleanIrcMessage from "../../../../../client/js/helpers/ircmessageparser/cleanIrcMessage";
import {cleanIrcMessage} from "../../shared/irc";
describe("cleanIrcMessage", function () {
it("should remove all formatting", function () {

View file

@ -1,8 +1,5 @@
import {expect} from "chai";
import {
findLinks,
findLinksWithSchema,
} from "../../../../../client/js/helpers/ircmessageparser/findLinks";
import {findLinks, findLinksWithSchema} from "../../shared/linkify";
describe("findLinks", () => {
it("should find url", () => {

14
test/shared/irc.ts Normal file
View file

@ -0,0 +1,14 @@
import {expect} from "chai";
import {condensedTypes} from "../../shared/irc";
describe(".condensedTypes", function () {
it("should be a non-empty array", function () {
expect(condensedTypes).to.be.an.instanceof(Set).that.is.not.empty;
});
it("should only contain ASCII strings", function () {
condensedTypes.forEach((type) => {
expect(type).to.be.a("string").that.does.match(/^\w+$/);
});
});
});

View file

@ -27,6 +27,7 @@ describe("Custom highlights", function () {
},
} as any
);
client.connect();
logInfoStub.restore();
expect(userLoadedLog).to.equal("User test loaded\n");

View file

@ -3,7 +3,8 @@
"include": [
"**/*",
"../client",
"../server"
"../server",
"../shared"
] /* Specifies a list of glob patterns that match files to be included in compilation. 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'. Requires TypeScript version 2.0 or later. */,
"files": [
"../babel.config.cjs",

View file

@ -99,6 +99,5 @@
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"files": ["./package.json", "./server/helper.ts"],
"exclude": ["./dist"]
}

View file

@ -6,12 +6,9 @@
] /* 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": [],
"references": [
{
"path": "./client" /* Path to referenced tsconfig or to folder containing tsconfig. */
},
{
"path": "./server" /* Path to referenced tsconfig or to folder containing tsconfig. */
}
{"path": "./client"},
{"path": "./server"},
{"path": "./shared"}
] /* Referenced projects. Requires TypeScript version 3.0 or later. */,
"compilerOptions": {
// TODO: Remove eventually

View file

@ -58,7 +58,7 @@ const config: webpack.Configuration = {
},
{
test: /\.ts$/i,
include: [path.resolve(__dirname, "client")],
include: [path.resolve(__dirname, "client"), path.resolve(__dirname, "shared")],
exclude: path.resolve(__dirname, "node_modules"),
use: {
loader: "babel-loader",

280
yarn.lock
View file

@ -1185,12 +1185,19 @@
dependencies:
type-detect "4.0.8"
"@sinonjs/fake-timers@>=5", "@sinonjs/fake-timers@^9.0.0":
version "9.1.2"
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c"
integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==
"@sinonjs/commons@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3"
integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==
dependencies:
"@sinonjs/commons" "^1.7.0"
type-detect "4.0.8"
"@sinonjs/fake-timers@^10.0.2":
version "10.0.2"
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c"
integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==
dependencies:
"@sinonjs/commons" "^2.0.0"
"@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1":
version "6.0.1"
@ -1199,6 +1206,13 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@sinonjs/fake-timers@^9.1.2":
version "9.1.2"
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c"
integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==
dependencies:
"@sinonjs/commons" "^1.7.0"
"@sinonjs/samsam@^5.3.1":
version "5.3.1"
resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f"
@ -1352,7 +1366,7 @@
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080"
integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==
"@types/eslint-scope@^3.7.0", "@types/eslint-scope@^3.7.3":
"@types/eslint-scope@^3.7.3":
version "3.7.4"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16"
integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==
@ -1373,11 +1387,6 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2"
integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==
"@types/estree@^0.0.50":
version "0.0.50"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
"@types/estree@^0.0.51":
version "0.0.51"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40"
@ -1720,6 +1729,16 @@
estree-walker "^2.0.2"
source-map "^0.6.1"
"@vue/compiler-core@3.2.47":
version "3.2.47"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.47.tgz#3e07c684d74897ac9aa5922c520741f3029267f8"
integrity sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/shared" "3.2.47"
estree-walker "^2.0.2"
source-map "^0.6.1"
"@vue/compiler-dom@3.2.35":
version "3.2.35"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.35.tgz#11bbcca0d49f9991d64dd8fbf8a0a4453caa571c"
@ -1736,6 +1755,14 @@
"@vue/compiler-core" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/compiler-dom@3.2.47", "@vue/compiler-dom@^3.0.1":
version "3.2.47"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz#a0b06caf7ef7056939e563dcaa9cbde30794f305"
integrity sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==
dependencies:
"@vue/compiler-core" "3.2.47"
"@vue/shared" "3.2.47"
"@vue/compiler-sfc@3.2.35":
version "3.2.35"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.35.tgz#1de80f858b33548bc22d166126234435937ebe0c"
@ -1784,6 +1811,14 @@
"@vue/compiler-dom" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/compiler-ssr@3.2.47":
version "3.2.47"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz#35872c01a273aac4d6070ab9d8da918ab13057ee"
integrity sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==
dependencies:
"@vue/compiler-dom" "3.2.47"
"@vue/shared" "3.2.47"
"@vue/devtools-api@^6.0.0", "@vue/devtools-api@^6.0.0-beta.11":
version "6.2.1"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092"
@ -1867,6 +1902,14 @@
"@vue/compiler-ssr" "3.2.35"
"@vue/shared" "3.2.35"
"@vue/server-renderer@^3.0.1":
version "3.2.47"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.47.tgz#8aa1d1871fc4eb5a7851aa7f741f8f700e6de3c0"
integrity sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==
dependencies:
"@vue/compiler-ssr" "3.2.47"
"@vue/shared" "3.2.47"
"@vue/shared@3.2.33":
version "3.2.33"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.33.tgz#69a8c99ceb37c1b031d5cc4aec2ff1dc77e1161e"
@ -1882,10 +1925,20 @@
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.37.tgz#8e6adc3f2759af52f0e85863dfb0b711ecc5c702"
integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==
"@vue/test-utils@2.2.7":
version "2.2.7"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.2.7.tgz#0d93d635031a4cca2de70b825aef3fe20a41e702"
integrity sha512-BMuoruUFTEqhLoOgsMcgNVMiByYbfHCKGr2C4CPdGtz/affUtDVX5zr1RnPuq0tYSiaqq+Enw5voUpG6JY8Q7g==
"@vue/shared@3.2.47":
version "3.2.47"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.47.tgz#e597ef75086c6e896ff5478a6bfc0a7aa4bbd14c"
integrity sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==
"@vue/test-utils@2.3.1":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.3.1.tgz#411883ea52091fa3e59d9b0b83f2934111c10776"
integrity sha512-tRtHRPEETQSUrqXgAewNZHm5iypxDFxwenfdcvMRm1kbGo4bcqHb1XHHlsaIjoDbLkuE2NYiF8vBQDNYrzlrSA==
dependencies:
js-beautify "1.14.6"
optionalDependencies:
"@vue/compiler-dom" "^3.0.1"
"@vue/server-renderer" "^3.0.1"
"@webassemblyjs/ast@1.11.1":
version "1.11.1"
@ -2035,7 +2088,7 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
abbrev@1:
abbrev@1, abbrev@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
@ -2440,6 +2493,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.2, braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@ -2771,7 +2831,7 @@ commander@9.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-9.0.0.tgz#86d58f24ee98126568936bd1d3574e0308a99a40"
integrity sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==
commander@^2.20.0:
commander@^2.19.0, commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@ -2804,6 +2864,14 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
config-chain@^1.1.13:
version "1.1.13"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
dependencies:
ini "^1.3.4"
proto-list "~1.2.1"
console-control-strings@^1.0.0, console-control-strings@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
@ -3231,6 +3299,16 @@ ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer "^5.0.1"
editorconfig@^0.15.3:
version "0.15.3"
resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5"
integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==
dependencies:
commander "^2.19.0"
lru-cache "^4.1.5"
semver "^5.6.0"
sigmund "^1.0.1"
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -3307,7 +3385,7 @@ engine.io@~6.2.0:
engine.io-parser "~5.0.3"
ws "~8.2.3"
enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.3, enhanced-resolve@^5.9.3:
enhanced-resolve@^5.0.0, enhanced-resolve@^5.9.3:
version "5.10.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6"
integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==
@ -3315,6 +3393,14 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.3, enhanced-resolve@^5.9.3:
graceful-fs "^4.2.4"
tapable "^2.2.0"
enhanced-resolve@^5.10.0:
version "5.12.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634"
integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
entities@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
@ -4036,6 +4122,17 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^8.0.3:
version "8.1.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^5.0.1"
once "^1.3.0"
global-modules@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
@ -4390,7 +4487,7 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.4:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ini@^1.3.5, ini@~1.3.0:
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
@ -4738,6 +4835,16 @@ jest-worker@^27.4.5:
merge-stream "^2.0.0"
supports-color "^8.0.0"
js-beautify@1.14.6:
version "1.14.6"
resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.6.tgz#b23ca5d74a462c282c7711bb51150bcc97f2b507"
integrity sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==
dependencies:
config-chain "^1.1.13"
editorconfig "^0.15.3"
glob "^8.0.3"
nopt "^6.0.0"
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@ -4773,7 +4880,7 @@ json-buffer@3.0.1, json-buffer@~3.0.1:
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
json-parse-better-errors@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
@ -5001,6 +5108,14 @@ lowercase-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lru-cache@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
dependencies:
pseudomap "^1.0.2"
yallist "^2.1.2"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@ -5074,13 +5189,20 @@ 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.4.1:
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==
dependencies:
fs-monkey "^1.0.3"
memfs@^3.4.3:
version "3.4.13"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.13.tgz#248a8bd239b3c240175cd5ec548de5227fc4f345"
integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==
dependencies:
fs-monkey "^1.0.3"
memorystream@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
@ -5212,6 +5334,13 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
minimatch@^5.0.1:
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
minimist-options@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619"
@ -5397,13 +5526,13 @@ nise@^4.0.4:
just-extend "^4.0.2"
path-to-regexp "^1.7.0"
nise@^5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.1.tgz#ac4237e0d785ecfcb83e20f389185975da5c31f3"
integrity sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==
nise@^5.1.1:
version "5.1.4"
resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.4.tgz#491ce7e7307d4ec546f5a659b2efe94a18b4bbc0"
integrity sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==
dependencies:
"@sinonjs/commons" "^1.8.3"
"@sinonjs/fake-timers" ">=5"
"@sinonjs/commons" "^2.0.0"
"@sinonjs/fake-timers" "^10.0.2"
"@sinonjs/text-encoding" "^0.7.1"
just-extend "^4.0.2"
path-to-regexp "^1.7.0"
@ -5465,6 +5594,13 @@ nopt@^5.0.0:
dependencies:
abbrev "1"
nopt@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d"
integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==
dependencies:
abbrev "^1.0.0"
normalize-package-data@^2.3.2, normalize-package-data@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@ -6382,10 +6518,10 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@8.4.19:
version "8.4.19"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc"
integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==
postcss@8.4.21:
version "8.4.21"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4"
integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==
dependencies:
nanoid "^3.3.4"
picocolors "^1.0.0"
@ -6459,6 +6595,11 @@ promise-retry@^2.0.1:
err-code "^2.0.2"
retry "^0.12.0"
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
proxy-addr@~2.0.7:
version "2.0.7"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
@ -6467,6 +6608,11 @@ proxy-addr@~2.0.7:
forwarded "0.2.0"
ipaddr.js "1.9.1"
pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
@ -6843,7 +6989,7 @@ semver-regex@^3.1.2:
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.4.tgz#13053c0d4aa11d070a2f2872b6b1e3ae1e1971b4"
integrity sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==
"semver@2 || 3 || 4 || 5", semver@^5.5.0:
"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@ -6963,21 +7109,26 @@ side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
sigmund@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
integrity sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
sinon@13.0.0:
version "13.0.0"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-13.0.0.tgz#3701f90204a1baa7457a3da70c9adcf335e92056"
integrity sha512-3tjMDB/tY04b06Bnb4aMKQfNrau2C9HET+R4HVWfv2KegDVLGg4wnBqjVepvxR7S7R1GTwDZzEv52tpFipt6yA==
sinon@13.0.2:
version "13.0.2"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-13.0.2.tgz#c6a8ddd655dc1415bbdc5ebf0e5b287806850c3a"
integrity sha512-KvOrztAVqzSJWMDoxM4vM+GPys1df2VBoXm+YciyB/OLMamfS3VXh3oGh5WtrAGSzrgczNWFFY22oKb7Fi5eeA==
dependencies:
"@sinonjs/commons" "^1.8.3"
"@sinonjs/fake-timers" "^9.0.0"
"@sinonjs/fake-timers" "^9.1.2"
"@sinonjs/samsam" "^6.1.1"
diff "^5.0.0"
nise "^5.1.0"
nise "^5.1.1"
supports-color "^7.2.0"
sinon@^9.0.3:
@ -7152,10 +7303,10 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
sqlite3@5.1.4:
version "5.1.4"
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.1.4.tgz#35f83d368963168b324ad2f0fffce09f3b8723a7"
integrity sha512-i0UlWAzPlzX3B5XP2cYuhWQJsTtlMD6obOa1PgeEQ4DHEXUuyJkgv50I3isqZAP5oFc2T8OFvakmDh2W6I+YpA==
sqlite3@5.1.6:
version "5.1.6"
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.1.6.tgz#1d4fbc90fe4fbd51e952e0a90fd8f6c2b9098e97"
integrity sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.0"
node-addon-api "^4.2.0"
@ -7828,10 +7979,10 @@ vue-eslint-parser@^9.0.1:
lodash "^4.17.21"
semver "^7.3.6"
vue-loader@17.0.0:
version "17.0.0"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-17.0.0.tgz#2eaa80aab125b19f00faa794b5bd867b17f85acb"
integrity sha512-OWSXjrzIvbF2LtOUmxT3HYgwwubbfFelN8PAP9R9dwpIkj48TVioHhWWSx7W7fk+iF5cgg3CBJRxwTdtLU4Ecg==
vue-loader@17.0.1:
version "17.0.1"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-17.0.1.tgz#c0ee8875e0610a0c2d13ba9b4d50a9c8442e7a3a"
integrity sha512-/OOyugJnImKCkAKrAvdsWMuwoCqGxWT5USLsjohzWbMgOwpA5wQmzQiLMzZd7DjhIfunzAGIApTOgIylz/kwcg==
dependencies:
chalk "^4.1.0"
hash-sum "^2.0.0"
@ -7862,7 +8013,7 @@ vuex@4.0.2:
dependencies:
"@vue/devtools-api" "^6.0.0-beta.11"
watchpack@^2.3.1:
watchpack@^2.3.1, watchpack@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"
integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==
@ -7905,13 +8056,13 @@ webpack-cli@4.9.2:
rechoir "^0.7.0"
webpack-merge "^5.7.3"
webpack-dev-middleware@5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c"
integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg==
webpack-dev-middleware@5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f"
integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==
dependencies:
colorette "^2.0.10"
memfs "^3.2.2"
memfs "^3.4.3"
mime-types "^2.1.31"
range-parser "^1.2.1"
schema-utils "^4.0.0"
@ -7939,34 +8090,34 @@ webpack-sources@^3.2.3:
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
webpack@5.68.0:
version "5.68.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.68.0.tgz#a653a58ed44280062e47257f260117e4be90d560"
integrity sha512-zUcqaUO0772UuuW2bzaES2Zjlm/y3kRBQDVFVCge+s2Y8mwuUTdperGaAv65/NtRL/1zanpSJOq/MD8u61vo6g==
webpack@5.76.0:
version "5.76.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c"
integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==
dependencies:
"@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.50"
"@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 "^8.7.1"
acorn-import-assertions "^1.7.6"
browserslist "^4.14.5"
chrome-trace-event "^1.0.2"
enhanced-resolve "^5.8.3"
enhanced-resolve "^5.10.0"
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"
json-parse-even-better-errors "^2.3.1"
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"
watchpack "^2.4.0"
webpack-sources "^3.2.3"
webpack@^5:
@ -8151,6 +8302,11 @@ y18n@^5.0.5:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"