feat: adding initial download sources

This commit is contained in:
Chubby Granny Chaser
2025-04-01 21:39:54 +01:00
parent 73f4b0e869
commit 0d75878b07
41 changed files with 306 additions and 520 deletions

BIN
binaries/7zr.exe Normal file

Binary file not shown.

BIN
binaries/7zz Normal file

Binary file not shown.

BIN
binaries/7zzs Normal file

Binary file not shown.

View File

@@ -20,6 +20,8 @@ asarUnpack:
- resources/** - resources/**
win: win:
executableName: Hydra executableName: Hydra
extraResources:
- from: binaries/7zr.exe
target: target:
- nsis - nsis
- portable - portable
@@ -35,6 +37,8 @@ portable:
artifactName: ${name}-${version}-portable.${ext} artifactName: ${name}-${version}-portable.${ext}
mac: mac:
entitlementsInherit: build/entitlements.mac.plist entitlementsInherit: build/entitlements.mac.plist
extraResources:
- from: binaries/7zz
extendInfo: extendInfo:
- NSCameraUsageDescription: Application requests access to the device's camera. - NSCameraUsageDescription: Application requests access to the device's camera.
- NSMicrophoneUsageDescription: Application requests access to the device's microphone. - NSMicrophoneUsageDescription: Application requests access to the device's microphone.
@@ -44,6 +48,8 @@ mac:
dmg: dmg:
artifactName: ${name}-${version}.${ext} artifactName: ${name}-${version}.${ext}
linux: linux:
extraResources:
- from: binaries/7zzs
target: target:
- AppImage - AppImage
- snap - snap

View File

@@ -16,9 +16,6 @@ export default defineConfig(({ mode }) => {
main: { main: {
build: { build: {
sourcemap: true, sourcemap: true,
rollupOptions: {
external: ["better-sqlite3"],
},
}, },
resolve: { resolve: {
alias: { alias: {

View File

@@ -28,8 +28,7 @@
"build:win": "electron-vite build && electron-builder --win", "build:win": "electron-vite build && electron-builder --win",
"build:mac": "electron-vite build && electron-builder --mac", "build:mac": "electron-vite build && electron-builder --mac",
"build:linux": "electron-vite build && electron-builder --linux", "build:linux": "electron-vite build && electron-builder --linux",
"prepare": "husky", "prepare": "husky"
"knex:migrate:make": "knex --knexfile src/main/knexfile.ts migrate:make --esm"
}, },
"dependencies": { "dependencies": {
"@electron-toolkit/preload": "^3.0.0", "@electron-toolkit/preload": "^3.0.0",
@@ -45,7 +44,6 @@
"auto-launch": "^5.0.6", "auto-launch": "^5.0.6",
"axios": "^1.7.9", "axios": "^1.7.9",
"axios-cookiejar-support": "^5.0.5", "axios-cookiejar-support": "^5.0.5",
"better-sqlite3": "^11.7.0",
"classic-level": "^2.0.0", "classic-level": "^2.0.0",
"classnames": "^2.5.1", "classnames": "^2.5.1",
"color": "^4.2.3", "color": "^4.2.3",
@@ -62,7 +60,6 @@
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"kill-port": "^2.0.1", "kill-port": "^2.0.1",
"knex": "^3.1.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"parse-torrent": "^11.0.17", "parse-torrent": "^11.0.17",
"piscina": "^4.7.0", "piscina": "^4.7.0",

View File

@@ -230,7 +230,8 @@
"seeding": "Seeding", "seeding": "Seeding",
"stop_seeding": "Stop seeding", "stop_seeding": "Stop seeding",
"resume_seeding": "Resume seeding", "resume_seeding": "Resume seeding",
"options": "Manage" "options": "Manage",
"extracting": "Extracting files…"
}, },
"settings": { "settings": {
"downloads_path": "Downloads path", "downloads_path": "Downloads path",
@@ -344,7 +345,8 @@
"error_importing_theme": "Error importing theme", "error_importing_theme": "Error importing theme",
"theme_imported": "Theme imported successfully", "theme_imported": "Theme imported successfully",
"enable_friend_request_notifications": "When a friend request is received", "enable_friend_request_notifications": "When a friend request is received",
"enable_auto_install": "Download updates automatically" "enable_auto_install": "Download updates automatically",
"automatically_extract_downloaded_files": "Automatically extract downloaded files"
}, },
"notifications": { "notifications": {
"download_complete": "Download complete", "download_complete": "Download complete",
@@ -357,7 +359,9 @@
"notification_achievement_unlocked_title": "Achievement unlocked for {{game}}", "notification_achievement_unlocked_title": "Achievement unlocked for {{game}}",
"notification_achievement_unlocked_body": "{{achievement}} and other {{count}} were unlocked", "notification_achievement_unlocked_body": "{{achievement}} and other {{count}} were unlocked",
"new_friend_request_description": "You have received a new friend request", "new_friend_request_description": "You have received a new friend request",
"new_friend_request_title": "New friend request" "new_friend_request_title": "New friend request",
"extraction_complete": "Extraction complete",
"game_extracted": "{{title}} extracted successfully"
}, },
"system_tray": { "system_tray": {
"open": "Open Hydra", "open": "Open Hydra",

View File

@@ -182,7 +182,8 @@
"download_error_not_cached_in_real_debrid": "Este download não está disponível no Real-Debrid e a verificação do status do download não está disponível.", "download_error_not_cached_in_real_debrid": "Este download não está disponível no Real-Debrid e a verificação do status do download não está disponível.",
"download_error_not_cached_in_torbox": "Este download não está disponível no Torbox e a verificação do status do download não está disponível.", "download_error_not_cached_in_torbox": "Este download não está disponível no Torbox e a verificação do status do download não está disponível.",
"game_removed_from_favorites": "Jogo removido dos favoritos", "game_removed_from_favorites": "Jogo removido dos favoritos",
"game_added_to_favorites": "Jogo adicionado aos favoritos" "game_added_to_favorites": "Jogo adicionado aos favoritos",
"automatically_extract_downloaded_files": "Extrair automaticamente os arquivos baixados"
}, },
"activation": { "activation": {
"title": "Ativação", "title": "Ativação",
@@ -219,7 +220,8 @@
"seeding": "Semeando", "seeding": "Semeando",
"stop_seeding": "Parar de semear", "stop_seeding": "Parar de semear",
"resume_seeding": "Semear", "resume_seeding": "Semear",
"options": "Gerenciar" "options": "Gerenciar",
"extracting": "Extraindo arquivos…"
}, },
"settings": { "settings": {
"downloads_path": "Diretório dos downloads", "downloads_path": "Diretório dos downloads",
@@ -342,7 +344,9 @@
"new_update_available": "Versão {{version}} disponível", "new_update_available": "Versão {{version}} disponível",
"restart_to_install_update": "Reinicie o Hydra para instalar a nova versão", "restart_to_install_update": "Reinicie o Hydra para instalar a nova versão",
"new_friend_request_title": "Novo pedido de amizade", "new_friend_request_title": "Novo pedido de amizade",
"new_friend_request_description": "Você recebeu um novo pedido de amizade" "new_friend_request_description": "Você recebeu um novo pedido de amizade",
"extraction_complete": "Extração concluída",
"game_extracted": "{{title}} extraído com sucesso"
}, },
"system_tray": { "system_tray": {
"open": "Abrir Hydra", "open": "Abrir Hydra",

View File

@@ -1,8 +1,8 @@
import { CloudSync } from "@main/services"; import { CloudSync } from "@main/services";
import { registerEvent } from "../register-event"; import { registerEvent } from "../register-event";
import type { GameShop } from "@types"; import type { GameShop } from "@types";
import { t } from "i18next"; import i18next, { t } from "i18next";
import { format } from "date-fns"; import { formatDate } from "date-fns";
const uploadSaveGame = async ( const uploadSaveGame = async (
_event: Electron.IpcMainInvokeEvent, _event: Electron.IpcMainInvokeEvent,
@@ -10,13 +10,15 @@ const uploadSaveGame = async (
shop: GameShop, shop: GameShop,
downloadOptionTitle: string | null downloadOptionTitle: string | null
) => { ) => {
const { language } = i18next;
return CloudSync.uploadSaveGame( return CloudSync.uploadSaveGame(
objectId, objectId,
shop, shop,
downloadOptionTitle, downloadOptionTitle,
t("backup_from", { t("backup_from", {
ns: "game_details", ns: "game_details",
date: format(new Date(), "dd/MM/yyyy"), date: formatDate(new Date(), language),
}) })
); );
}; };

View File

@@ -1,13 +1,13 @@
import { HydraApi } from "@main/services"; import { HydraApi } from "@main/services";
import { registerEvent } from "../register-event"; import { registerEvent } from "../register-event";
const createDownloadSource = async ( const createDownloadSources = async (
_event: Electron.IpcMainInvokeEvent, _event: Electron.IpcMainInvokeEvent,
url: string urls: string[]
) => { ) => {
await HydraApi.post("/profile/download-sources", { await HydraApi.post("/profile/download-sources", {
url, urls,
}); });
}; };
registerEvent("createDownloadSource", createDownloadSource); registerEvent("createDownloadSources", createDownloadSources);

View File

@@ -90,7 +90,7 @@ import "./themes/get-custom-theme-by-id";
import "./themes/get-active-custom-theme"; import "./themes/get-active-custom-theme";
import "./themes/close-editor-window"; import "./themes/close-editor-window";
import "./themes/toggle-custom-theme"; import "./themes/toggle-custom-theme";
import "./download-sources/create-download-source"; import "./download-sources/create-download-sources";
import "./download-sources/remove-download-source"; import "./download-sources/remove-download-source";
import "./download-sources/get-download-sources"; import "./download-sources/get-download-sources";
import { isPortableVersion } from "@main/helpers"; import { isPortableVersion } from "@main/helpers";

View File

@@ -12,7 +12,15 @@ const startGameDownload = async (
_event: Electron.IpcMainInvokeEvent, _event: Electron.IpcMainInvokeEvent,
payload: StartGameDownloadPayload payload: StartGameDownloadPayload
) => { ) => {
const { objectId, title, shop, downloadPath, downloader, uri } = payload; const {
objectId,
title,
shop,
downloadPath,
downloader,
uri,
automaticallyExtract,
} = payload;
const gameKey = levelKeys.game(shop, objectId); const gameKey = levelKeys.game(shop, objectId);
@@ -74,6 +82,8 @@ const startGameDownload = async (
shouldSeed: false, shouldSeed: false,
timestamp: Date.now(), timestamp: Date.now(),
queued: true, queued: true,
extracting: false,
automaticallyExtract,
}; };
try { try {

View File

@@ -23,10 +23,6 @@ const updateUserPreferences = async (
patchUserProfile({ language: preferences.language }).catch(() => {}); patchUserProfile({ language: preferences.language }).catch(() => {});
} }
if (!preferences.downloadsPath) {
preferences.downloadsPath = null;
}
await db.put<string, UserPreferences>( await db.put<string, UserPreferences>(
levelKeys.userPreferences, levelKeys.userPreferences,
{ {

View File

@@ -1,11 +0,0 @@
import knex from "knex";
import { databasePath } from "./constants";
import { app } from "electron";
export const knexClient = knex({
debug: !app.isPackaged,
client: "better-sqlite3",
connection: {
filename: databasePath,
},
});

View File

@@ -1,10 +0,0 @@
const config = {
development: {
migrations: {
extension: "ts",
stub: "migrations/migration.stub",
},
},
};
export default config;

View File

@@ -13,6 +13,5 @@ export const levelKeys = {
downloads: "downloads", downloads: "downloads",
userPreferences: "userPreferences", userPreferences: "userPreferences",
language: "language", language: "language",
sqliteMigrationDone: "sqliteMigrationDone",
screenState: "screenState", screenState: "screenState",
}; };

View File

@@ -1,4 +1,4 @@
import { DownloadManager, logger, Ludusavi, startMainLoop } from "./services"; import { DownloadManager, Ludusavi, startMainLoop } from "./services";
import { RealDebridClient } from "./services/download/real-debrid"; import { RealDebridClient } from "./services/download/real-debrid";
import { HydraApi } from "./services/hydra-api"; import { HydraApi } from "./services/hydra-api";
import { uploadGamesBatch } from "./services/library-sync"; import { uploadGamesBatch } from "./services/library-sync";
@@ -6,26 +6,17 @@ import { Aria2 } from "./services/aria2";
import { downloadsSublevel } from "./level/sublevels/downloads"; import { downloadsSublevel } from "./level/sublevels/downloads";
import { sortBy } from "lodash-es"; import { sortBy } from "lodash-es";
import { Downloader } from "@shared"; import { Downloader } from "@shared";
import { import { levelKeys, db } from "./level";
gameAchievementsSublevel, import type { UserPreferences } from "@types";
gamesSublevel,
levelKeys,
db,
} from "./level";
import { Auth, User, type UserPreferences } from "@types";
import { knexClient } from "./knex-client";
import { TorBoxClient } from "./services/download/torbox"; import { TorBoxClient } from "./services/download/torbox";
export const loadState = async () => { export const loadState = async () => {
const userPreferences = await migrateFromSqlite().then(async () => { const userPreferences = await db.get<string, UserPreferences | null>(
await db.put<string, boolean>(levelKeys.sqliteMigrationDone, true, { levelKeys.userPreferences,
{
valueEncoding: "json", valueEncoding: "json",
}); }
);
return db.get<string, UserPreferences | null>(levelKeys.userPreferences, {
valueEncoding: "json",
});
});
await import("./events"); await import("./events");
@@ -52,6 +43,15 @@ export const loadState = async () => {
return sortBy(games, "timestamp", "DESC"); return sortBy(games, "timestamp", "DESC");
}); });
downloads.forEach((download) => {
if (download.extracting) {
downloadsSublevel.put(levelKeys.game(download.shop, download.objectId), {
...download,
extracting: false,
});
}
});
const [nextItemOnQueue] = downloads.filter((game) => game.queued); const [nextItemOnQueue] = downloads.filter((game) => game.queued);
const downloadsToSeed = downloads.filter( const downloadsToSeed = downloads.filter(
@@ -66,137 +66,3 @@ export const loadState = async () => {
startMainLoop(); startMainLoop();
}; };
const migrateFromSqlite = async () => {
const sqliteMigrationDone = await db.get(levelKeys.sqliteMigrationDone);
if (sqliteMigrationDone) {
return;
}
const migrateGames = knexClient("game")
.select("*")
.then((games) => {
return gamesSublevel.batch(
games.map((game) => ({
type: "put",
key: levelKeys.game(game.shop, game.objectID),
value: {
objectId: game.objectID,
shop: game.shop,
title: game.title,
iconUrl: game.iconUrl,
playTimeInMilliseconds: game.playTimeInMilliseconds,
lastTimePlayed: game.lastTimePlayed,
remoteId: game.remoteId,
winePrefixPath: game.winePrefixPath,
launchOptions: game.launchOptions,
executablePath: game.executablePath,
isDeleted: game.isDeleted === 1,
},
}))
);
})
.then(() => {
logger.info("Games migrated successfully");
});
const migrateUserPreferences = knexClient("user_preferences")
.select("*")
.then(async (userPreferences) => {
if (userPreferences.length > 0) {
const { realDebridApiToken, ...rest } = userPreferences[0];
await db.put<string, UserPreferences>(
levelKeys.userPreferences,
{
...rest,
realDebridApiToken,
preferQuitInsteadOfHiding: rest.preferQuitInsteadOfHiding === 1,
runAtStartup: rest.runAtStartup === 1,
startMinimized: rest.startMinimized === 1,
disableNsfwAlert: rest.disableNsfwAlert === 1,
seedAfterDownloadComplete: rest.seedAfterDownloadComplete === 1,
showHiddenAchievementsDescription:
rest.showHiddenAchievementsDescription === 1,
downloadNotificationsEnabled:
rest.downloadNotificationsEnabled === 1,
repackUpdatesNotificationsEnabled:
rest.repackUpdatesNotificationsEnabled === 1,
achievementNotificationsEnabled:
rest.achievementNotificationsEnabled === 1,
},
{ valueEncoding: "json" }
);
if (rest.language) {
await db.put<string, string>(levelKeys.language, rest.language, {
valueEncoding: "utf-8",
});
}
}
})
.then(() => {
logger.info("User preferences migrated successfully");
});
const migrateAchievements = knexClient("game_achievement")
.select("*")
.then((achievements) => {
return gameAchievementsSublevel.batch(
achievements.map((achievement) => ({
type: "put",
key: levelKeys.game(achievement.shop, achievement.objectId),
value: {
achievements: JSON.parse(achievement.achievements),
unlockedAchievements: JSON.parse(achievement.unlockedAchievements),
},
}))
);
})
.then(() => {
logger.info("Achievements migrated successfully");
});
const migrateUser = knexClient("user_auth")
.select("*")
.then(async (users) => {
if (users.length > 0) {
await db.put<string, User>(
levelKeys.user,
{
id: users[0].userId,
displayName: users[0].displayName,
profileImageUrl: users[0].profileImageUrl,
backgroundImageUrl: users[0].backgroundImageUrl,
subscription: users[0].subscription,
},
{
valueEncoding: "json",
}
);
await db.put<string, Auth>(
levelKeys.auth,
{
accessToken: users[0].accessToken,
refreshToken: users[0].refreshToken,
tokenExpirationTimestamp: users[0].tokenExpirationTimestamp,
},
{
valueEncoding: "json",
}
);
}
})
.then(() => {
logger.info("User data migrated successfully");
});
return Promise.allSettled([
migrateGames,
migrateUserPreferences,
migrateAchievements,
migrateUser,
]);
};

38
src/main/services/7zip.ts Normal file
View File

@@ -0,0 +1,38 @@
import { app } from "electron";
import cp from "node:child_process";
import path from "node:path";
export const binaryName = {
linux: "7zzs",
darwin: "7zz",
win32: "7zr.exe",
};
export class _7Zip {
private static readonly binaryPath = app.isPackaged
? path.join(process.resourcesPath, binaryName[process.platform])
: path.join(
__dirname,
"..",
"..",
"binaries",
binaryName[process.platform]
);
public static extractFile(
filePath: string,
outputPath: string,
cb: () => void
) {
const child = cp.spawn(this.binaryPath, [
"x",
filePath,
"-o" + outputPath,
"-y",
]);
child.on("exit", () => {
cb();
});
}
}

View File

@@ -2,18 +2,15 @@ import path from "node:path";
import cp from "node:child_process"; import cp from "node:child_process";
import { app } from "electron"; import { app } from "electron";
export const startAria2 = () => {};
export class Aria2 { export class Aria2 {
private static process: cp.ChildProcess | null = null; private static process: cp.ChildProcess | null = null;
private static readonly binaryPath = app.isPackaged
? path.join(process.resourcesPath, "aria2", "aria2c")
: path.join(__dirname, "..", "..", "aria2", "aria2c");
public static spawn() { public static spawn() {
const binaryPath = app.isPackaged
? path.join(process.resourcesPath, "aria2", "aria2c")
: path.join(__dirname, "..", "..", "aria2", "aria2c");
this.process = cp.spawn( this.process = cp.spawn(
binaryPath, this.binaryPath,
[ [
"--enable-rpc", "--enable-rpc",
"--rpc-listen-all", "--rpc-listen-all",

View File

@@ -1,6 +1,9 @@
import { Downloader, DownloadError } from "@shared"; import { Downloader, DownloadError } from "@shared";
import { WindowManager } from "../window-manager"; import { WindowManager } from "../window-manager";
import { publishDownloadCompleteNotification } from "../notifications"; import {
publishDownloadCompleteNotification,
publishExtractionCompleteNotification,
} from "../notifications";
import type { Download, DownloadProgress, UserPreferences } from "@types"; import type { Download, DownloadProgress, UserPreferences } from "@types";
import { import {
GofileApi, GofileApi,
@@ -22,9 +25,11 @@ import { logger } from "../logger";
import { db, downloadsSublevel, gamesSublevel, levelKeys } from "@main/level"; import { db, downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
import { sortBy } from "lodash-es"; import { sortBy } from "lodash-es";
import { TorBoxClient } from "./torbox"; import { TorBoxClient } from "./torbox";
import { _7Zip } from "../7zip";
export class DownloadManager { export class DownloadManager {
private static downloadingGameId: string | null = null; private static downloadingGameId: string | null = null;
private static readonly extensionsToExtract = [".rar", ".zip", ".7z"];
public static async startRPC( public static async startRPC(
download?: Download, download?: Download,
@@ -150,13 +155,47 @@ export class DownloadManager {
queued: false, queued: false,
}); });
} else { } else {
const shouldExtract =
download.downloader !== Downloader.Torrent &&
this.extensionsToExtract.some((ext) =>
download.folderName?.endsWith(ext)
) &&
download.automaticallyExtract;
downloadsSublevel.put(gameId, { downloadsSublevel.put(gameId, {
...download, ...download,
status: "complete", status: "complete",
shouldSeed: false, shouldSeed: false,
queued: false, queued: false,
extracting: shouldExtract,
}); });
if (shouldExtract) {
_7Zip.extractFile(
path.join(download.downloadPath, download.folderName!),
path.join(
download.downloadPath,
path.parse(download.folderName!).name
),
async () => {
const download = await downloadsSublevel.get(gameId);
downloadsSublevel.put(gameId, {
...download!,
extracting: false,
});
WindowManager.mainWindow?.webContents.send(
"on-extraction-complete",
game.shop,
game.objectId
);
publishExtractionCompleteNotification(game);
}
);
}
this.cancelDownload(gameId); this.cancelDownload(gameId);
} }

View File

@@ -8,3 +8,4 @@ export * from "./main-loop";
export * from "./hydra-api"; export * from "./hydra-api";
export * from "./ludusavi"; export * from "./ludusavi";
export * from "./cloud-sync"; export * from "./cloud-sync";
export * from "./7zip";

View File

@@ -128,6 +128,17 @@ export const publishCombinedNewAchievementNotification = async (
} }
}; };
export const publishExtractionCompleteNotification = async (game: Game) => {
new Notification({
title: t("extraction_complete", { ns: "notifications" }),
body: t("game_extracted", {
ns: "notifications",
title: game.title,
}),
icon: trayIcon,
}).show();
};
export const publishNewAchievementNotification = async (info: { export const publishNewAchievementNotification = async (info: {
achievements: { displayName: string; iconUrl: string }[]; achievements: { displayName: string; iconUrl: string }[];
unlockedAchievementCount: number; unlockedAchievementCount: number;

View File

@@ -6,9 +6,9 @@ import axios from "axios";
import { exec } from "child_process"; import { exec } from "child_process";
import { ProcessPayload } from "./download/types"; import { ProcessPayload } from "./download/types";
import { gamesSublevel, levelKeys } from "@main/level"; import { gamesSublevel, levelKeys } from "@main/level";
import { t } from "i18next"; import i18next, { t } from "i18next";
import { CloudSync } from "./cloud-sync"; import { CloudSync } from "./cloud-sync";
import { format } from "date-fns"; import { formatDate } from "date-fns";
const commands = { const commands = {
findWineDir: `lsof -c wine 2>/dev/null | grep '/drive_c/windows$' | head -n 1 | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}'`, findWineDir: `lsof -c wine 2>/dev/null | grep '/drive_c/windows$' | head -n 1 | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}'`,
@@ -229,6 +229,8 @@ function onOpenGame(game: Game) {
if (game.remoteId) { if (game.remoteId) {
updateGamePlaytime(game, 0, new Date()).catch(() => {}); updateGamePlaytime(game, 0, new Date()).catch(() => {});
const { language } = i18next;
if (game.automaticCloudSync) { if (game.automaticCloudSync) {
CloudSync.uploadSaveGame( CloudSync.uploadSaveGame(
game.objectId, game.objectId,
@@ -236,7 +238,7 @@ function onOpenGame(game: Game) {
null, null,
t("automatic_backup_from", { t("automatic_backup_from", {
ns: "game_details", ns: "game_details",
date: format(new Date(), "dd/MM/yyyy"), date: formatDate(new Date(), language),
}) })
); );
} }
@@ -296,6 +298,8 @@ const onCloseGame = (game: Game) => {
)!; )!;
gamesPlaytime.delete(levelKeys.game(game.shop, game.objectId)); gamesPlaytime.delete(levelKeys.game(game.shop, game.objectId));
const { language } = i18next;
if (game.remoteId) { if (game.remoteId) {
updateGamePlaytime( updateGamePlaytime(
game, game,
@@ -310,7 +314,7 @@ const onCloseGame = (game: Game) => {
null, null,
t("automatic_backup_from", { t("automatic_backup_from", {
ns: "game_details", ns: "game_details",
date: format(new Date(), "dd/MM/yyyy"), date: formatDate(new Date(), language),
}) })
); );
} }

View File

@@ -100,8 +100,8 @@ contextBridge.exposeInMainWorld("electron", {
/* Download sources */ /* Download sources */
putDownloadSource: (objectIds: string[]) => putDownloadSource: (objectIds: string[]) =>
ipcRenderer.invoke("putDownloadSource", objectIds), ipcRenderer.invoke("putDownloadSource", objectIds),
createDownloadSource: (url: string) => createDownloadSources: (urls: string[]) =>
ipcRenderer.invoke("createDownloadSource", url), ipcRenderer.invoke("createDownloadSources", urls),
removeDownloadSource: (url: string, removeAll?: boolean) => removeDownloadSource: (url: string, removeAll?: boolean) =>
ipcRenderer.invoke("removeDownloadSource", url, removeAll), ipcRenderer.invoke("removeDownloadSource", url, removeAll),
getDownloadSources: () => ipcRenderer.invoke("getDownloadSources"), getDownloadSources: () => ipcRenderer.invoke("getDownloadSources"),
@@ -200,6 +200,15 @@ contextBridge.exposeInMainWorld("electron", {
return () => return () =>
ipcRenderer.removeListener("on-achievement-unlocked", listener); ipcRenderer.removeListener("on-achievement-unlocked", listener);
}, },
onExtractionComplete: (cb: (shop: GameShop, objectId: string) => void) => {
const listener = (
_event: Electron.IpcRendererEvent,
shop: GameShop,
objectId: string
) => cb(shop, objectId);
ipcRenderer.on("on-extraction-complete", listener);
return () => ipcRenderer.removeListener("on-extraction-complete", listener);
},
/* Hardware */ /* Hardware */
getDiskFreeSpace: (path: string) => getDiskFreeSpace: (path: string) =>

