Merge remote-tracking branch 'origin/master' into max/04-10-web-push-neo

This commit is contained in:
Max Leiter
2026-04-12 13:13:24 -07:00
12 changed files with 327 additions and 915 deletions

View File

@@ -3,10 +3,10 @@
<aside class="settings-menu">
<h2>Settings</h2>
<ul role="navigation" aria-label="Settings tabs">
<SettingTabItem name="General" class-name="general" to="" />
<SettingTabItem v-if="showGeneral" name="General" class-name="general" to="" />
<SettingTabItem name="Appearance" class-name="appearance" to="appearance" />
<SettingTabItem name="Notifications" class-name="notifications" to="notifications" />
<SettingTabItem name="Account" class-name="account" to="account" />
<SettingTabItem v-if="!isPublic" name="Account" class-name="account" to="account" />
</ul>
</aside>
</template>
@@ -93,11 +93,18 @@
<script lang="ts">
import SettingTabItem from "./SettingTabItem.vue";
import {defineComponent} from "vue";
import {useStore} from "../../js/store";
export default defineComponent({
name: "SettingsTabs",
components: {
SettingTabItem,
},
setup() {
const store = useStore();
const isPublic = store.state.serverConfiguration?.public;
const showGeneral = !isPublic || store.state.serverConfiguration?.fileUpload;
return {isPublic, showGeneral};
},
});
</script>

View File

