mirror of
https://github.com/thelounge/thelounge.git
synced 2026-04-17 04:18:47 -04:00
Merge remote-tracking branch 'origin/master' into max/04-10-web-push-neo
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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`);
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
14
server/plugins/messageStorage/types.d.ts
vendored
14
server/plugins/messageStorage/types.d.ts
vendored
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
478
yarn.lock
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user