View File

@@ -143,6 +143,10 @@ export function App() {
const existingDownloadSources: DownloadSource[] = const existingDownloadSources: DownloadSource[] =
await downloadSourcesTable.toArray(); await downloadSourcesTable.toArray();
window.electron.createDownloadSources(
existingDownloadSources.map((source) => source.url)
);
await Promise.allSettled( await Promise.allSettled(
downloadSources.map(async (source) => { downloadSources.map(async (source) => {
return new Promise((resolve) => { return new Promise((resolve) => {

View File

@@ -160,12 +160,15 @@ declare global {
authenticateRealDebrid: (apiToken: string) => Promise<RealDebridUser>; authenticateRealDebrid: (apiToken: string) => Promise<RealDebridUser>;
authenticateTorBox: (apiToken: string) => Promise<TorBoxUser>; authenticateTorBox: (apiToken: string) => Promise<TorBoxUser>;
onAchievementUnlocked: (cb: () => void) => () => Electron.IpcRenderer; onAchievementUnlocked: (cb: () => void) => () => Electron.IpcRenderer;
onExtractionComplete: (
cb: (shop: GameShop, objectId: string) => void
) => () => Electron.IpcRenderer;
/* Download sources */ /* Download sources */
putDownloadSource: ( putDownloadSource: (
objectIds: string[] objectIds: string[]
) => Promise<{ fingerprint: string }>; ) => Promise<{ fingerprint: string }>;
createDownloadSource: (url: string) => Promise<void>; createDownloadSources: (urls: string[]) => Promise<void>;
removeDownloadSource: (url: string, removeAll?: boolean) => Promise<void>; removeDownloadSource: (url: string, removeAll?: boolean) => Promise<void>;
getDownloadSources: () => Promise< getDownloadSources: () => Promise<
Pick<DownloadSource, "url" | "createdAt" | "updatedAt">[] Pick<DownloadSource, "url" | "createdAt" | "updatedAt">[]

View File

@@ -1,19 +1,7 @@
import { formatDate, getDateLocale } from "@shared";
import { format, formatDistance, subMilliseconds } from "date-fns"; import { format, formatDistance, subMilliseconds } from "date-fns";
import type { FormatDistanceOptions } from "date-fns"; import type { FormatDistanceOptions } from "date-fns";
import { import { enUS } from "date-fns/locale";
ptBR,
enUS,
es,
fr,
pl,
hu,
tr,
ru,
it,
be,
zhCN,
da,
} from "date-fns/locale";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
export function useDate() { export function useDate() {
@@ -21,22 +9,6 @@ export function useDate() {
const { language } = i18n; const { language } = i18n;
const getDateLocale = () => {
if (language.startsWith("pt")) return ptBR;
if (language.startsWith("es")) return es;
if (language.startsWith("fr")) return fr;
if (language.startsWith("hu")) return hu;
if (language.startsWith("pl")) return pl;
if (language.startsWith("tr")) return tr;
if (language.startsWith("ru")) return ru;
if (language.startsWith("it")) return it;
if (language.startsWith("be")) return be;
if (language.startsWith("zh")) return zhCN;
if (language.startsWith("da")) return da;
return enUS;
};
return { return {
formatDistance: ( formatDistance: (
date: string | number | Date, date: string | number | Date,
@@ -46,7 +18,7 @@ export function useDate() {
try { try {
return formatDistance(date, baseDate, { return formatDistance(date, baseDate, {
...options, ...options,
locale: getDateLocale(), locale: getDateLocale(language),
}); });
} catch (err) { } catch (err) {
return ""; return "";
@@ -61,7 +33,7 @@ export function useDate() {
try { try {
return formatDistance(subMilliseconds(new Date(), millis), baseDate, { return formatDistance(subMilliseconds(new Date(), millis), baseDate, {
...options, ...options,
locale: getDateLocale(), locale: getDateLocale(language),
}); });
} catch (err) { } catch (err) {
return ""; return "";
@@ -69,18 +41,13 @@ export function useDate() {
}, },
formatDateTime: (date: number | Date | string): string => { formatDateTime: (date: number | Date | string): string => {
const locale = getDateLocale(); const locale = getDateLocale(language);
return format( return format(
date, date,
locale == enUS ? "MM/dd/yyyy - HH:mm" : "dd/MM/yyyy HH:mm" locale == enUS ? "MM/dd/yyyy - HH:mm" : "dd/MM/yyyy HH:mm"
); );
}, },
formatDate: (date: number | Date | string): string => { formatDate: (date: number | Date | string) => formatDate(date, language),
if (isNaN(new Date(date).getDate())) return "N/A";
const locale = getDateLocale();
return format(date, locale == enUS ? "MM/dd/yyyy" : "dd/MM/yyyy");
},
}; };
} }

View File

@@ -18,14 +18,11 @@ export function Pagination({
if (totalPages <= 1) return null; if (totalPages <= 1) return null;
// Number of visible pages
const visiblePages = 3; const visiblePages = 3;
// Calculate the start and end of the visible range let startPage = Math.max(1, page - 1);
let startPage = Math.max(1, page - 1); // Shift range slightly back
let endPage = startPage + visiblePages - 1; let endPage = startPage + visiblePages - 1;
// Adjust the range if we're near the start or end
if (endPage > totalPages) { if (endPage > totalPages) {
endPage = totalPages; endPage = totalPages;
startPage = Math.max(1, endPage - visiblePages + 1); startPage = Math.max(1, endPage - visiblePages + 1);
@@ -33,7 +30,6 @@ export function Pagination({
return ( return (
<div className="pagination"> <div className="pagination">
{/* Previous Button */}
<Button <Button
theme="outline" theme="outline"
onClick={() => onPageChange(page - 1)} onClick={() => onPageChange(page - 1)}
@@ -45,7 +41,6 @@ export function Pagination({
{page > 2 && ( {page > 2 && (
<> <>
{/* initial page */}
<Button <Button
theme="outline" theme="outline"
onClick={() => onPageChange(1)} onClick={() => onPageChange(1)}
@@ -55,14 +50,12 @@ export function Pagination({
{1} {1}
</Button> </Button>
{/* ellipsis */}
<div className="pagination__ellipsis"> <div className="pagination__ellipsis">
<span className="pagination__ellipsis-text">...</span> <span className="pagination__ellipsis-text">...</span>
</div> </div>
</> </>
)} )}
{/* Page Buttons */}
{Array.from( {Array.from(
{ length: endPage - startPage + 1 }, { length: endPage - startPage + 1 },
(_, i) => startPage + i (_, i) => startPage + i
@@ -79,12 +72,10 @@ export function Pagination({
{page < totalPages - 1 && ( {page < totalPages - 1 && (
<> <>
{/* ellipsis */}
<div className="pagination__ellipsis"> <div className="pagination__ellipsis">
<span className="pagination__ellipsis-text">...</span> <span className="pagination__ellipsis-text">...</span>
</div> </div>
{/* last page */}
<Button <Button
theme="outline" theme="outline"
onClick={() => onPageChange(totalPages)} onClick={() => onPageChange(totalPages)}
@@ -96,7 +87,6 @@ export function Pagination({
</> </>
)} )}
{/* Next Button */}
<Button <Button
theme="outline" theme="outline"
onClick={() => onPageChange(page + 1)} onClick={() => onPageChange(page + 1)}

View File

@@ -96,6 +96,10 @@ export function DownloadGroup({
const finalDownloadSize = getFinalDownloadSize(game); const finalDownloadSize = getFinalDownloadSize(game);
const seedingStatus = seedingMap.get(game.id); const seedingStatus = seedingMap.get(game.id);
if (download.extracting) {
return <p>{t("extracting")}</p>;
}
if (isGameDeleting(game.id)) { if (isGameDeleting(game.id)) {
return <p>{t("deleting")}</p>; return <p>{t("deleting")}</p>;
} }

View File

@@ -38,7 +38,13 @@ export default function Downloads() {
useEffect(() => { useEffect(() => {
window.electron.onSeedingStatus((value) => setSeedingStatus(value)); window.electron.onSeedingStatus((value) => setSeedingStatus(value));
}, []);
const unsubscribe = window.electron.onExtractionComplete(() => {
updateLibrary();
});
return () => unsubscribe();
}, [updateLibrary]);
const handleOpenGameInstaller = (shop: GameShop, objectId: string) => const handleOpenGameInstaller = (shop: GameShop, objectId: string) =>
window.electron.openGameInstaller(shop, objectId).then((isBinaryInPath) => { window.electron.openGameInstaller(shop, objectId).then((isBinaryInPath) => {
@@ -67,7 +73,7 @@ export default function Downloads() {
if (!next.download) return prev; if (!next.download) return prev;
/* Is downloading */ /* Is downloading */
if (lastPacket?.gameId === next.id) if (lastPacket?.gameId === next.id || next.download.extracting)
return { ...prev, downloading: [...prev.downloading, next] }; return { ...prev, downloading: [...prev.downloading, next] };
/* Is either queued or paused */ /* Is either queued or paused */

View File

@@ -4,7 +4,6 @@ import { cloudSyncContext, gameDetailsContext } from "@renderer/context";
import "./cloud-sync-modal.scss"; import "./cloud-sync-modal.scss";
import { formatBytes } from "@shared"; import { formatBytes } from "@shared";
import { format } from "date-fns";
import { import {
ClockIcon, ClockIcon,
DeviceDesktopIcon, DeviceDesktopIcon,
@@ -14,7 +13,7 @@ import {
TrashIcon, TrashIcon,
UploadIcon, UploadIcon,
} from "@primer/octicons-react"; } from "@primer/octicons-react";
import { useAppSelector, useToast } from "@renderer/hooks"; import { useAppSelector, useDate, useToast } from "@renderer/hooks";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { AxiosProgressEvent } from "axios"; import { AxiosProgressEvent } from "axios";
import { formatDownloadProgress } from "@renderer/helpers"; import { formatDownloadProgress } from "@renderer/helpers";
@@ -29,6 +28,8 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
const { t } = useTranslation("game_details"); const { t } = useTranslation("game_details");
const { formatDate, formatDateTime } = useDate();
const { const {
artifacts, artifacts,
backupPreview, backupPreview,
@@ -205,7 +206,7 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
<h3> <h3>
{artifact.label ?? {artifact.label ??
t("backup_from", { t("backup_from", {
date: format(artifact.createdAt, "dd/MM/yyyy"), date: formatDate(artifact.createdAt),
})} })}
</h3> </h3>
<small>{formatBytes(artifact.artifactLengthInBytes)}</small> <small>{formatBytes(artifact.artifactLengthInBytes)}</small>
@@ -223,7 +224,7 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
<span className="cloud-sync-modal__artifact-meta"> <span className="cloud-sync-modal__artifact-meta">
<ClockIcon size={14} /> <ClockIcon size={14} />
{format(artifact.createdAt, "dd/MM/yyyy HH:mm:ss")} {formatDateTime(artifact.createdAt)}
</span> </span>
</div> </div>

View File

@@ -98,7 +98,8 @@ export default function GameDetails() {
const handleStartDownload = async ( const handleStartDownload = async (
repack: GameRepack, repack: GameRepack,
downloader: Downloader, downloader: Downloader,
downloadPath: string downloadPath: string,
automaticallyExtract: boolean
) => { ) => {
const response = await startDownload({ const response = await startDownload({
repackId: repack.id, repackId: repack.id,
@@ -108,6 +109,7 @@ export default function GameDetails() {
shop, shop,
downloadPath, downloadPath,
uri: selectRepackUri(repack, downloader), uri: selectRepackUri(repack, downloader),
automaticallyExtract: automaticallyExtract,
}); });
if (response.ok) { if (response.ok) {

View File

@@ -1,6 +1,12 @@
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import { Button, Link, Modal, TextField } from "@renderer/components"; import {
Button,
CheckboxField,
Link,
Modal,
TextField,
} from "@renderer/components";
import { CheckCircleFillIcon, DownloadIcon } from "@primer/octicons-react"; import { CheckCircleFillIcon, DownloadIcon } from "@primer/octicons-react";
import { Downloader, formatBytes, getDownloadersForUris } from "@shared"; import { Downloader, formatBytes, getDownloadersForUris } from "@shared";
import type { GameRepack } from "@types"; import type { GameRepack } from "@types";
@@ -14,7 +20,8 @@ export interface DownloadSettingsModalProps {
startDownload: ( startDownload: (
repack: GameRepack, repack: GameRepack,
downloader: Downloader, downloader: Downloader,
downloadPath: string downloadPath: string,
automaticallyExtract: boolean
) => Promise<{ ok: boolean; error?: string }>; ) => Promise<{ ok: boolean; error?: string }>;
repack: GameRepack | null; repack: GameRepack | null;
} }
@@ -32,6 +39,8 @@ export function DownloadSettingsModal({
const [diskFreeSpace, setDiskFreeSpace] = useState<number | null>(null); const [diskFreeSpace, setDiskFreeSpace] = useState<number | null>(null);
const [selectedPath, setSelectedPath] = useState(""); const [selectedPath, setSelectedPath] = useState("");
const [downloadStarting, setDownloadStarting] = useState(false); const [downloadStarting, setDownloadStarting] = useState(false);
const [automaticExtractionEnabled, setAutomaticExtractionEnabled] =
useState(true);
const [selectedDownloader, setSelectedDownloader] = const [selectedDownloader, setSelectedDownloader] =
useState<Downloader | null>(null); useState<Downloader | null>(null);
const [hasWritePermission, setHasWritePermission] = useState<boolean | null>( const [hasWritePermission, setHasWritePermission] = useState<boolean | null>(
@@ -72,6 +81,21 @@ export function DownloadSettingsModal({
return getDownloadersForUris(repack?.uris ?? []); return getDownloadersForUris(repack?.uris ?? []);
}, [repack?.uris]); }, [repack?.uris]);
const getDefaultDownloader = useCallback(
(availableDownloaders: Downloader[]) => {
if (availableDownloaders.includes(Downloader.TorBox)) {
return Downloader.TorBox;
}
if (availableDownloaders.includes(Downloader.RealDebrid)) {
return Downloader.RealDebrid;
}
return availableDownloaders[0];
},
[]
);
useEffect(() => { useEffect(() => {
if (userPreferences?.downloadsPath) { if (userPreferences?.downloadsPath) {
setSelectedPath(userPreferences.downloadsPath); setSelectedPath(userPreferences.downloadsPath);
@@ -89,13 +113,9 @@ export function DownloadSettingsModal({
return true; return true;
}); });
/* Gives preference to TorBox */ setSelectedDownloader(getDefaultDownloader(filteredDownloaders));
const selectedDownloader = filteredDownloaders.includes(Downloader.TorBox)
? Downloader.TorBox
: filteredDownloaders[0];
setSelectedDownloader(selectedDownloader ?? null);
}, [ }, [
getDefaultDownloader,
userPreferences?.downloadsPath, userPreferences?.downloadsPath,
downloaders, downloaders,
userPreferences?.realDebridApiToken, userPreferences?.realDebridApiToken,
@@ -122,7 +142,8 @@ export function DownloadSettingsModal({
const response = await startDownload( const response = await startDownload(
repack, repack,
selectedDownloader!, selectedDownloader!,
selectedPath selectedPath,
automaticExtractionEnabled
); );
if (response.ok) { if (response.ok) {
@@ -217,6 +238,16 @@ export function DownloadSettingsModal({
</p> </p>
</div> </div>
{selectedDownloader !== Downloader.Torrent && (
<CheckboxField
label={t("automatically_extract_downloaded_files")}
checked={automaticExtractionEnabled}
onChange={() =>
setAutomaticExtractionEnabled(!automaticExtractionEnabled)
}
/>
)}
<Button <Button
onClick={handleStartClick} onClick={handleStartClick}
disabled={ disabled={

View File

@@ -16,7 +16,8 @@ export interface RepacksModalProps {
startDownload: ( startDownload: (
repack: GameRepack, repack: GameRepack,
downloader: Downloader, downloader: Downloader,
downloadPath: string downloadPath: string,
automaticallyExtract: boolean
) => Promise<{ ok: boolean; error?: string }>; ) => Promise<{ ok: boolean; error?: string }>;
onClose: () => void; onClose: () => void;
} }

View File

@@ -120,7 +120,7 @@ export function AddDownloadSourceModal({
downloadSourcesWorker.postMessage(["IMPORT_DOWNLOAD_SOURCE", url]); downloadSourcesWorker.postMessage(["IMPORT_DOWNLOAD_SOURCE", url]);
channel.onmessage = () => { channel.onmessage = () => {
window.electron.createDownloadSource(url); window.electron.createDownloadSources([url]);
setIsLoading(false); setIsLoading(false);
putDownloadSource(); putDownloadSource();

View File

@@ -139,9 +139,9 @@ export function SettingsGeneral() {
}))} }))}
/> />
<p className="settings-general__notifications-title"> <h2 className="settings-general__notifications-title">
{t("notifications")} {t("notifications")}
</p> </h2>
<CheckboxField <CheckboxField
label={t("enable_download_notifications")} label={t("enable_download_notifications")}

View File

@@ -1,5 +1,21 @@
import {
ptBR,
enUS,
es,
fr,
pl,
hu,
tr,
ru,
it,
be,
zhCN,
da,
} from "date-fns/locale";
import { charMap } from "./char-map"; import { charMap } from "./char-map";
import { Downloader } from "./constants"; import { Downloader } from "./constants";
import { format } from "date-fns";
export * from "./constants"; export * from "./constants";
@@ -124,3 +140,29 @@ export const steamUrlBuilder = {
icon: (objectId: string, clientIcon: string) => icon: (objectId: string, clientIcon: string) =>
`https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/${objectId}/${clientIcon}.ico`, `https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/${objectId}/${clientIcon}.ico`,
}; };
export const getDateLocale = (language: string) => {
if (language.startsWith("pt")) return ptBR;
if (language.startsWith("es")) return es;
if (language.startsWith("fr")) return fr;
if (language.startsWith("hu")) return hu;
if (language.startsWith("pl")) return pl;
if (language.startsWith("tr")) return tr;
if (language.startsWith("ru")) return ru;
if (language.startsWith("it")) return it;
if (language.startsWith("be")) return be;
if (language.startsWith("zh")) return zhCN;
if (language.startsWith("da")) return da;
return enUS;
};
export const formatDate = (
date: number | Date | string,
language: string
): string => {
if (isNaN(new Date(date).getDate())) return "N/A";
const locale = getDateLocale(language);
return format(date, locale == enUS ? "MM/dd/yyyy" : "dd/MM/yyyy");
};

View File

@@ -7,7 +7,8 @@ export type DownloadStatus =
| "error" | "error"
| "complete" | "complete"
| "seeding" | "seeding"
| "removed"; | "removed"
| "extracting";
export interface DownloadProgress { export interface DownloadProgress {
downloadSpeed: number; downloadSpeed: number;

View File

@@ -91,6 +91,7 @@ export interface StartGameDownloadPayload {
uri: string; uri: string;
downloadPath: string; downloadPath: string;
downloader: Downloader; downloader: Downloader;
automaticallyExtract: boolean;
} }
export interface UserFriend { export interface UserFriend {

View File

@@ -60,6 +60,8 @@ export interface Download {
status: DownloadStatus | null; status: DownloadStatus | null;
queued: boolean; queued: boolean;
timestamp: number; timestamp: number;
extracting: boolean;
automaticallyExtract: boolean;
} }
export interface GameAchievement { export interface GameAchievement {

242
yarn.lock
View File

@@ -3961,27 +3961,12 @@ bep53-range@^2.0.0:
resolved "https://registry.yarnpkg.com/bep53-range/-/bep53-range-2.0.0.tgz#a1770475661b4b814c4359e4b66f7cbd88de2b10" resolved "https://registry.yarnpkg.com/bep53-range/-/bep53-range-2.0.0.tgz#a1770475661b4b814c4359e4b66f7cbd88de2b10"
integrity sha512-sMm2sV5PRs0YOVk0LTKtjuIprVzxgTQUsrGX/7Yph2Rm4FO2Fqqtq7hNjsOB5xezM4v4+5rljCgK++UeQJZguA== integrity sha512-sMm2sV5PRs0YOVk0LTKtjuIprVzxgTQUsrGX/7Yph2Rm4FO2Fqqtq7hNjsOB5xezM4v4+5rljCgK++UeQJZguA==
better-sqlite3@^11.7.0:
version "11.7.0"
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.7.0.tgz#3eaa0f54f9e57d0a100d980e42320f8b9a4cd676"
integrity sha512-mXpa5jnIKKHeoGzBrUJrc65cXFKcILGZpU3FXR0pradUEm9MA7UZz02qfEejaMcm9iXrSOCenwwYMJ/tZ1y5Ig==
dependencies:
bindings "^1.5.0"
prebuild-install "^7.1.1"
binary-extensions@^2.0.0: binary-extensions@^2.0.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
bindings@^1.5.0: bl@^4.1.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, bl@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
@@ -4269,11 +4254,6 @@ chokidar@^3.5.3:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
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@^2.0.0: chownr@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
@@ -4405,11 +4385,6 @@ color@^4.2.3:
color-convert "^2.0.1" color-convert "^2.0.1"
color-string "^1.9.0" color-string "^1.9.0"
colorette@2.0.19:
version "2.0.19"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
colorjs.io@^0.5.0: colorjs.io@^0.5.0:
version "0.5.2" version "0.5.2"
resolved "https://registry.yarnpkg.com/colorjs.io/-/colorjs.io-0.5.2.tgz#63b20139b007591ebc3359932bef84628eb3fcef" resolved "https://registry.yarnpkg.com/colorjs.io/-/colorjs.io-0.5.2.tgz#63b20139b007591ebc3359932bef84628eb3fcef"
@@ -4422,11 +4397,6 @@ combined-stream@^1.0.8:
dependencies: dependencies:
delayed-stream "~1.0.0" delayed-stream "~1.0.0"
commander@^10.0.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
commander@^5.0.0: commander@^5.0.0:
version "5.1.0" version "5.1.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
@@ -4661,13 +4631,6 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, d
dependencies: dependencies:
ms "^2.1.3" ms "^2.1.3"
debug@4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
decimal.js@^10.4.3: decimal.js@^10.4.3:
version "10.4.3" version "10.4.3"
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
@@ -4680,11 +4643,6 @@ decompress-response@^6.0.0:
dependencies: dependencies:
mimic-response "^3.1.0" mimic-response "^3.1.0"
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
deep-is@^0.1.3: deep-is@^0.1.3:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@@ -4730,7 +4688,7 @@ delegates@^1.0.0:
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
detect-libc@^2.0.0, detect-libc@^2.0.1: detect-libc@^2.0.1:
version "2.0.3" version "2.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==
@@ -4985,7 +4943,7 @@ encoding@^0.1.13:
dependencies: dependencies:
iconv-lite "^0.6.2" iconv-lite "^0.6.2"
end-of-stream@^1.1.0, end-of-stream@^1.4.1: end-of-stream@^1.1.0:
version "1.4.4" version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@@ -5439,11 +5397,6 @@ eslint@^8.56.0:
strip-ansi "^6.0.1" strip-ansi "^6.0.1"
text-table "^0.2.0" text-table "^0.2.0"
esm@^3.2.25:
version "3.2.25"
resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
espree@^9.6.0, espree@^9.6.1: espree@^9.6.0, espree@^9.6.1:
version "9.6.1" version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -5487,11 +5440,6 @@ event-target-shim@^5.0.0:
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
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: exponential-backoff@^3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6"
@@ -5590,11 +5538,6 @@ file-type@^19.6.0:
token-types "^6.0.0" token-types "^6.0.0"
uint8array-extras "^1.3.0" uint8array-extras "^1.3.0"
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==
filelist@^1.0.4: filelist@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
@@ -5676,11 +5619,6 @@ formdata-polyfill@^4.0.10:
dependencies: dependencies:
fetch-blob "^3.1.2" fetch-blob "^3.1.2"
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, fs-extra@^10.1.0: fs-extra@^10.0.0, fs-extra@^10.1.0:
version "10.1.0" version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
@@ -5839,11 +5777,6 @@ get-nonce@^1.0.0:
resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3"
integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==
get-package-type@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
get-proto@^1.0.0, get-proto@^1.0.1: get-proto@^1.0.0, get-proto@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
@@ -5895,11 +5828,6 @@ get-them-args@1.3.2:
resolved "https://registry.yarnpkg.com/get-them-args/-/get-them-args-1.3.2.tgz#74a20ba8a4abece5ae199ad03f2bcc68fdfc9ba5" resolved "https://registry.yarnpkg.com/get-them-args/-/get-them-args-1.3.2.tgz#74a20ba8a4abece5ae199ad03f2bcc68fdfc9ba5"
integrity sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw== integrity sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw==
getopts@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4"
integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==
git-raw-commits@^4.0.0: git-raw-commits@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-4.0.0.tgz#b212fd2bff9726d27c1283a1157e829490593285" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-4.0.0.tgz#b212fd2bff9726d27c1283a1157e829490593285"
@@ -5909,11 +5837,6 @@ git-raw-commits@^4.0.0:
meow "^12.0.1" meow "^12.0.1"
split2 "^4.0.0" split2 "^4.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, glob-parent@~5.1.2: glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -6314,11 +6237,6 @@ ini@4.1.1:
resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1" resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1"
integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g== integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==
ini@~1.3.0:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
internal-slot@^1.0.7: internal-slot@^1.0.7:
version "1.0.7" version "1.0.7"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802"
@@ -6337,11 +6255,6 @@ internal-slot@^1.1.0:
hasown "^2.0.2" hasown "^2.0.2"
side-channel "^1.1.0" side-channel "^1.1.0"
interpret@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
invariant@^2.2.4: invariant@^2.2.4:
version "2.2.4" version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
@@ -6935,26 +6848,6 @@ kill-port@^2.0.1:
get-them-args "1.3.2" get-them-args "1.3.2"
shell-exec "1.0.2" shell-exec "1.0.2"
knex@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/knex/-/knex-3.1.0.tgz#b6ddd5b5ad26a6315234a5b09ec38dc4a370bd8c"
integrity sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==
dependencies:
colorette "2.0.19"
commander "^10.0.0"
debug "4.3.4"
escalade "^3.1.1"
esm "^3.2.25"
get-package-type "^0.1.0"
getopts "2.3.0"
interpret "^2.2.0"
lodash "^4.17.21"
pg-connection-string "2.6.2"
rechoir "^0.8.0"
resolve-from "^5.0.0"
tarn "^3.0.2"
tildify "2.0.0"
language-subtag-registry@^0.3.20: language-subtag-registry@^0.3.20:
version "0.3.23" version "0.3.23"
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7"
@@ -7107,7 +7000,7 @@ lodash.upperfirst@^4.3.1:
resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce"
integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==
lodash@^4.17.15, lodash@^4.17.21: lodash@^4.17.15:
version "4.17.21" version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -7320,7 +7213,7 @@ minimatch@^9.0.3, minimatch@^9.0.4:
dependencies: dependencies:
brace-expansion "^2.0.1" brace-expansion "^2.0.1"
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6, minimist@^1.2.8: minimist@^1.2.6, minimist@^1.2.8:
version "1.2.8" version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
@@ -7402,11 +7295,6 @@ minizlib@^3.0.1:
minipass "^7.0.4" minipass "^7.0.4"
rimraf "^5.0.5" rimraf "^5.0.5"
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==
mkdirp@^0.5.1: mkdirp@^0.5.1:
version "0.5.6" version "0.5.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
@@ -7429,11 +7317,6 @@ module-error@^1.0.1:
resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86"
integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ms@^2.0.0, ms@^2.1.1, ms@^2.1.3: ms@^2.0.0, ms@^2.1.1, ms@^2.1.3:
version "2.1.3" version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
@@ -7449,11 +7332,6 @@ nanoid@^3.3.7:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
napi-build-utils@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
napi-macros@^2.2.2: napi-macros@^2.2.2:
version "2.2.2" version "2.2.2"
resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044"
@@ -7477,7 +7355,7 @@ no-case@^3.0.4:
lower-case "^2.0.2" lower-case "^2.0.2"
tslib "^2.0.3" tslib "^2.0.3"
node-abi@^3.3.0, node-abi@^3.45.0: node-abi@^3.45.0:
version "3.68.0" version "3.68.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.68.0.tgz#8f37fb02ecf4f43ebe694090dcb52e0c4cc4ba25" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.68.0.tgz#8f37fb02ecf4f43ebe694090dcb52e0c4cc4ba25"
integrity sha512-7vbj10trelExNjFSBm5kTvZXXa7pZyKWx9RCKIyqe6I9Ev3IzGpQoqBP3a+cOdxY+pWj6VkP28n/2wWysBHD/A== integrity sha512-7vbj10trelExNjFSBm5kTvZXXa7pZyKWx9RCKIyqe6I9Ev3IzGpQoqBP3a+cOdxY+pWj6VkP28n/2wWysBHD/A==
@@ -7845,11 +7723,6 @@ pend@~1.2.0:
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
pg-connection-string@2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475"
integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==
picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0: picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59"
@@ -7890,24 +7763,6 @@ postcss@^8.4.43:
picocolors "^1.1.0" picocolors "^1.1.0"
source-map-js "^1.2.1" source-map-js "^1.2.1"
prebuild-install@^7.1.1:
version "7.1.2"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056"
integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==
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 "^1.0.1"
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"
prelude-ls@^1.2.1: prelude-ls@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -8023,16 +7878,6 @@ rc-virtual-list@^3.16.1:
rc-resize-observer "^1.0.0" rc-resize-observer "^1.0.0"
rc-util "^5.36.0" rc-util "^5.36.0"
rc@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
dependencies:
deep-extend "^0.6.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-dom@^18.2.0: react-dom@^18.2.0:
version "18.3.1" version "18.3.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
@@ -8147,7 +7992,7 @@ read-binary-file-arch@^1.0.6:
dependencies: dependencies:
debug "^4.3.4" debug "^4.3.4"
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.2" version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
@@ -8163,13 +8008,6 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
rechoir@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22"
integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==
dependencies:
resolve "^1.20.0"
redux-thunk@^3.1.0: redux-thunk@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-3.1.0.tgz#94aa6e04977c30e14e892eae84978c1af6058ff3" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-3.1.0.tgz#94aa6e04977c30e14e892eae84978c1af6058ff3"
@@ -8266,15 +8104,6 @@ resolve-from@^5.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
resolve@^1.20.0:
version "1.22.8"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
dependencies:
is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^2.0.0-next.5: resolve@^2.0.0-next.5:
version "2.0.0-next.5" version "2.0.0-next.5"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c"
@@ -8731,20 +8560,6 @@ signal-exit@^4.0.1:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== 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"
simple-swizzle@^0.2.2: simple-swizzle@^0.2.2:
version "0.2.2" version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
@@ -9000,11 +8815,6 @@ strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
strnum@^1.0.5: strnum@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db"
@@ -9074,27 +8884,6 @@ synckit@^0.9.1:
"@pkgr/core" "^0.1.0" "@pkgr/core" "^0.1.0"
tslib "^2.6.2" tslib "^2.6.2"
tar-fs@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
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@^6.0.5, tar@^6.1.11, tar@^6.1.12, tar@^6.1.2: tar@^6.0.5, tar@^6.1.11, tar@^6.1.12, tar@^6.1.2:
version "6.2.1" version "6.2.1"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a"
@@ -9119,11 +8908,6 @@ tar@^7.4.3:
mkdirp "^3.0.1" mkdirp "^3.0.1"
yallist "^5.0.0" yallist "^5.0.0"
tarn@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693"
integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==
temp-file@^3.4.0: temp-file@^3.4.0:
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/temp-file/-/temp-file-3.4.0.tgz#766ea28911c683996c248ef1a20eea04d51652c7" resolved "https://registry.yarnpkg.com/temp-file/-/temp-file-3.4.0.tgz#766ea28911c683996c248ef1a20eea04d51652c7"
@@ -9147,11 +8931,6 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
tildify@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a"
integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==
tiny-case@^1.0.3: tiny-case@^1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03"
@@ -9286,13 +9065,6 @@ tslib@^2.0.3, tslib@^2.6.2:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
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: type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"