@@ -84,9 +84,6 @@
"web-push-neo": "0.1.2",
"yarn": "1.22.22"
},
"optionalDependencies": {
"sqlite3": "6.0.1"
},
"devDependencies": {
"@babel/core": "7.17.10",
"@babel/plugin-transform-runtime": "7.18.2",

View File

@@ -150,7 +150,11 @@ class Client {
}
for (const messageStorage of client.messageStorage) {
messageStorage.enable().catch((e) => log.error(e));
try {
messageStorage.enable();
} catch (e: any) {
log.error(e);
}
}
}
@@ -645,11 +649,15 @@ class Client {
}
for (const messageStorage of this.messageStorage) {
messageStorage.deleteChannel(target.network, target.chan).catch((e) => log.error(e));
try {
messageStorage.deleteChannel(target.network, target.chan);
} catch (e: any) {
log.error(e);
}
}
}
async search(query: SearchQuery): Promise<SearchResponse> {
search(query: SearchQuery): SearchResponse {
if (!this.messageProvider?.isEnabled) {
return {
...query,
@@ -778,7 +786,11 @@ class Client {
});
for (const messageStorage of this.messageStorage) {
messageStorage.close().catch((e) => log.error(e));
try {
messageStorage.close();
} catch (e: any) {
log.error(e);
}
}
}

View File

@@ -15,10 +15,12 @@ program
.description("Migrate message storage where needed")
.on("--help", Utils.extraHelp)
.action(function (user) {
runMigrations(user).catch((err) => {
try {
runMigrations(user);
} catch (err: any) {
log.error(err.toString());
process.exit(1);
});
}
});
program
@@ -27,13 +29,15 @@ program
.description("Delete messages from the DB based on the storage policy")
.on("--help", Utils.extraHelp)
.action(function (user) {
runCleaning(user).catch((err) => {
try {
runCleaning(user);
} catch (err: any) {
log.error(err.toString());
process.exit(1);
});
}
});
async function runMigrations(user?: string) {
function runMigrations(user?: string) {
const manager = new ClientManager();
const users = manager.getUsers();
@@ -46,14 +50,14 @@ async function runMigrations(user?: string) {
}
for (const name of users) {
await migrateUser(manager, name);
migrateUser(manager, name);
// if any migration fails we blow up,
// chances are the rest won't complete either
}
}
// runs sqlite migrations for a user, which must exist
async function migrateUser(manager: ClientManager, user: string) {
function migrateUser(manager: ClientManager, user: string) {
log.info("handling user", user);
if (!isUserLogEnabled(manager, user)) {
@@ -62,8 +66,8 @@ async function migrateUser(manager: ClientManager, user: string) {
}
const sqlite = new SqliteMessageStorage(user);
await sqlite.enable(); // enable runs migrations
await sqlite.close();
sqlite.enable();
sqlite.close();
log.info("user", user, "migrated successfully");
}
@@ -78,7 +82,7 @@ function isUserLogEnabled(manager: ClientManager, user: string): boolean {
return conf.log;
}
async function runCleaning(user: string) {
function runCleaning(user: string) {
const manager = new ClientManager();
const users = manager.getUsers();
@@ -91,13 +95,13 @@ async function runCleaning(user: string) {
}
for (const name of users) {
await cleanUser(manager, name);
cleanUser(manager, name);
// if any migration fails we blow up,
// chances are the rest won't complete either
}
}
async function cleanUser(manager: ClientManager, user: string) {
function cleanUser(manager: ClientManager, user: string) {
log.info("handling user", user);
if (!isUserLogEnabled(manager, user)) {
@@ -106,17 +110,17 @@ async function cleanUser(manager: ClientManager, user: string) {
}
const sqlite = new SqliteMessageStorage(user);
await sqlite.enable();
sqlite.enable();
const cleaner = new StorageCleaner(sqlite);
const num_deleted = await cleaner.runDeletesNoLimit();
const num_deleted = cleaner.runDeletesNoLimit();
log.info(`deleted ${num_deleted} messages`);
log.info("running a vacuum now, this might take a while");
if (num_deleted > 0) {
await sqlite.vacuum();
sqlite.vacuum();
}
await sqlite.close();
sqlite.close();
log.info(`cleaning messages for ${user} has been successful`);
}

View File

@@ -261,7 +261,11 @@ class Chan {
}
for (const messageStorage of client.messageStorage) {
messageStorage.index(target.network, targetChannel, msg).catch((e) => log.error(e));
try {
messageStorage.index(target.network, targetChannel, msg);
} catch (e: any) {
log.error(e);
}
}
}
@@ -288,38 +292,41 @@ class Chan {
return;
}
client.messageProvider
.getMessages(network, this, () => client.idMsg++)
.then((messages) => {
if (messages.length === 0) {
if (network.irc!.network.cap.isEnabled("znc.in/playback")) {
requestZncPlayback(this, network, 0);
}
return;
}
this.messages = messages.concat(this.messages);
if (!this.firstUnread) {
this.firstUnread = messages[messages.length - 1].id;
}
client.emit("more", {
chan: this.id,
messages: messages.slice(-100),
totalMessages: messages.length,
});
if (network.irc!.network.cap.isEnabled("znc.in/playback")) {
const from = Math.floor(messages[messages.length - 1].time.getTime() / 1000);
requestZncPlayback(this, network, from);
}
})
.catch((err: Error) =>
log.error(`Failed to load messages for ${client.name}: ${err.toString()}`)
try {
const messages = client.messageProvider.getMessages(
network,
this,
() => client.idMsg++
);
if (messages.length === 0) {
if (network.irc!.network.cap.isEnabled("znc.in/playback")) {
requestZncPlayback(this, network, 0);
}
return;
}
this.messages = messages.concat(this.messages);
if (!this.firstUnread) {
this.firstUnread = messages[messages.length - 1].id;
}
client.emit("more", {
chan: this.id,
messages: messages.slice(-100),
totalMessages: messages.length,
});
if (network.irc!.network.cap.isEnabled("znc.in/playback")) {
const from = Math.floor(messages[messages.length - 1].time.getTime() / 1000);
requestZncPlayback(this, network, from);
}
} catch (err: any) {
log.error(`Failed to load messages for ${client.name}: ${err.toString()}`);
}
}
isLoggable() {

View File

@@ -1,8 +1,8 @@
import type {Database} from "sqlite3";
import {DatabaseSync} from "node:sqlite";
import log from "../../log";
import path from "path";
import fs from "fs/promises";
import {mkdirSync} from "fs";
import Config from "../../config";
import Msg, {Message} from "../../models/msg";
import Chan, {Channel} from "../../models/chan";
@@ -11,19 +11,6 @@ import type {SearchableMessageStorage, DeletionRequest} from "./types";
import Network from "../../models/network";
import {SearchQuery, SearchResponse} from "../../../shared/types/storage";
// TODO; type
let sqlite3: any;
try {
sqlite3 = require("sqlite3");
} catch (e: any) {
Config.values.messageStorage = Config.values.messageStorage.filter((item) => item !== "sqlite");
log.error(
"Unable to load sqlite3 module. See https://github.com/mapbox/node-sqlite3/wiki/Binaries"
);
}
type Migration = {version: number; stmts: string[]};
type Rollback = {version: number; rollback_forbidden?: boolean; stmts: string[]};
@@ -103,35 +90,21 @@ export const rollbacks: Rollback[] = [
},
];
class Deferred {
resolve!: () => void;
promise: Promise<void>;
constructor() {
this.promise = new Promise((resolve) => {
this.resolve = resolve;
});
}
}
class SqliteMessageStorage implements SearchableMessageStorage {
isEnabled: boolean;
database!: Database;
initDone: Deferred;
database!: DatabaseSync;
userName: string;
constructor(userName: string) {
this.userName = userName;
this.isEnabled = false;
this.initDone = new Deferred();
}
async _enable(connection_string: string) {
this.database = new sqlite3.Database(connection_string);
_enable(connection_string: string) {
this.database = new DatabaseSync(connection_string);
try {
await this.run_pragmas(); // must be done outside of a transaction
await this.run_migrations();
this.run_migrations();
} catch (e) {
this.isEnabled = false;
throw Helper.catch_to_error("Migration failed", e);
@@ -140,46 +113,35 @@ class SqliteMessageStorage implements SearchableMessageStorage {
this.isEnabled = true;
}
async enable() {
enable() {
const logsPath = Config.getUserLogsPath();
const sqlitePath = path.join(logsPath, `${this.userName}.sqlite3`);
try {
await fs.mkdir(logsPath, {recursive: true});
} catch (e) {
throw Helper.catch_to_error("Unable to create logs directory", e);
}
try {
await this._enable(sqlitePath);
} finally {
this.initDone.resolve(); // unblock the instance methods
}
mkdirSync(logsPath, {recursive: true});
this._enable(sqlitePath);
}
async setup_new_db() {
setup_new_db() {
for (const stmt of schema) {
await this.serialize_run(stmt);
this.database.exec(stmt);
}
await this.serialize_run(
"INSERT INTO options (name, value) VALUES ('schema_version', ?)",
currentSchemaVersion.toString()
);
this.database
.prepare("INSERT INTO options (name, value) VALUES ('schema_version', ?)")
.run(currentSchemaVersion.toString());
}
async current_version(): Promise<number> {
const have_options = await this.serialize_get(
"select 1 from sqlite_master where type = 'table' and name = 'options'"
);
current_version(): number {
const have_options = this.database
.prepare("select 1 from sqlite_master where type = 'table' and name = 'options'")
.get();
if (!have_options) {
return 0;
}
const version = await this.serialize_get(
"SELECT value FROM options WHERE name = 'schema_version'"
);
const version = this.database
.prepare("SELECT value FROM options WHERE name = 'schema_version'")
.get() as {value: string} | undefined;
if (version === undefined) {
// technically shouldn't happen, means something created a schema but didn't populate it
@@ -191,14 +153,13 @@ class SqliteMessageStorage implements SearchableMessageStorage {
return storedSchemaVersion;
}
async update_version_in_db() {
return this.serialize_run(
"UPDATE options SET value = ? WHERE name = 'schema_version'",
currentSchemaVersion.toString()
);
update_version_in_db() {
this.database
.prepare("UPDATE options SET value = ? WHERE name = 'schema_version'")
.run(currentSchemaVersion.toString());
}
async _run_migrations(dbVersion: number) {
_run_migrations(dbVersion: number) {
log.info(
`sqlite messages schema version is out of date (${dbVersion} < ${currentSchemaVersion}). Running migrations.`
);
@@ -206,18 +167,14 @@ class SqliteMessageStorage implements SearchableMessageStorage {
const to_execute = necessaryMigrations(dbVersion);
for (const stmt of to_execute.map((m) => m.stmts).flat()) {
await this.serialize_run(stmt);
this.database.exec(stmt);
}
await this.update_version_in_db();
this.update_version_in_db();
}
async run_pragmas() {
await this.serialize_run("PRAGMA foreign_keys = ON;");
}
async run_migrations() {
const version = await this.current_version();
run_migrations() {
const version = this.current_version();
if (version > currentSchemaVersion) {
throw `sqlite messages schema version is higher than expected (${version} > ${currentSchemaVersion}). Is The Lounge out of date?`;
@@ -225,58 +182,54 @@ class SqliteMessageStorage implements SearchableMessageStorage {
return; // nothing to do
}
await this.serialize_run("BEGIN EXCLUSIVE TRANSACTION");
this.database.exec("BEGIN EXCLUSIVE TRANSACTION");
try {
if (version === 0) {
await this.setup_new_db();
this.setup_new_db();
} else {
await this._run_migrations(version);
this._run_migrations(version);
}
await this.insert_rollback_since(version);
this.insert_rollback_since(version);
} catch (err) {
await this.serialize_run("ROLLBACK");
this.database.exec("ROLLBACK");
throw err;
}
await this.serialize_run("COMMIT");
await this.serialize_run("VACUUM");
this.database.exec("COMMIT");
this.database.exec("VACUUM");
}
// helper method that vacuums the db, meant to be used by migration related cli commands
async vacuum() {
await this.serialize_run("VACUUM");
vacuum() {
this.database.exec("VACUUM");
}
async close() {
close() {
if (!this.isEnabled) {
return;
}
this.isEnabled = false;
return new Promise<void>((resolve, reject) => {
this.database.close((err) => {
if (err) {
reject(`Failed to close sqlite database: ${err.message}`);
return;
}
resolve();
});
});
this.database.close();
}
async fetch_rollbacks(since_version: number) {
const res = await this.serialize_fetchall(
`select version, rollback_forbidden, statement
from rollback_steps
join migrations on migrations.id=rollback_steps.migration_id
where version > ?
order by version desc, step asc`,
since_version
);
fetch_rollbacks(since_version: number): Rollback[] {
const res = this.database
.prepare(
`select version, rollback_forbidden, statement
from rollback_steps
join migrations on migrations.id=rollback_steps.migration_id
where version > ?
order by version desc, step asc`
)
.all(since_version) as {
version: number;
rollback_forbidden: number;
statement: string;
}[];
const result: Rollback[] = [];
// convert to Rollback[]
@@ -298,12 +251,12 @@ class SqliteMessageStorage implements SearchableMessageStorage {
return result;
}
async delete_migrations_older_than(version: number) {
return this.serialize_run("delete from migrations where migrations.version > ?", version);
delete_migrations_older_than(version: number) {
this.database.prepare("delete from migrations where migrations.version > ?").run(version);
}
async _downgrade_to(version: number) {
const _rollbacks = await this.fetch_rollbacks(version);
_downgrade_to(version: number): number {
const _rollbacks = this.fetch_rollbacks(version);
if (_rollbacks.length === 0) {
return version;
@@ -317,72 +270,69 @@ class SqliteMessageStorage implements SearchableMessageStorage {
for (const rollback of _rollbacks) {
for (const stmt of rollback.stmts) {
await this.serialize_run(stmt);
this.database.exec(stmt);
}
}
await this.delete_migrations_older_than(version);
await this.update_version_in_db();
this.delete_migrations_older_than(version);
this.update_version_in_db();
return version;
}
async downgrade_to(version: number) {
downgrade_to(version: number): number {
if (version <= 0) {
throw Error(`${version} is not a valid version to downgrade to`);
}
await this.serialize_run("BEGIN EXCLUSIVE TRANSACTION");
this.database.exec("BEGIN EXCLUSIVE TRANSACTION");
let new_version: number;
try {
new_version = await this._downgrade_to(version);
new_version = this._downgrade_to(version);
} catch (err) {
await this.serialize_run("ROLLBACK");
this.database.exec("ROLLBACK");
throw err;
}
await this.serialize_run("COMMIT");
this.database.exec("COMMIT");
return new_version;
}
async downgrade() {
const res = await this.downgrade_to(currentSchemaVersion);
return res;
downgrade() {
return this.downgrade_to(currentSchemaVersion);
}
async insert_rollback_since(version: number) {
insert_rollback_since(version: number) {
const missing = newRollbacks(version);
for (const rollback of missing) {
const migration = await this.serialize_get(
`insert into migrations
(version, rollback_forbidden)
values (?, ?)
returning id`,
rollback.version,
rollback.rollback_forbidden || 0
);
const migration = this.database
.prepare(
`insert into migrations
(version, rollback_forbidden)
values (?, ?)
returning id`
)
.get(rollback.version, rollback.rollback_forbidden ? 1 : 0) as {id: number};
let step = 0;
for (const stmt of rollback.stmts) {
let step = 0;
await this.serialize_run(
`insert into rollback_steps
(migration_id, step, statement)
values (?, ?, ?)`,
migration.id,
step,
stmt
);
this.database
.prepare(
`insert into rollback_steps
(migration_id, step, statement)
values (?, ?, ?)`
)
.run(migration.id, step, stmt);
step++;
}
}
}
async index(network: Network, channel: Chan, msg: Msg) {
await this.initDone.promise;
index(network: Network, channel: Chan, msg: Msg) {
if (!this.isEnabled) {
return;
}
@@ -398,38 +348,30 @@ class SqliteMessageStorage implements SearchableMessageStorage {
return newMsg;
}, {});
await this.serialize_run(
"INSERT INTO messages(network, channel, time, type, msg) VALUES(?, ?, ?, ?, ?)",
network.uuid,
channel.name.toLowerCase(),
msg.time.getTime(),
msg.type,
JSON.stringify(clonedMsg)
);
this.database
.prepare(
"INSERT INTO messages(network, channel, time, type, msg) VALUES(?, ?, ?, ?, ?)"
)
.run(
network.uuid,
channel.name.toLowerCase(),
msg.time.getTime(),
msg.type,
JSON.stringify(clonedMsg)
);
}
async deleteChannel(network: Network, channel: Channel) {
await this.initDone.promise;
deleteChannel(network: Network, channel: Channel) {
if (!this.isEnabled) {
return;
}
await this.serialize_run(
"DELETE FROM messages WHERE network = ? AND channel = ?",
network.uuid,
channel.name.toLowerCase()
);
this.database
.prepare("DELETE FROM messages WHERE network = ? AND channel = ?")
.run(network.uuid, channel.name.toLowerCase());
}
async getMessages(
network: Network,
channel: Channel,
nextID: () => number
): Promise<Message[]> {
await this.initDone.promise;
getMessages(network: Network, channel: Channel, nextID: () => number): Message[] {
if (!this.isEnabled || Config.values.maxHistory === 0) {
return [];
}
@@ -437,14 +379,17 @@ class SqliteMessageStorage implements SearchableMessageStorage {
// If unlimited history is specified, load 100k messages
const limit = Config.values.maxHistory < 0 ? 100000 : Config.values.maxHistory;
const rows = await this.serialize_fetchall(
"SELECT msg, type, time FROM messages WHERE network = ? AND channel = ? ORDER BY time DESC LIMIT ?",
network.uuid,
channel.name.toLowerCase(),
limit
);
const rows = this.database
.prepare(
"SELECT msg, type, time FROM messages WHERE network = ? AND channel = ? ORDER BY time DESC LIMIT ?"
)
.all(network.uuid, channel.name.toLowerCase(), limit) as {
msg: string;
type: string;
time: number;
}[];
return rows.reverse().map((row: any): Message => {
return rows.reverse().map((row): Message => {
const msg = JSON.parse(row.msg);
msg.time = row.time;
msg.type = row.type;
@@ -456,9 +401,7 @@ class SqliteMessageStorage implements SearchableMessageStorage {
});
}
async search(query: SearchQuery): Promise<SearchResponse> {
await this.initDone.promise;
search(query: SearchQuery): SearchResponse {
if (!this.isEnabled) {
// this should never be hit as messageProvider is checked in client.search()
throw new Error(
@@ -471,7 +414,7 @@ class SqliteMessageStorage implements SearchableMessageStorage {
let select =
"SELECT msg, type, time, network, channel FROM messages WHERE type = 'message' AND json_extract(msg, '$.text') LIKE ? ESCAPE '@'";
const params: any[] = [`%${escapedSearchTerm}%`];
const params: (string | number)[] = [`%${escapedSearchTerm}%`];
if (query.networkUuid) {
select += " AND network = ? ";
@@ -489,15 +432,21 @@ class SqliteMessageStorage implements SearchableMessageStorage {
params.push(maxResults);
params.push(query.offset);
const rows = await this.serialize_fetchall(select, ...params);
const rows = this.database.prepare(select).all(...params) as {
msg: string;
type: string;
time: number;
network: string;
channel: string;
}[];
return {
...query,
results: parseSearchRowsToMessages(query.offset, rows).reverse(),
};
}
async deleteMessages(req: DeletionRequest): Promise<number> {
await this.initDone.promise;
deleteMessages(req: DeletionRequest): number {
let sql = "delete from messages where id in (select id from messages where\n";
// We roughly get a timestamp from N days before.
@@ -520,61 +469,19 @@ class SqliteMessageStorage implements SearchableMessageStorage {
sql += `limit ${req.limit}\n`;
sql += ")";
return this.serialize_run(sql);
return this.database.prepare(sql).run().changes as number;
}
canProvideMessages() {
return this.isEnabled;
}
private serialize_run(stmt: string, ...params: any[]): Promise<number> {
return new Promise((resolve, reject) => {
this.database.serialize(() => {
this.database.run(stmt, params, function (err) {
if (err) {
reject(err);
return;
}
resolve(this.changes); // number of affected rows, `this` is re-bound by sqlite3
});
});
});
}
private serialize_fetchall(stmt: string, ...params: any[]): Promise<any[]> {
return new Promise((resolve, reject) => {
this.database.serialize(() => {
this.database.all(stmt, params, (err, rows) => {
if (err) {
reject(err);
return;
}
resolve(rows);
});
});
});
}
private serialize_get(stmt: string, ...params: any[]): Promise<any> {
return new Promise((resolve, reject) => {
this.database.serialize(() => {
this.database.get(stmt, params, (err, row) => {
if (err) {
reject(err);
return;
}
resolve(row);
});
});
});
}
}
// TODO: type any
function parseSearchRowsToMessages(id: number, rows: any[]) {
function parseSearchRowsToMessages(
id: number,
rows: {msg: string; type: string; time: number; network: string; channel: string}[]
) {
const messages: Msg[] = [];
for (const row of rows) {

View File

@@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions */
import fs from "fs/promises";
import {mkdirSync, appendFileSync} from "fs";
import path from "path";
import filenamify from "filenamify";
@@ -19,17 +18,15 @@ class TextFileMessageStorage implements MessageStorage {
this.isEnabled = false;
}
// eslint-disable-next-line @typescript-eslint/require-await
async enable() {
enable() {
this.isEnabled = true;
}
// eslint-disable-next-line @typescript-eslint/require-await
async close() {
close() {
this.isEnabled = false;
}
async index(network: Network, channel: Channel, msg: Message) {
index(network: Network, channel: Channel, msg: Message) {
if (!this.isEnabled) {
return;
}
@@ -40,11 +37,7 @@ class TextFileMessageStorage implements MessageStorage {
TextFileMessageStorage.getNetworkFolderName(network)
);
try {
await fs.mkdir(logPath, {recursive: true});
} catch (e) {
throw new Error(`Unable to create logs directory: ${e}`);
}
mkdirSync(logPath, {recursive: true});
let line = `[${msg.time.toISOString()}] `;
@@ -102,25 +95,21 @@ class TextFileMessageStorage implements MessageStorage {
line += "\n";
try {
await fs.appendFile(
path.join(logPath, TextFileMessageStorage.getChannelFileName(channel)),
line
);
} catch (e) {
throw new Error(`Failed to write user log: ${e}`);
}
appendFileSync(
path.join(logPath, TextFileMessageStorage.getChannelFileName(channel)),
line
);
}
async deleteChannel() {
deleteChannel() {
// Not implemented for text log files
}
getMessages() {
getMessages(): Message[] {
// Not implemented for text log files
// They do not contain enough data to fully re-create message objects
// Use sqlite storage instead
return Promise.resolve([]);
return [];
}
canProvideMessages() {

View File

@@ -1,5 +1,3 @@
import type {Database} from "sqlite3";
import {Channel} from "../../models/channel";
import {Message} from "../../models/message";
import {Network} from "../../models/network";
@@ -16,20 +14,20 @@ export type DeletionRequest = {
interface MessageStorage {
isEnabled: boolean;
enable(): Promise<void>;
enable(): void;
close(): Promise<void>;
close(): void;
index(network: Network, channel: Channel, msg: Message): Promise<void>;
index(network: Network, channel: Channel, msg: Message): void;
deleteChannel(network: Network, channel: Channel): Promise<void>;
deleteChannel(network: Network, channel: Channel): void;
getMessages(network: Network, channel: Channel, nextID: () => number): Promise<Message[]>;
getMessages(network: Network, channel: Channel, nextID: () => number): Message[];
canProvideMessages(): boolean;
}
type SearchFunction = (query: SearchQuery) => Promise<SearchResponse>;
type SearchFunction = (query: SearchQuery) => SearchResponse;
export interface SearchableMessageStorage extends MessageStorage {
search: SearchFunction;

View File

@@ -760,8 +760,8 @@ function initializeClient(
socket.emit("setting:all", clientSettings);
});
socket.on("search", async (query) => {
const results = await client.search(query);
socket.on("search", (query) => {
const results = client.search(query);
socket.emit("search:results", results);
});

View File

@@ -61,7 +61,7 @@ export class StorageCleaner {
};
}
async runDeletesNoLimit(): Promise<number> {
runDeletesNoLimit(): number {
if (!Config.values.storagePolicy.enabled) {
// this is meant to be used by cli tools, so we guard against this
throw new Error("storage policy is disabled");
@@ -69,11 +69,10 @@ export class StorageCleaner {
const req = this.genDeletionRequest();
req.limit = -1; // unlimited
const num_deleted = await this.db.deleteMessages(req);
return num_deleted;
return this.db.deleteMessages(req);
}
private async runDeletes() {
private runDeletes() {
if (this.isStopped) {
return;
}
@@ -89,7 +88,7 @@ export class StorageCleaner {
let num_deleted = 0;
try {
num_deleted = await this.db.deleteMessages(req);
num_deleted = this.db.deleteMessages(req);
this.errCount = 0; // reset when it works
} catch (err: any) {
this.errCount++;
@@ -115,13 +114,13 @@ export class StorageCleaner {
}
private schedule(ms: number) {
const self = this;
this.ticker = setTimeout(() => {
self.runDeletes().catch((err) => {
try {
this.runDeletes();
} catch (err) {
log.error("storageCleaner: unexpected failure");
throw err;
});
}
}, ms);
}

View File

@@ -11,7 +11,7 @@ import MessageStorage, {
necessaryMigrations,
rollbacks,
} from "../../server/plugins/messageStorage/sqlite";
import sqlite3 from "sqlite3";
import {DatabaseSync} from "node:sqlite";
import {DeletionRequest} from "../../server/plugins/messageStorage/types";
const orig_schema = [
@@ -50,44 +50,26 @@ const v1_dummy_messages = [
];
describe("SQLite migrations", function () {
let db: sqlite3.Database;
let db: DatabaseSync;
function serialize_run(stmt: string, ...params: any[]): Promise<void> {
return new Promise((resolve, reject) => {
db.serialize(() => {
db.run(stmt, params, (err) => {
if (err) {
reject(err);
return;
}
resolve();
});
});
});
}
before(async function () {
db = new sqlite3.Database(":memory:");
before(function () {
db = new DatabaseSync(":memory:");
for (const stmt of orig_schema) {
await serialize_run(stmt);
db.exec(stmt);
}
const insert = db.prepare(
"INSERT INTO messages(network, channel, time, type, msg) VALUES(?, ?, ?, ?, ?)"
);
for (const msg of v1_dummy_messages) {
await serialize_run(
"INSERT INTO messages(network, channel, time, type, msg) VALUES(?, ?, ?, ?, ?)",
msg.network,
msg.channel,
msg.time,
msg.type,
msg.msg
);
insert.run(msg.network, msg.channel, msg.time, msg.type, msg.msg);
}
});
after(function (done) {
db.close(done);
after(function () {
db.close();
});
it("has a down migration for every migration", function () {
@@ -97,20 +79,20 @@ describe("SQLite migrations", function () {
);
});
it("has working up-migrations", async function () {
it("has working up-migrations", function () {
const to_execute = necessaryMigrations(v1_schema_version);
expect(to_execute.length).to.eq(migrations.length);
await serialize_run("BEGIN EXCLUSIVE TRANSACTION");
db.exec("BEGIN EXCLUSIVE TRANSACTION");
for (const stmt of to_execute.map((m) => m.stmts).flat()) {
await serialize_run(stmt);
db.exec(stmt);
}
await serialize_run("COMMIT TRANSACTION");
db.exec("COMMIT TRANSACTION");
});
it("has working down-migrations", async function () {
await serialize_run("BEGIN EXCLUSIVE TRANSACTION");
it("has working down-migrations", function () {
db.exec("BEGIN EXCLUSIVE TRANSACTION");
for (const rollback of rollbacks.slice().reverse()) {
if (rollback.rollback_forbidden) {
@@ -120,35 +102,34 @@ describe("SQLite migrations", function () {
}
for (const stmt of rollback.stmts) {
await serialize_run(stmt);
db.exec(stmt);
}
}
await serialize_run("COMMIT TRANSACTION");
db.exec("COMMIT TRANSACTION");
});
});
describe("SQLite unit tests", function () {
let store: MessageStorage;
beforeEach(async function () {
beforeEach(function () {
store = new MessageStorage("testUser");
await store._enable(":memory:");
store.initDone.resolve();
store._enable(":memory:");
});
afterEach(async function () {
await store.close();
afterEach(function () {
store.close();
});
it("deletes messages when asked to", async function () {
it("deletes messages when asked to", function () {
const baseDate = new Date();
const net = {uuid: "testnet"} as any;
const chan = {name: "#channel"} as any;
for (let i = 0; i < 14; ++i) {
await store.index(
store.index(
net,
chan,
new Msg({
@@ -165,29 +146,29 @@ describe("SQLite unit tests", function () {
olderThanDays: 2,
};
let deleted = await store.deleteMessages(delReq);
let deleted = store.deleteMessages(delReq);
expect(deleted).to.equal(limit, "number of deleted messages doesn't match");
let id = 0;
let messages = await store.getMessages(net, chan, () => id++);
let messages = store.getMessages(net, chan, () => id++);
expect(messages.find((m) => m.text === "msg 13")).to.be.undefined; // oldest gets deleted first
// let's test if it properly cleans now
delReq.limit = 100;
deleted = await store.deleteMessages(delReq);
deleted = store.deleteMessages(delReq);
expect(deleted).to.equal(11, "number of deleted messages doesn't match");
messages = await store.getMessages(net, chan, () => id++);
messages = store.getMessages(net, chan, () => id++);
expect(messages.map((m) => m.text)).to.have.ordered.members(["msg 1", "msg 0"]);
});
it("deletes only the types it should", async function () {
it("deletes only the types it should", function () {
const baseDate = new Date();
const net = {uuid: "testnet"} as any;
const chan = {name: "#channel"} as any;
for (let i = 0; i < 6; ++i) {
await store.index(
store.index(
net,
chan,
new Msg({
@@ -211,11 +192,11 @@ describe("SQLite unit tests", function () {
olderThanDays: 0,
};
let deleted = await store.deleteMessages(delReq);
let deleted = store.deleteMessages(delReq);
expect(deleted).to.equal(3, "number of deleted messages doesn't match");
let id = 0;
let messages = await store.getMessages(net, chan, () => id++);
let messages = store.getMessages(net, chan, () => id++);
expect(messages.map((m) => m.type)).to.have.ordered.members([
MessageType.MESSAGE,
MessageType.PART,
@@ -227,9 +208,9 @@ describe("SQLite unit tests", function () {
MessageType.PART,
MessageType.MESSAGE,
];
deleted = await store.deleteMessages(delReq);
deleted = store.deleteMessages(delReq);
expect(deleted).to.equal(2, "number of deleted messages doesn't match");
messages = await store.getMessages(net, chan, () => id++);
messages = store.getMessages(net, chan, () => id++);
expect(messages.map((m) => m.type)).to.have.ordered.members([MessageType.AWAY]);
});
});
@@ -242,36 +223,6 @@ describe("SQLite Message Storage", function () {
const expectedPath = path.join(Config.getHomePath(), "logs", "testUser.sqlite3");
let store: MessageStorage;
function db_get_one(stmt: string, ...params: any[]): Promise<any> {
return new Promise((resolve, reject) => {
store.database.serialize(() => {
store.database.get(stmt, params, (err, row) => {
if (err) {
reject(err);
return;
}
resolve(row);
});
});
});
}
function db_get_mult(stmt: string, ...params: any[]): Promise<any[]> {
return new Promise((resolve, reject) => {
store.database.serialize(() => {
store.database.all(stmt, params, (err, rows) => {
if (err) {
reject(err);
return;
}
resolve(rows);
});
});
});
}
before(function (done) {
store = new MessageStorage("testUser");
@@ -290,36 +241,37 @@ describe("SQLite Message Storage", function () {
fs.rmdir(path.join(Config.getHomePath(), "logs"), done);
});
it("should create database file", async function () {
it("should create database file", function () {
expect(store.isEnabled).to.be.false;
expect(fs.existsSync(expectedPath)).to.be.false;
await store.enable();
store.enable();
expect(store.isEnabled).to.be.true;
});
it("should resolve an empty array when disabled", async function () {
it("should resolve an empty array when disabled", function () {
store.isEnabled = false;
const messages = await store.getMessages(null as any, null as any, null as any);
const messages = store.getMessages(null as any, null as any, null as any);
expect(messages).to.be.empty;
store.isEnabled = true;
});
it("should insert schema version to options table", async function () {
const row = await db_get_one("SELECT value FROM options WHERE name = 'schema_version'");
it("should insert schema version to options table", function () {
const row = store.database
.prepare("SELECT value FROM options WHERE name = 'schema_version'")
.get() as {value: string};
expect(row.value).to.equal(currentSchemaVersion.toString());
});
it("should insert migrations", async function () {
const row = await db_get_one(
"SELECT id, version FROM migrations WHERE version = ?",
currentSchemaVersion
);
it("should insert migrations", function () {
const row = store.database
.prepare("SELECT id, version FROM migrations WHERE version = ?")
.get(currentSchemaVersion) as {id: number; version: number} | undefined;
expect(row).to.not.be.undefined;
});
it("should store a message", async function () {
await store.index(
it("should store a message", function () {
store.index(
{
uuid: "this-is-a-network-guid",
} as any,
@@ -333,9 +285,9 @@ describe("SQLite Message Storage", function () {
);
});
it("should retrieve previously stored message", async function () {
it("should retrieve previously stored message", function () {
let msgid = 0;
const messages = await store.getMessages(
const messages = store.getMessages(
{
uuid: "this-is-a-network-guid",
} as any,
@@ -351,14 +303,14 @@ describe("SQLite Message Storage", function () {
expect(msg.time.getTime()).to.equal(123456789);
});
it("should retrieve latest LIMIT messages in order", async function () {
it("should retrieve latest LIMIT messages in order", function () {
const originalMaxHistory = Config.values.maxHistory;
try {
Config.values.maxHistory = 2;
for (let i = 0; i < 200; ++i) {
await store.index(
store.index(
{uuid: "retrieval-order-test-network"} as any,
{name: "#channel"} as any,
new Msg({
@@ -369,7 +321,7 @@ describe("SQLite Message Storage", function () {
}
let msgId = 0;
const messages = await store.getMessages(
const messages = store.getMessages(
{uuid: "retrieval-order-test-network"} as any,
{name: "#channel"} as any,
() => msgId++
@@ -381,13 +333,13 @@ describe("SQLite Message Storage", function () {
}
});
it("should search messages", async function () {
it("should search messages", function () {
const originalMaxHistory = Config.values.maxHistory;
try {
Config.values.maxHistory = 2;
const search = await store.search({
const search = store.search({
searchTerm: "msg",
networkUuid: "retrieval-order-test-network",
channelName: "",
@@ -406,9 +358,9 @@ describe("SQLite Message Storage", function () {
}
});
it("should search messages with escaped wildcards", async function () {
async function assertResults(query: string, expected: string[]) {
const search = await store.search({
it("should search messages with escaped wildcards", function () {
function assertResults(query: string, expected: string[]) {
const search = store.search({
searchTerm: query,
networkUuid: "this-is-a-network-guid2",
channelName: "",
@@ -422,7 +374,7 @@ describe("SQLite Message Storage", function () {
try {
Config.values.maxHistory = 3;
await store.index(
store.index(
{uuid: "this-is-a-network-guid2"} as any,
{name: "#channel"} as any,
new Msg({
@@ -431,7 +383,7 @@ describe("SQLite Message Storage", function () {
} as any)
);
await store.index(
store.index(
{uuid: "this-is-a-network-guid2"} as any,
{name: "#channel"} as any,
new Msg({
@@ -440,7 +392,7 @@ describe("SQLite Message Storage", function () {
} as any)
);
await store.index(
store.index(
{uuid: "this-is-a-network-guid2"} as any,
{name: "#channel"} as any,
new Msg({
@@ -449,20 +401,20 @@ describe("SQLite Message Storage", function () {
} as any)
);
await assertResults("foo", ["foo % bar _ baz", "foo bar x baz"]);
await assertResults("%", ["foo % bar _ baz"]);
await assertResults("foo % bar ", ["foo % bar _ baz"]);
await assertResults("_", ["foo % bar _ baz"]);
await assertResults("bar _ baz", ["foo % bar _ baz"]);
await assertResults("%%", []);
await assertResults("@%", []);
await assertResults("@", ["bar @ baz"]);
assertResults("foo", ["foo % bar _ baz", "foo bar x baz"]);
assertResults("%", ["foo % bar _ baz"]);
assertResults("foo % bar ", ["foo % bar _ baz"]);
assertResults("_", ["foo % bar _ baz"]);
assertResults("bar _ baz", ["foo % bar _ baz"]);
assertResults("%%", []);
assertResults("@%", []);
assertResults("@", ["bar @ baz"]);
} finally {
Config.values.maxHistory = originalMaxHistory;
}
});
it("should be able to downgrade", async function () {
it("should be able to downgrade", function () {
for (const rollback of rollbacks.slice().reverse()) {
if (rollback.rollback_forbidden) {
throw Error(
@@ -470,13 +422,13 @@ describe("SQLite Message Storage", function () {
);
}
const new_version = await store.downgrade_to(rollback.version);
const new_version = store.downgrade_to(rollback.version);
expect(new_version).to.equal(rollback.version);
}
});
it("should close database", async function () {
await store.close();
it("should close database", function () {
store.close();
expect(fs.existsSync(expectedPath)).to.be.true;
});
});

478
yarn.lock
View File

@@ -1265,11 +1265,6 @@
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5"
integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==
"@gar/promise-retry@^1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@gar/promise-retry/-/promise-retry-1.0.3.tgz#65e726428e794bc4453948e0a41e6de4215ce8b0"
integrity sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==
"@humanwhocodes/config-array@^0.11.14":
version "0.11.14"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b"
@@ -1301,13 +1296,6 @@
wrap-ansi "^8.1.0"
wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
"@isaacs/fs-minipass@^4.0.0":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz#2d59ae3ab4b38fb4270bfa23d30f8e2e86c7fe32"
integrity sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==
dependencies:
minipass "^7.0.4"
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@@ -1608,29 +1596,6 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@npmcli/agent@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-4.0.0.tgz#2bb2b1c0a170940511554a7986ae2a8be9fedcce"
integrity sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==
dependencies:
agent-base "^7.1.0"
http-proxy-agent "^7.0.0"
https-proxy-agent "^7.0.1"
lru-cache "^11.2.1"
socks-proxy-agent "^8.0.3"
"@npmcli/fs@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-5.0.0.tgz#674619771907342b3d1ac197aaf1deeb657e3539"
integrity sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==
dependencies:
semver "^7.3.5"
"@npmcli/redact@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@npmcli/redact/-/redact-4.0.0.tgz#c91121e02b7559a997614a2c1057cd7fc67608c4"
integrity sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==
"@one-ini/wasm@0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@one-ini/wasm/-/wasm-0.1.1.tgz#6013659736c9dbfccc96e8a9c2b3de317df39323"
@@ -2660,11 +2625,6 @@ abbrev@^2.0.0:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf"
integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==
abbrev@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-4.0.0.tgz#ec933f0e27b6cd60e89b5c6b2a304af42209bb05"
integrity sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==
abstract-logging@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839"
@@ -2713,11 +2673,6 @@ acorn@^8.9.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
agent-base@^7.1.0, agent-base@^7.1.2:
version "7.1.4"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8"
integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==
aggregate-error@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
@@ -3005,11 +2960,6 @@ balanced-match@^2.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9"
integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==
balanced-match@^4.0.2:
version "4.0.4"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a"
integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@@ -3035,22 +2985,6 @@ big.js@^5.2.2:
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
bindings@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
dependencies:
file-uri-to-path "1.0.0"
bl@^4.0.3:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
dependencies:
buffer "^5.5.0"
inherits "^2.0.4"
readable-stream "^3.4.0"
body-parser@1.20.3:
version "1.20.3"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6"
@@ -3096,13 +3030,6 @@ brace-expansion@^2.0.2:
dependencies:
balanced-match "^1.0.0"
brace-expansion@^5.0.5:
version "5.0.5"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.5.tgz#dcc3a37116b79f3e1b46db994ced5d570e930fdb"
integrity sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==
dependencies:
balanced-match "^4.0.2"
braces@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
@@ -3141,14 +3068,6 @@ buffer-from@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.1.13"
buffer@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
@@ -3162,22 +3081,6 @@ bytes@3.1.2:
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
cacache@^20.0.1:
version "20.0.4"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-20.0.4.tgz#9b547dc3db0c1f87cba6dbbff91fb17181b4bbb1"
integrity sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==
dependencies:
"@npmcli/fs" "^5.0.0"
fs-minipass "^3.0.0"
glob "^13.0.0"
lru-cache "^11.1.0"
minipass "^7.0.3"
minipass-collect "^2.0.1"
minipass-flush "^1.0.5"
minipass-pipeline "^1.2.4"
p-map "^7.0.2"
ssri "^13.0.0"
cacheable-lookup@^5.0.3:
version "5.0.4"
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
@@ -3340,16 +3243,6 @@ chokidar@^4.0.1:
dependencies:
readdirp "^4.0.1"
chownr@^1.1.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
chownr@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-3.0.0.tgz#9855e64ecd240a9cc4267ce8a4aa5d24a1da15e4"
integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==
chrome-trace-event@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
@@ -3808,7 +3701,7 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -3909,11 +3802,6 @@ destroy@1.2.0:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
detect-libc@^2.0.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad"
integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
diff@^4.0.1, diff@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
@@ -4073,13 +3961,6 @@ end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
end-of-stream@^1.4.1:
version "1.4.5"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c"
integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==
dependencies:
once "^1.4.0"
engine.io-client@~6.2.1:
version "6.2.3"
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.2.3.tgz#a8cbdab003162529db85e9de31575097f6d29458"
@@ -4138,7 +4019,7 @@ entities@^4.2.0, entities@^4.4.0, entities@^4.5.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
env-paths@^2.2.0, env-paths@^2.2.1:
env-paths@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
@@ -4553,16 +4434,6 @@ execall@^2.0.0:
dependencies:
clone-regexp "^2.1.0"
expand-template@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
exponential-backoff@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz#51cf92c1c0493c766053f9d3abee4434c244d2f6"
integrity sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==
express@4.20.0:
version "4.20.0"
resolved "https://registry.yarnpkg.com/express/-/express-4.20.0.tgz#f1d08e591fcec770c07be4767af8eb9bcfd67c48"
@@ -4674,11 +4545,6 @@ file-type@16.5.4:
strtok3 "^6.2.4"
token-types "^4.1.1"
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
filename-reserved-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229"
@@ -4817,11 +4683,6 @@ fromentries@^1.2.0:
resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a"
integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-extra@^10.0.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
@@ -4831,13 +4692,6 @@ fs-extra@^10.0.0:
jsonfile "^6.0.1"
universalify "^2.0.0"
fs-minipass@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54"
integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==
dependencies:
minipass "^7.0.3"
fs-monkey@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3"
@@ -4937,11 +4791,6 @@ get-tsconfig@^4.7.5:
dependencies:
resolve-pkg-maps "^1.0.0"
github-from-package@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==
glob-parent@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -4989,15 +4838,6 @@ glob@^10.4.5:
package-json-from-dist "^1.0.0"
path-scurry "^1.11.1"
glob@^13.0.0:
version "13.0.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-13.0.6.tgz#078666566a425147ccacfbd2e332deb66a2be71d"
integrity sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==
dependencies:
minimatch "^10.2.2"
minipass "^7.1.3"
path-scurry "^2.0.2"
glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
@@ -5109,7 +4949,7 @@ graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0,
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
graceful-fs@^4.2.11, graceful-fs@^4.2.6:
graceful-fs@^4.2.11:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
@@ -5240,11 +5080,6 @@ http-cache-semantics@^4.0.0:
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
http-cache-semantics@^4.1.1:
version "4.2.0"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5"
integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==
http-errors@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
@@ -5256,14 +5091,6 @@ http-errors@2.0.0:
statuses "2.0.1"
toidentifier "1.0.1"
http-proxy-agent@^7.0.0:
version "7.0.2"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e"
integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==
dependencies:
agent-base "^7.1.0"
debug "^4.3.4"
http2-wrapper@^1.0.0-beta.5.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
@@ -5272,14 +5099,6 @@ http2-wrapper@^1.0.0-beta.5.2:
quick-lru "^5.1.1"
resolve-alpn "^1.0.0"
https-proxy-agent@^7.0.1:
version "7.0.6"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9"
integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==
dependencies:
agent-base "^7.1.2"
debug "4"
human-signals@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
@@ -5304,19 +5123,12 @@ iconv-lite@0.6.3, iconv-lite@^0.6.3:
dependencies:
safer-buffer ">= 2.1.2 < 3.0.0"
iconv-lite@^0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e"
integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==
dependencies:
safer-buffer ">= 2.1.2 < 3.0.0"
icss-utils@^5.0.0, icss-utils@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae"
integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
ieee754@^1.1.13, ieee754@^1.2.1:
ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
@@ -5378,7 +5190,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.4:
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -5657,11 +5469,6 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
isexe@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-4.0.0.tgz#48f6576af8e87a18feb796b7ed5e2e5903b43dca"
integrity sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==
isobject@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
@@ -6054,11 +5861,6 @@ lru-cache@^10.2.0:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878"
integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==
lru-cache@^11.0.0, lru-cache@^11.1.0, lru-cache@^11.2.1:
version "11.3.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.3.3.tgz#d6c633c2a9657760fd30594d8d98da65330d9d78"
integrity sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@@ -6085,24 +5887,6 @@ make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
make-fetch-happen@^15.0.0:
version "15.0.5"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-15.0.5.tgz#b0e3dd53d487b2733e4ea232c2bebf1bd16afb03"
integrity sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg==
dependencies:
"@gar/promise-retry" "^1.0.0"
"@npmcli/agent" "^4.0.0"
"@npmcli/redact" "^4.0.0"
cacache "^20.0.1"
http-cache-semantics "^4.1.1"
minipass "^7.0.2"
minipass-fetch "^5.0.0"
minipass-flush "^1.0.5"
minipass-pipeline "^1.2.4"
negotiator "^1.0.0"
proc-log "^6.0.0"
ssri "^13.0.0"
map-obj@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
@@ -6275,13 +6059,6 @@ minimatch@9.0.1:
dependencies:
brace-expansion "^2.0.1"
minimatch@^10.2.2:
version "10.2.5"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.5.tgz#bd48687a0be38ed2961399105600f832095861d1"
integrity sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==
dependencies:
brace-expansion "^5.0.5"
minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@@ -6317,79 +6094,16 @@ minimist@^1.2.0:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
minimist@^1.2.3:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
minipass-collect@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-2.0.1.tgz#1621bc77e12258a12c60d34e2276ec5c20680863"
integrity sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==
dependencies:
minipass "^7.0.3"
minipass-fetch@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-5.0.2.tgz#3973a605ddfd8abb865e50d6fc634853c8239729"
integrity sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==
dependencies:
minipass "^7.0.3"
minipass-sized "^2.0.0"
minizlib "^3.0.1"
optionalDependencies:
iconv-lite "^0.7.2"
minipass-flush@^1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.7.tgz#145c383d5ae294b36030aa80d4e872d08bebcb73"
integrity sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==
dependencies:
minipass "^3.0.0"
minipass-pipeline@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c"
integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==
dependencies:
minipass "^3.0.0"
minipass-sized@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-2.0.0.tgz#2228ee97e3f74f6b22ba6d1319addb7621534306"
integrity sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==
dependencies:
minipass "^7.1.2"
minipass@^3.0.0:
version "3.3.6"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a"
integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==
dependencies:
yallist "^4.0.0"
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4:
version "7.1.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.0.tgz#b545f84af94e567386770159302ca113469c80b8"
integrity sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==
minipass@^7.0.2, minipass@^7.0.3, minipass@^7.1.2, minipass@^7.1.3:
minipass@^7.1.2:
version "7.1.3"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.3.tgz#79389b4eb1bb2d003a9bba87d492f2bd37bdc65b"
integrity sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==
minizlib@^3.0.1, minizlib@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-3.1.0.tgz#6ad76c3a8f10227c9b51d1c9ac8e30b27f5a251c"
integrity sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==
dependencies:
minipass "^7.1.2"
mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
version "0.5.3"
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
mocha@11.7.5:
version "11.7.5"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-11.7.5.tgz#58f5bbfa5e0211ce7e5ee6128107cefc2515a627"
@@ -6473,11 +6187,6 @@ nanoid@^3.3.7:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
napi-build-utils@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e"
integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@@ -6488,11 +6197,6 @@ negotiator@0.6.3:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
negotiator@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a"
integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==
neo-async@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
@@ -6525,44 +6229,16 @@ nise@^5.1.1:
just-extend "^4.0.2"
path-to-regexp "^1.7.0"
node-abi@^3.3.0:
version "3.89.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.89.0.tgz#eea98bf89d4534743bbbf2defa9f4f9bd3bdccfd"
integrity sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==
dependencies:
semver "^7.3.5"
node-abort-controller@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.0.1.tgz#f91fa50b1dee3f909afabb7e261b1e1d6b0cb74e"
integrity sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==
node-addon-api@^8.0.0:
version "8.7.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.7.0.tgz#f64f8413456ecbe900221305a3f883c37666473f"
integrity sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==
node-forge@1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
node-gyp@12.x:
version "12.2.0"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-12.2.0.tgz#ff73f6f509e33d8b7e768f889ffc9738ad117b07"
integrity sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==
dependencies:
env-paths "^2.2.0"
exponential-backoff "^3.1.1"
graceful-fs "^4.2.6"
make-fetch-happen "^15.0.0"
nopt "^9.0.0"
proc-log "^6.0.0"
semver "^7.3.5"
tar "^7.5.4"
tinyglobby "^0.2.12"
which "^6.0.0"
node-preload@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301"
@@ -6587,13 +6263,6 @@ nopt@^7.2.0:
dependencies:
abbrev "^2.0.0"
nopt@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-9.0.0.tgz#6bff0836b2964d24508b6b41b5a9a49c4f4a1f96"
integrity sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==
dependencies:
abbrev "^4.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"
@@ -6814,11 +6483,6 @@ p-map@^3.0.0:
dependencies:
aggregate-error "^3.0.0"
p-map@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-7.0.4.tgz#b81814255f542e252d5729dca4d66e5ec14935b8"
integrity sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==
p-try@^2.0.0, p-try@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
@@ -6942,14 +6606,6 @@ path-scurry@^1.11.1:
lru-cache "^10.2.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-scurry@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.2.tgz#6be0d0ee02a10d9e0de7a98bae65e182c9061f85"
integrity sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==
dependencies:
lru-cache "^11.0.0"
minipass "^7.1.2"
path-to-regexp@0.1.10:
version "0.1.10"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b"
@@ -7582,24 +7238,6 @@ postcss@^8.4.40:
picocolors "^1.1.1"
source-map-js "^1.2.1"
prebuild-install@^7.1.3:
version "7.1.3"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec"
integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==
dependencies:
detect-libc "^2.0.0"
expand-template "^2.0.3"
github-from-package "0.0.0"
minimist "^1.2.3"
mkdirp-classic "^0.5.3"
napi-build-utils "^2.0.0"
node-abi "^3.3.0"
pump "^3.0.0"
rc "^1.2.7"
simple-get "^4.0.0"
tar-fs "^2.0.0"
tunnel-agent "^0.6.0"
precond@0.2:
version "0.2.3"
resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac"
@@ -7639,11 +7277,6 @@ primer-tooltips@2.0.0:
dependencies:
primer-support "5.0.0"
proc-log@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-6.1.0.tgz#18519482a37d5198e231133a70144a50f21f0215"
integrity sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==
process-on-spawn@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/process-on-spawn/-/process-on-spawn-1.0.0.tgz#95b05a23073d30a17acfdc92a440efd2baefdc93"
@@ -7728,7 +7361,7 @@ raw-body@2.5.2:
iconv-lite "0.4.24"
unpipe "1.0.0"
rc@1.2.8, rc@^1.2.7, rc@^1.2.8:
rc@1.2.8, rc@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
@@ -7788,7 +7421,7 @@ read@1.0.7:
dependencies:
mute-stream "~0.0.4"
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0:
readable-stream@^3.5.0:
version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
@@ -8013,7 +7646,7 @@ safe-array-concat@^1.1.2:
has-symbols "^1.0.3"
isarray "^2.0.5"
safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
safe-buffer@5.2.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@@ -8264,20 +7897,6 @@ signal-exit@^4.0.1:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
simple-concat@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
simple-get@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==
dependencies:
decompress-response "^6.0.0"
once "^1.3.1"
simple-concat "^1.0.0"
sinon@13.0.2:
version "13.0.2"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-13.0.2.tgz#c6a8ddd655dc1415bbdc5ebf0e5b287806850c3a"
@@ -8366,15 +7985,6 @@ socket.io@4.6.2:
socket.io-adapter "~2.5.2"
socket.io-parser "~4.2.4"
socks-proxy-agent@^8.0.3:
version "8.0.5"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz#b9cdb4e7e998509d7659d689ce7697ac21645bee"
integrity sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==
dependencies:
agent-base "^7.1.2"
debug "^4.3.4"
socks "^2.8.3"
socks@^2.8.3:
version "2.8.3"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5"
@@ -8474,25 +8084,6 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
sqlite3@6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-6.0.1.tgz#c0956e7834931c406b283c87b66771c847a6abfc"
integrity sha512-X0czUUMG2tmSqJpEQa3tCuZSHKIx8PwM53vLZzKp/o6Rpy25fiVfjdbnZ988M8+O3ZWR1ih0K255VumCb3MAnQ==
dependencies:
bindings "^1.5.0"
node-addon-api "^8.0.0"
prebuild-install "^7.1.3"
tar "^7.5.10"
optionalDependencies:
node-gyp "12.x"
ssri@^13.0.0:
version "13.0.1"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-13.0.1.tgz#2d8946614d33f4d0c84946bb370dce7a9379fd18"
integrity sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==
dependencies:
minipass "^7.0.3"
stable@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
@@ -8794,38 +8385,6 @@ tapable@^2.3.0:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.2.tgz#86755feabad08d82a26b891db044808c6ad00f15"
integrity sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==
tar-fs@^2.0.0:
version "2.1.4"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.4.tgz#800824dbf4ef06ded9afea4acafe71c67c76b930"
integrity sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==
dependencies:
chownr "^1.1.1"
mkdirp-classic "^0.5.2"
pump "^3.0.0"
tar-stream "^2.1.4"
tar-stream@^2.1.4:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
dependencies:
bl "^4.0.3"
end-of-stream "^1.4.1"
fs-constants "^1.0.0"
inherits "^2.0.3"
readable-stream "^3.1.1"
tar@^7.5.10, tar@^7.5.4:
version "7.5.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.13.tgz#0d214ed56781a26edc313581c0e2d929ceeb866d"
integrity sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==
dependencies:
"@isaacs/fs-minipass" "^4.0.0"
chownr "^3.0.0"
minipass "^7.1.2"
minizlib "^3.1.0"
yallist "^5.0.0"
terser-webpack-plugin@^5.1.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz#8033db876dd5875487213e87c627bca323e5ed90"
@@ -9011,13 +8570,6 @@ tsx@4.21.0:
optionalDependencies:
fsevents "~2.3.3"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
dependencies:
safe-buffer "^5.0.1"
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@@ -9540,13 +9092,6 @@ which@^2.0.1:
dependencies:
isexe "^2.0.0"
which@^6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/which/-/which-6.0.1.tgz#021642443a198fb93b784a5606721cb18cfcbfce"
integrity sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==
dependencies:
isexe "^4.0.0"
wildcard@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67"
@@ -9665,11 +9210,6 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yallist@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-5.0.0.tgz#00e2de443639ed0d78fd87de0d27469fbcffb533"
integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==
yaml@^1.10.0, yaml@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"