diff --git a/.l10nignore b/.l10nignore new file mode 100644 index 0000000..e505894 --- /dev/null +++ b/.l10nignore @@ -0,0 +1,2 @@ +js/ +vendor/ \ No newline at end of file diff --git a/appinfo/info.xml b/appinfo/info.xml index 7b0d2c6..6edf2a5 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Groupfolder Filesystem Snapshots Allows restoring a groupfolder to a previous snapshot in the filesystem App proving a PHP API for other apps, that allows (partially) restoring a groupfolder to a previous snapshot in the filesystem. Requires a filesystem with snapshot support (tested with and made for ZFS). It is made for other apps to integrate with, IT DOES NOT WORK STANDALONE - 1.3.1 + 1.4.1 agpl verdigado eG Jonathan Treffler @@ -13,7 +13,7 @@ files https://git.verdigado.com/verdigado-public/nextcloud_groupfolder_filesystem_snapshots/issues - + pgsql sqlite mysql diff --git a/krankerl.toml b/krankerl.toml index eee1014..ecf3843 100644 --- a/krankerl.toml +++ b/krankerl.toml @@ -1,6 +1,6 @@ [package] before_cmds = [ "composer install", - "npm install", + "npm ci", "npm run build", ] diff --git a/l10n/.gitkeep b/l10n/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/l10n/de.js b/l10n/de.js new file mode 100644 index 0000000..a94a64b --- /dev/null +++ b/l10n/de.js @@ -0,0 +1,9 @@ +OC.L10N.register( + "groupfolder_filesystem_snapshots", + { + "Automated hourly backup" : "Stündliches automatisches Backup", + "Automated daily backup" : "Tägliches automatisches Backup", + "Automated weekly backup" : "Wöchentliches automatisches Backup", + "Automated monthly backup" : "Monatliches automatisches Backup" +}, +"nplurals=2; plural=(n != 1);"); diff --git a/l10n/de.json b/l10n/de.json new file mode 100644 index 0000000..8ae274f --- /dev/null +++ b/l10n/de.json @@ -0,0 +1,7 @@ +{ "translations": { + "Automated hourly backup" : "Stündliches automatisches Backup", + "Automated daily backup" : "Tägliches automatisches Backup", + "Automated weekly backup" : "Wöchentliches automatisches Backup", + "Automated monthly backup" : "Monatliches automatisches Backup" +},"pluralForm" :"nplurals=2; plural=(n != 1);" +} \ No newline at end of file diff --git a/l10n/de_DE.js b/l10n/de_DE.js new file mode 100644 index 0000000..a94a64b --- /dev/null +++ b/l10n/de_DE.js @@ -0,0 +1,9 @@ +OC.L10N.register( + "groupfolder_filesystem_snapshots", + { + "Automated hourly backup" : "Stündliches automatisches Backup", + "Automated daily backup" : "Tägliches automatisches Backup", + "Automated weekly backup" : "Wöchentliches automatisches Backup", + "Automated monthly backup" : "Monatliches automatisches Backup" +}, +"nplurals=2; plural=(n != 1);"); diff --git a/l10n/de_DE.json b/l10n/de_DE.json new file mode 100644 index 0000000..8ae274f --- /dev/null +++ b/l10n/de_DE.json @@ -0,0 +1,7 @@ +{ "translations": { + "Automated hourly backup" : "Stündliches automatisches Backup", + "Automated daily backup" : "Tägliches automatisches Backup", + "Automated weekly backup" : "Wöchentliches automatisches Backup", + "Automated monthly backup" : "Monatliches automatisches Backup" +},"pluralForm" :"nplurals=2; plural=(n != 1);" +} \ No newline at end of file diff --git a/lib/Controller/AdminSettingsController.php b/lib/Controller/AdminSettingsController.php index 97302d0..399e08e 100644 --- a/lib/Controller/AdminSettingsController.php +++ b/lib/Controller/AdminSettingsController.php @@ -19,29 +19,29 @@ class AdminSettingsController extends Controller { ); } - /** - * @return JSONResponse - */ - public function index(): JSONResponse { - return new JSONResponse($this->settingsService->getAppValues()); - } + /** + * @return JSONResponse + */ + public function index(): JSONResponse { + return new JSONResponse($this->settingsService->getAppValues()); + } - /** - * @param $key - * - * @return JSONResponse - */ - public function show($key): JSONResponse { - return new JSONResponse($this->settingsService->getAppValue($key)); - } + /** + * @param $key + * + * @return JSONResponse + */ + public function show($key): JSONResponse { + return new JSONResponse($this->settingsService->getAppValue($key)); + } - /** - * @param $key - * @param $value - * - * @return JSONResponse - */ - public function update($key, $value): JSONResponse { + /** + * @param $key + * @param $value + * + * @return JSONResponse + */ + public function update($key, $value): JSONResponse { return new JSONResponse($this->settingsService->setAppValue($key, $value)); - } + } } \ No newline at end of file diff --git a/lib/Db/DiffTask.php b/lib/Db/DiffTask.php index 0398287..7a5a8c4 100644 --- a/lib/Db/DiffTask.php +++ b/lib/Db/DiffTask.php @@ -7,25 +7,25 @@ use OCP\AppFramework\Db\Entity; class DiffTask extends Entity implements JsonSerializable { - protected $userId; - protected $groupfolderId; + protected $userId; + protected $groupfolderId; protected $relativePath; - protected $snapshotId; - protected $timestamp; + protected $snapshotId; + protected $timestamp; - public function __construct() { - $this->addType('id','integer'); - $this->addType('groupfolderId','integer'); - } + public function __construct() { + $this->addType('id','integer'); + $this->addType('groupfolderId','integer'); + } - public function jsonSerialize() { - return [ - 'id' => $this->id, + public function jsonSerialize() { + return [ + 'id' => $this->id, 'userId' => $this->userId, - 'groupfolderId' => $this->groupfolderId, + 'groupfolderId' => $this->groupfolderId, 'relativePath' => $this->relativePath, - 'snapshotId' => $this->snapshotId, - 'timestamp' => $this->timestamp, - ]; - } + 'snapshotId' => $this->snapshotId, + 'timestamp' => $this->timestamp, + ]; + } } \ No newline at end of file diff --git a/lib/Db/DiffTaskMapper.php b/lib/Db/DiffTaskMapper.php index b1811c6..86f0353 100644 --- a/lib/Db/DiffTaskMapper.php +++ b/lib/Db/DiffTaskMapper.php @@ -9,29 +9,29 @@ use OCP\AppFramework\Db\QBMapper; */ class DiffTaskMapper extends QBMapper { - public function __construct(IDBConnection $db) { - parent::__construct($db, 'groupfolder_snapshots_tasks', DiffTask::class); - } + public function __construct(IDBConnection $db) { + parent::__construct($db, 'groupfolder_snapshots_tasks', DiffTask::class); + } - public function find(int $id, string $userId) { - $qb = $this->db->getQueryBuilder(); + public function find(int $id, string $userId) { + $qb = $this->db->getQueryBuilder(); - $qb->select('*') - ->from($this->getTableName()) - ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) - ->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))); + $qb->select('*') + ->from($this->getTableName()) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) + ->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))); - return $this->findEntity($qb); - } + return $this->findEntity($qb); + } - public function findAll(string $userId) { - $qb = $this->db->getQueryBuilder(); + public function findAll(string $userId) { + $qb = $this->db->getQueryBuilder(); - $qb->select('*') - ->from($this->getTableName()) - ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))); + $qb->select('*') + ->from($this->getTableName()) + ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))); - return $this->findEntities($qb); - } + return $this->findEntities($qb); + } } \ No newline at end of file diff --git a/lib/Db/DiffTaskResult.php b/lib/Db/DiffTaskResult.php index b6865a9..e16d63e 100644 --- a/lib/Db/DiffTaskResult.php +++ b/lib/Db/DiffTaskResult.php @@ -7,45 +7,49 @@ use OCP\AppFramework\Db\Entity; class DiffTaskResult extends Entity implements JsonSerializable { - protected $taskId; - protected $timestamp; - protected $type; + protected $taskId; + protected $timestamp; + protected $type; - protected $beforeFileExists; - protected $beforePath; - protected $beforeSize; + protected $beforeFileExists; + protected $beforePath; + protected $beforeSize; - protected $currentFileExists; - protected $currentPath; - protected $currentSize; + protected $currentFileExists; + protected $currentFileId; + + protected $currentPath; + protected $currentSize; protected $reverted; - public function __construct() { - $this->addType('id','integer'); - $this->addType('taskId','integer'); - $this->addType('beforeFileExists','boolean'); - $this->addType('beforeSize','integer'); - $this->addType('currentFileExists','boolean'); - $this->addType('currentSize','integer'); + public function __construct() { + $this->addType('id','integer'); + $this->addType('taskId','integer'); + $this->addType('beforeFileExists','boolean'); + $this->addType('beforeSize','integer'); + $this->addType('currentFileExists','boolean'); + $this->addType('currentFileId','integer'); + $this->addType('currentSize','integer'); $this->addType('reverted','boolean'); - } + } - public function jsonSerialize() { - return [ - 'id' => $this->id, - 'taskId' => $this->taskId, - 'type' => $this->type, - 'before' => [ - 'fileExists' => $this->beforeFileExists, - 'path' => $this->beforePath, - 'size' => $this->beforeSize, - ], - 'current' => [ - 'fileExists' => $this->currentFileExists, - 'path' => $this->currentPath, - 'size' => $this->currentSize, + public function jsonSerialize() { + return [ + 'id' => $this->id, + 'taskId' => $this->taskId, + 'type' => $this->type, + 'before' => [ + 'fileExists' => $this->beforeFileExists, + 'path' => $this->beforePath, + 'size' => $this->beforeSize, + ], + 'current' => [ + 'fileExists' => $this->currentFileExists, + 'fileId' => $this->currentFileId, + 'path' => $this->currentPath, + 'size' => $this->currentSize, ], 'reverted' => $this->reverted, - ]; - } + ]; + } } \ No newline at end of file diff --git a/lib/Db/DiffTaskResultMapper.php b/lib/Db/DiffTaskResultMapper.php index 882a0e1..7ecbaf2 100644 --- a/lib/Db/DiffTaskResultMapper.php +++ b/lib/Db/DiffTaskResultMapper.php @@ -9,29 +9,29 @@ use OCP\AppFramework\Db\QBMapper; */ class DiffTaskResultMapper extends QBMapper { - public function __construct(IDBConnection $db) { - parent::__construct($db, 'groupfolder_snapshots_task_results', DiffTaskResult::class); - } + public function __construct(IDBConnection $db) { + parent::__construct($db, 'groupfolder_snapshots_task_results', DiffTaskResult::class); + } - public function find(int $id) { - $qb = $this->db->getQueryBuilder(); + public function find(int $id) { + $qb = $this->db->getQueryBuilder(); - $qb->select('*') - ->from($this->getTableName()) - ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))); + $qb->select('*') + ->from($this->getTableName()) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))); - return $this->findEntity($qb); - } + return $this->findEntity($qb); + } - public function findAll(int $taskId) { - $qb = $this->db->getQueryBuilder(); + public function findAll(int $taskId) { + $qb = $this->db->getQueryBuilder(); - $qb->select('*') - ->from($this->getTableName()) - ->where($qb->expr()->eq('task_id', $qb->createNamedParameter($taskId))); + $qb->select('*') + ->from($this->getTableName()) + ->where($qb->expr()->eq('task_id', $qb->createNamedParameter($taskId))); - return $this->findEntities($qb); - } + return $this->findEntities($qb); + } public function markReverted(int $id) { $taskResult = $this->find($id); diff --git a/lib/Entity/Snapshot.php b/lib/Entity/Snapshot.php index e571a7d..90a99fe 100644 --- a/lib/Entity/Snapshot.php +++ b/lib/Entity/Snapshot.php @@ -5,16 +5,30 @@ namespace OCA\GroupfolderFilesystemSnapshots\Entity; use JsonSerializable; class Snapshot implements JsonSerializable { - /** @var string */ - private $id; + public function __construct( + private string $id, + private string $name, + private ?\DateTimeImmutable $createdTimestamp = null, + ) { + } - public function __construct(string $id) { - $this->id = $id; - } + public function getId(): string { + return $this->id; + } - public function jsonSerialize(): mixed { + public function getName(): string { + return $this->name; + } + + public function getCreatedTimestamp(): ?\DateTimeImmutable { + return $this->createdTimestamp; + } + + public function jsonSerialize(): mixed { return [ - 'id' => $this->id + 'id' => $this->id, + 'name' => $this->name, + 'createdTimestamp' => $this->createdTimestamp?->getTimestamp(), ]; } } diff --git a/lib/Helpers/FileHelper.php b/lib/Helpers/FileHelper.php index c987549..27b6992 100644 --- a/lib/Helpers/FileHelper.php +++ b/lib/Helpers/FileHelper.php @@ -3,34 +3,34 @@ namespace OCA\GroupfolderFilesystemSnapshots\Helpers; class FileHelper { - private static function seperateFilesFromFolders($parentDir, $items) { - $files = []; - $folders = []; + private static function seperateFilesFromFolders($parentDir, $items) { + $files = []; + $folders = []; - foreach($items as $item) { - if(is_dir($parentDir . DIRECTORY_SEPARATOR . $item)) { - $folders[] = $item; - } else { - $files[] = $item; - } - } + foreach($items as $item) { + if(is_dir($parentDir . DIRECTORY_SEPARATOR . $item)) { + $folders[] = $item; + } else { + $files[] = $item; + } + } - return array($files, $folders); - } + return array($files, $folders); + } - public static function getFilesAndFolders($dir) { - $scan = array_diff(scandir($dir), array('..', '.')); + public static function getFilesAndFolders($dir) { + $scan = array_diff(scandir($dir), array('..', '.')); - return self::seperateFilesFromFolders($dir, $scan); - } + return self::seperateFilesFromFolders($dir, $scan); + } - public static function getFilesizesOfFiles($prefix, array $files) { - $result = array(); + public static function getFilesizesOfFiles($prefix, array $files) { + $result = array(); - foreach($files as $index=>$file) { - $result[$index] = filesize($prefix . DIRECTORY_SEPARATOR . $file); - } + foreach($files as $index=>$file) { + $result[$index] = filesize($prefix . DIRECTORY_SEPARATOR . $file); + } - return $result; - } + return $result; + } } \ No newline at end of file diff --git a/lib/Manager/PathManager.php b/lib/Manager/PathManager.php index 7b8a6e9..d7f0234 100644 --- a/lib/Manager/PathManager.php +++ b/lib/Manager/PathManager.php @@ -70,12 +70,12 @@ class PathManager { private function checkIfGroupfolderExists(int $groupfolderId): bool { $storageId = $this->getRootFolderStorageId(); if ($storageId === null) { - return "storage Id null"; + return false; } $folder = $this->groupfolderFolderManager->getFolder($groupfolderId, $storageId); if ($folder === false) { - return "Folder does not exist"; + return false; } return true; diff --git a/lib/Manager/SnapshotManager.php b/lib/Manager/SnapshotManager.php index a66def3..ac9594b 100644 --- a/lib/Manager/SnapshotManager.php +++ b/lib/Manager/SnapshotManager.php @@ -2,16 +2,21 @@ namespace OCA\GroupfolderFilesystemSnapshots\Manager; -use OCA\GroupfolderFilesystemSnapshots\Manager\PathManager; +use OCP\IL10N; +use OCA\GroupfolderFilesystemSnapshots\Manager\PathManager; +use OCA\GroupfolderFilesystemSnapshots\Service\SettingsService; use OCA\GroupfolderFilesystemSnapshots\Entity\Snapshot; class SnapshotManager { - private PathManager $pathManager; + private string $snapshotNamingScheme = ""; - - public function __construct(PathManager $pathManager){ - $this->pathManager = $pathManager; + public function __construct( + protected readonly IL10N $l10n, + private readonly PathManager $pathManager, + private readonly SettingsService $settingsService, + ){ + $this->snapshotNamingScheme = $this->settingsService->getAppValue("snapshot_naming_scheme"); } private function validSnapshotId(string $snapshotId) { @@ -27,20 +32,94 @@ class SnapshotManager { } } + private function createSnapshotEntity(string $id): Snapshot { + if ($this->snapshotNamingScheme === "zfs-auto-snapshot" && str_starts_with($id, "zfs-auto-snap")) { + if (str_starts_with($id, "zfs-auto-snap_hourly-")) { + $name = $this->l10n->t("Automated hourly backup"); + $datetimestring = str_replace("zfs-auto-snap_hourly-", "", $id); + } elseif (str_starts_with($id, "zfs-auto-snap_daily-")) { + $name = $this->l10n->t("Automated daily backup"); + $datetimestring = str_replace("zfs-auto-snap_daily-", "", $id); + } elseif (str_starts_with($id, "zfs-auto-snap_weekly-")) { + $name = $this->l10n->t("Automated weekly backup"); + $datetimestring = str_replace("zfs-auto-snap_weekly-", "", $id); + } elseif (str_starts_with($id, "zfs-auto-snap_monthly-")) { + $name = $this->l10n->t("Automated monthly backup"); + $datetimestring = str_replace("zfs-auto-snap_monthly-", "", $id); + } + + if(isset($datetimestring)) { + $datetimearray = explode("-", $datetimestring); + $timestring = array_pop($datetimearray); + + $year = (int)$datetimearray[0]; + $month = (int)$datetimearray[1]; + $day = (int)$datetimearray[2]; + $hour = (int)substr($timestring, 0, 2); + $minute = (int)substr($timestring, 2, 2); + + $createdTimestamp = (new \DateTimeImmutable()) + ->setDate($year, $month, $day) + ->setTime($hour, $minute); + } + + return new Snapshot( + id: $id, + name: $name ?: $id, + createdTimestamp: $createdTimestamp, + ); + } else { + return new Snapshot( + id: $id, + name: $id, + ); + } + } + function get(string $snapshotId) { if(self::snapshotExists($snapshotId)) { - return new Snapshot($snapshotId); + return $this->createSnapshotEntity($snapshotId); } else { return false; } - } - function getAll() { + function getAll(): array { + $snapshots = []; + $iterator = new \FilesystemIterator($this->pathManager->getFilesystemSnapshotsPath()); - foreach ($iterator as $fileinfo) { - if(!$fileinfo->isDir()) continue; - yield new Snapshot($fileinfo->getFilename()); - } + + foreach ($iterator as $fileinfo) { + if(!$fileinfo->isDir()) continue; + $snapshots[] = $this->createSnapshotEntity($fileinfo->getFilename()); + } + + return $snapshots; } + + function getAllGenerator(){ + $iterator = new \FilesystemIterator($this->pathManager->getFilesystemSnapshotsPath()); + + foreach ($iterator as $fileinfo) { + if(!$fileinfo->isDir()) continue; + yield $this->createSnapshotEntity($fileinfo->getFilename()); + } + } + + /** + * @var $subPathFilter Only return snapshots that have this subfolder in the specified groupfolder + */ + function getFilteredGenerator(int $groupfolderId, string $subDirectoryFilter) { + $iterator = new \FilesystemIterator($this->pathManager->getFilesystemSnapshotsPath()); + + $groupfolderSubdirectoryPath = $this->pathManager->getGroupFolderDirectory($groupfolderId, $subDirectoryFilter); + + foreach ($iterator as $fileinfo) { + if(!$fileinfo->isDir()) continue; + $snapshotId = $fileinfo->getFilename(); + $filterFullPath = $this->pathManager->convertToSnapshotPath($groupfolderSubdirectoryPath, $snapshotId); + if(!(is_dir($filterFullPath))) continue; + yield $this->createSnapshotEntity($snapshotId); + } + } } \ No newline at end of file diff --git a/lib/Migration/Version140Date20250701164500.php b/lib/Migration/Version140Date20250701164500.php new file mode 100644 index 0000000..bebdd12 --- /dev/null +++ b/lib/Migration/Version140Date20250701164500.php @@ -0,0 +1,33 @@ +getTable(self::RESULTS_TABLE); + + if(!$table->hasColumn('current_file_id')) { + $table->addColumn('current_file_id', Types::BIGINT, [ + 'notnull' => false, + ]); + } + + return $schema; + } +} diff --git a/lib/RecursiveDiff.php b/lib/RecursiveDiff.php index 98ed344..9196eee 100644 --- a/lib/RecursiveDiff.php +++ b/lib/RecursiveDiff.php @@ -5,227 +5,223 @@ namespace OCA\GroupfolderFilesystemSnapshots; use OCA\GroupfolderFilesystemSnapshots\Helpers\FileHelper; class RecursiveDiff { + private $scan1files = []; + private $scan1folders = []; - public string $dir1; - public string $dir2; + private $scan2files = []; + private $scan2folders = []; - private $prefix; + private $subJobs = []; - private $newResultCallback; - private $progressCallback; + private $subJobProgress = []; + private $progress = 0; - private $scan1files = []; - private $scan1folders = []; + public function __construct( + public readonly string $dir1, + public readonly string $dir2, + private readonly string $prefix = "", + private readonly array $folderBlocklist = [], + private $newResultCallback, + private $progressCallback, + ){} - private $scan2files = []; - private $scan2folders = []; + public function scan() { + $scan_num_files = 0; - private $subJobs = []; + if(file_exists($this->dir1) && is_dir($this->dir1)) { + [$this->scan1files, $this->scan1folders] = FileHelper::getFilesAndFolders($this->dir1); + } + + if(file_exists($this->dir2) && is_dir($this->dir2)) { + [$this->scan2files, $this->scan2folders] = FileHelper::getFilesAndFolders($this->dir2); + } - private $subJobProgress = []; - private $progress = 0; + $scan_num_files += sizeof($this->scan1files); + $scan_num_files += sizeof($this->scan2files); + + $allSubfolders = array_unique(array_merge($this->scan1folders, $this->scan2folders)); - public function __construct($dir1, $dir2, $prefix = "", $newResultCallback, $progressCallback){ - $this->dir1 = $dir1; - $this->dir2 = $dir2; - $this->prefix = $prefix; + foreach($allSubfolders as $key=>$folder) { + $subdir1 = $this->dir1 . DIRECTORY_SEPARATOR . $folder; + $subdir2 = $this->dir2 . DIRECTORY_SEPARATOR . $folder; + $subprefix = $this->prefix . DIRECTORY_SEPARATOR . $folder; + $subFolderBlocklist = $this->folderBlocklist[$folder] ?? []; - $this->newResultCallback = $newResultCallback; - $this->progressCallback = $progressCallback; - } + if($subFolderBlocklist === true) { + continue; + } + + $newJob = new RecursiveDiff($subdir1, $subdir2, $subprefix, $subFolderBlocklist, $this->newResultCallback, function($numDoneFiles) use ($key) { + $this->subJobProgress[$key] = $numDoneFiles; - public function scan() { - $scan_num_files = 0; + $this->updateProgress(); + }); - if(file_exists($this->dir1) && is_dir($this->dir1)) { - [$this->scan1files, $this->scan1folders] = FileHelper::getFilesAndFolders($this->dir1); - } - - if(file_exists($this->dir2) && is_dir($this->dir2)) { - [$this->scan2files, $this->scan2folders] = FileHelper::getFilesAndFolders($this->dir2); - } + $this->subJobs[] = $newJob; - $scan_num_files += sizeof($this->scan1files); - $scan_num_files += sizeof($this->scan2files); - - $allSubfolders = array_unique(array_merge($this->scan1folders, $this->scan2folders)); + $scan_num_files += $newJob->scan(); + } - foreach($allSubfolders as $key=>$folder) { - $subdir1 = $this->dir1 . DIRECTORY_SEPARATOR . $folder; - $subdir2 = $this->dir2 . DIRECTORY_SEPARATOR . $folder; - $subprefix = $this->prefix . DIRECTORY_SEPARATOR . $folder; - - $newJob = new RecursiveDiff($subdir1, $subdir2, $subprefix, $this->newResultCallback, function($numDoneFiles) use ($key) { - $this->subJobProgress[$key] = $numDoneFiles; + return $scan_num_files; + } - $this->updateProgress(); - }); + private function updateProgress() { + ($this->progressCallback)(array_sum($this->subJobProgress) + $this->progress); + } - $this->subJobs[] = $newJob; + function diff() { + $diff = []; - $scan_num_files += $newJob->scan(); - } + foreach($this->subJobs as $job) { + $result = $job->diff(); + array_push($diff, ...$result); + } - return $scan_num_files; - } + $fileCreations = array_diff($this->scan2files, $this->scan1files); + $fileCreationsFilesizes = FileHelper::getFilesizesOfFiles($this->dir2, $fileCreations); - private function updateProgress() { - ($this->progressCallback)(array_sum($this->subJobProgress) + $this->progress); - } + $fileDeletions = array_diff($this->scan1files, $this->scan2files); + $fileDeletionsFilesizes = FileHelper::getFilesizesOfFiles($this->dir1, $fileDeletions); - function diff() { - $diff = []; + $filePossibleEdits = array_intersect($this->scan1files, $this->scan2files); - foreach($this->subJobs as $job) { - $result = $job->diff(); - array_push($diff, ...$result); - } + /*$diff[] = [ + "type" => "DEBUG", + "prefix" => $this->prefix, + "fileCreations" => $fileCreations, + "fileCreationsFilesizes" => $fileCreationsFilesizes, + "fileDeletions" => $fileDeletions, + "fileDeletionsFilesizes" => $fileDeletionsFilesizes, + //"folderCreations" => $folderCreations, + //"folderDeletions" => $folderDeletions, + "allSubfolders" => $allSubfolders, + ];*/ - $fileCreations = array_diff($this->scan2files, $this->scan1files); - $fileCreationsFilesizes = FileHelper::getFilesizesOfFiles($this->dir2, $fileCreations); + // search for creations and deletions, that are actually renames + foreach($fileCreations as $creationIndex=>$creation) { + $creationPath = $this->dir2 . DIRECTORY_SEPARATOR . $creation; + $creationSize = $fileCreationsFilesizes[$creationIndex]; + + $renameContenders = array_keys($fileDeletionsFilesizes, $creationSize); - $fileDeletions = array_diff($this->scan1files, $this->scan2files); - $fileDeletionsFilesizes = FileHelper::getFilesizesOfFiles($this->dir1, $fileDeletions); + if(sizeof($renameContenders) != 0) { + /*$diff[] = [ + "type" => "DEBUG", + "comparing" => [ + "creation" => $creationIndex, + "deletions" => $renameContenders, + ], + ];*/ - $filePossibleEdits = array_intersect($this->scan1files, $this->scan2files); + $creationSHA = sha1_file($creationPath); + foreach($renameContenders as $contender) { + $deletion = $fileDeletions[$contender]; + $deletionPath = $this->dir1 . DIRECTORY_SEPARATOR . $deletion; + $deletionSHA = sha1_file($deletionPath); - /*$diff[] = [ - "type" => "DEBUG", - "prefix" => $this->prefix, - "fileCreations" => $fileCreations, - "fileCreationsFilesizes" => $fileCreationsFilesizes, - "fileDeletions" => $fileDeletions, - "fileDeletionsFilesizes" => $fileDeletionsFilesizes, - //"folderCreations" => $folderCreations, - //"folderDeletions" => $folderDeletions, - "allSubfolders" => $allSubfolders, - ];*/ + if($deletionSHA == $creationSHA) { + ($this->newResultCallback)( + type: "RENAME", + beforeFileExists: True, + beforePath: $this->prefix . DIRECTORY_SEPARATOR . $deletion, + beforeSize: $creationSize, + currentFileExists: True, + currentPath: $this->prefix . DIRECTORY_SEPARATOR . $creation, + currentSize: $creationSize, + ); - // search for creations and deletions, that are actually renames - foreach($fileCreations as $creationIndex=>$creation) { - $creationPath = $this->dir2 . DIRECTORY_SEPARATOR . $creation; - $creationSize = $fileCreationsFilesizes[$creationIndex]; - - $renameContenders = array_keys($fileDeletionsFilesizes, $creationSize); + unset($fileCreations[$creationIndex]); + unset($fileDeletions[$contender]); - if(sizeof($renameContenders) != 0) { - /*$diff[] = [ - "type" => "DEBUG", - "comparing" => [ - "creation" => $creationIndex, - "deletions" => $renameContenders, - ], - ];*/ + $this->progress += 2; + $this->updateProgress(); - $creationSHA = sha1_file($creationPath); - foreach($renameContenders as $contender) { - $deletion = $fileDeletions[$contender]; - $deletionPath = $this->dir1 . DIRECTORY_SEPARATOR . $deletion; - $deletionSHA = sha1_file($deletionPath); + break; + } + } + } + } - if($deletionSHA == $creationSHA) { - ($this->newResultCallback)( - type: "RENAME", - beforeFileExists: True, - beforePath: $this->prefix . DIRECTORY_SEPARATOR . $deletion, - beforeSize: $creationSize, - currentFileExists: True, - currentPath: $this->prefix . DIRECTORY_SEPARATOR . $creation, - currentSize: $creationSize, - ); + foreach($fileCreations as $index=>$creation) { + ($this->newResultCallback)( + type: "CREATION", + beforeFileExists: False, + beforePath: NULL, + beforeSize: NULL, + currentFileExists: True, + currentPath: $this->prefix . DIRECTORY_SEPARATOR . $creation, + currentSize: $fileCreationsFilesizes[$index], + ); - unset($fileCreations[$creationIndex]); - unset($fileDeletions[$contender]); + $this->progress++; + $this->updateProgress(); + } - $this->progress += 2; - $this->updateProgress(); + foreach($fileDeletions as $index=>$deletion) { + ($this->newResultCallback)( + type: "DELETION", + beforeFileExists: True, + beforePath: $this->prefix . DIRECTORY_SEPARATOR . $deletion, + beforeSize: $fileDeletionsFilesizes[$index], + currentFileExists: False, + currentPath: NULL, + currentSize: NULL, + ); - break; - } - } - } - } + $this->progress++; + $this->updateProgress(); + } - foreach($fileCreations as $index=>$creation) { - ($this->newResultCallback)( - type: "CREATION", - beforeFileExists: False, - beforePath: NULL, - beforeSize: NULL, - currentFileExists: True, - currentPath: $this->prefix . DIRECTORY_SEPARATOR . $creation, - currentSize: $fileCreationsFilesizes[$index], - ); + foreach($filePossibleEdits as $possibleEdit) { + $file1 = $this->dir1 . DIRECTORY_SEPARATOR . $possibleEdit; + $file2 = $this->dir2 . DIRECTORY_SEPARATOR . $possibleEdit; + $file1Size = filesize($file1); + $file2Size = filesize($file2); - $this->progress++; - $this->updateProgress(); - } + $this->progress += 2; + $this->updateProgress(); - foreach($fileDeletions as $index=>$deletion) { - ($this->newResultCallback)( - type: "DELETION", - beforeFileExists: True, - beforePath: $this->prefix . DIRECTORY_SEPARATOR . $deletion, - beforeSize: $fileDeletionsFilesizes[$index], - currentFileExists: False, - currentPath: NULL, - currentSize: NULL, - ); + if(filemtime($file1) == filemtime($file2)) { + //not different because same mtime + continue; + } else { + // mtime different, but could just have gotten touched without modifications + if($file1Size == $file2Size) { + // if filesize is the same check for binary differences + $handle1 = fopen($file1, 'rb'); + $handle2 = fopen($file2, 'rb'); - $this->progress++; - $this->updateProgress(); - } + $filesdifferent = false; - foreach($filePossibleEdits as $possibleEdit) { - $file1 = $this->dir1 . DIRECTORY_SEPARATOR . $possibleEdit; - $file2 = $this->dir2 . DIRECTORY_SEPARATOR . $possibleEdit; - $file1Size = filesize($file1); - $file2Size = filesize($file2); + while(!feof($handle1)) { + if(fread($handle1, 8192) != fread($handle2, 8192)) { + // files are different + $filesdifferent = true; + break; + } + } - $this->progress += 2; - $this->updateProgress(); + fclose($handle1); + fclose($handle2); - if(filemtime($file1) == filemtime($file2)) { - //not different because same mtime - continue; - } else { - // mtime different, but could just have gotten touched without modifications - if($file1Size == $file2Size) { - // if filesize is the same check for binary differences - $handle1 = fopen($file1, 'rb'); - $handle2 = fopen($file2, 'rb'); + if(!$filesdifferent) { + continue; + } + } + } - $filesdifferent = false; + + ($this->newResultCallback)( + type: "EDIT", + beforeFileExists: True, + beforePath: $this->prefix . DIRECTORY_SEPARATOR . $possibleEdit, + beforeSize: $file1Size, + currentFileExists: True, + currentPath: $this->prefix . DIRECTORY_SEPARATOR . $possibleEdit, + currentSize: $file2Size, + ); + } - while(!feof($handle1)) { - if(fread($handle1, 8192) != fread($handle2, 8192)) { - // files are different - $filesdifferent = true; - break; - } - } - - fclose($handle1); - fclose($handle2); - - if(!$filesdifferent) { - continue; - } - } - } - - - ($this->newResultCallback)( - type: "EDIT", - beforeFileExists: True, - beforePath: $this->prefix . DIRECTORY_SEPARATOR . $possibleEdit, - beforeSize: $file1Size, - currentFileExists: True, - currentPath: $this->prefix . DIRECTORY_SEPARATOR . $possibleEdit, - currentSize: $file2Size, - ); - } - - return $diff; - } + return $diff; + } } \ No newline at end of file diff --git a/lib/Sections/SnapshotsSection.php b/lib/Sections/SnapshotsSection.php index ca5800e..75f6ac5 100644 --- a/lib/Sections/SnapshotsSection.php +++ b/lib/Sections/SnapshotsSection.php @@ -6,27 +6,27 @@ use OCP\IURLGenerator; use OCP\Settings\IIconSection; class SnapshotsSection implements IIconSection { - private IL10N $l; - private IURLGenerator $urlGenerator; + private IL10N $l; + private IURLGenerator $urlGenerator; - public function __construct(IL10N $l, IURLGenerator $urlGenerator) { - $this->l = $l; - $this->urlGenerator = $urlGenerator; - } + public function __construct(IL10N $l, IURLGenerator $urlGenerator) { + $this->l = $l; + $this->urlGenerator = $urlGenerator; + } - public function getIcon(): string { - return $this->urlGenerator->imagePath('core', 'actions/settings-dark.svg'); - } + public function getIcon(): string { + return $this->urlGenerator->imagePath('core', 'actions/settings-dark.svg'); + } - public function getID(): string { - return 'groupfolder_filesystem_snapshots'; - } + public function getID(): string { + return 'groupfolder_filesystem_snapshots'; + } - public function getName(): string { - return $this->l->t('Groupfolder Filesystem Snapshots'); - } + public function getName(): string { + return $this->l->t('Groupfolder Filesystem Snapshots'); + } - public function getPriority(): int { - return 98; - } + public function getPriority(): int { + return 98; + } } \ No newline at end of file diff --git a/lib/Service/DiffTaskResultService.php b/lib/Service/DiffTaskResultService.php index 399185b..ed2e750 100644 --- a/lib/Service/DiffTaskResultService.php +++ b/lib/Service/DiffTaskResultService.php @@ -58,7 +58,7 @@ class DiffTaskResultService { $diffTaskResult = $this->find($id); if($diffTaskResult->getReverted()) { - throw new AlreadyRevertedException; + throw new AlreadyRevertedException(); } $taskId = $diffTaskResult->getTaskId(); @@ -66,35 +66,35 @@ class DiffTaskResultService { $snapshotPath = $this->pathManager->getGroupFolderSnapshotDirectory($diffTask->getGroupfolderId(), $diffTask->getRelativePath(), $diffTask->getSnapshotId()); - $gruenerFolder = $this->pathManager->getGroupfolderMountById($diffTask->getGroupfolderId())->get($diffTask->getRelativePath()); + $parentFolder = $this->pathManager->getGroupfolderMountById($diffTask->getGroupfolderId())->get($diffTask->getRelativePath()); switch($diffTaskResult->getType()) { case "CREATION": - $currentFile = $this->getSubfolderMustExist($gruenerFolder, $diffTaskResult->getCurrentPath()); + $currentFile = $this->getSubfolderMustExist($parentFolder, $diffTaskResult->getCurrentPath()); $currentFile->delete(); break; case "RENAME": - $currentFile = $this->getSubfolderMustExist($gruenerFolder, $diffTaskResult->getCurrentPath()); - $beforeDirectory = $this->getOrCreateSubdirectoryByFilepath($gruenerFolder, $diffTaskResult->getBeforePath()); + $currentFile = $this->getSubfolderMustExist($parentFolder, $diffTaskResult->getCurrentPath()); + $beforeDirectory = $this->getOrCreateSubdirectoryByFilepath($parentFolder, $diffTaskResult->getBeforePath()); $currentFile->move($beforeDirectory->getPath() . DIRECTORY_SEPARATOR . basename($diffTaskResult->getBeforePath())); break; case "DELETION": $beforeFileFilesystemPath = $snapshotPath . DIRECTORY_SEPARATOR . $diffTaskResult->getBeforePath(); - $beforeDirectory = $this->getOrCreateSubdirectoryByFilepath($gruenerFolder, $diffTaskResult->getBeforePath()); + $beforeDirectory = $this->getOrCreateSubdirectoryByFilepath($parentFolder, $diffTaskResult->getBeforePath()); $restoredFile = $beforeDirectory->newFile(basename($diffTaskResult->getBeforePath())); $this->copyFilesystemFileToNextcloudFile($beforeFileFilesystemPath, $restoredFile); break; case "EDIT": - $currentFile = $this->getSubfolderMustExist($gruenerFolder, $diffTaskResult->getCurrentPath()); + $currentFile = $this->getSubfolderMustExist($parentFolder, $diffTaskResult->getCurrentPath()); $beforeFileFilesystemPath = $snapshotPath . DIRECTORY_SEPARATOR . $diffTaskResult->getBeforePath(); $this->copyFilesystemFileToNextcloudFile($beforeFileFilesystemPath, $currentFile); break; default: - throw new \Exception; + throw new Exception(); } return $this->mapper->markReverted($id); @@ -104,7 +104,7 @@ class DiffTaskResultService { if($parent->nodeExists($path)) { return $parent->get($path); } else { - throw new ChangesMadeSinceDiffException; + throw new ChangesMadeSinceDiffException(); } } @@ -119,7 +119,7 @@ class DiffTaskResultService { if($temp instanceof \OCP\Files\Folder) { $beforeDirectory = $temp; } else { - throw new ChangesMadeSinceDiffException; + throw new ChangesMadeSinceDiffException(); } } else { $beforeDirectory = $beforeDirectory->newFolder($subdir); diff --git a/lib/Service/DiffTaskService.php b/lib/Service/DiffTaskService.php index 16ebb46..0f789ec 100644 --- a/lib/Service/DiffTaskService.php +++ b/lib/Service/DiffTaskService.php @@ -58,7 +58,8 @@ class DiffTaskService { } } - function create(string $relativePathInGroupfolder, int $groupfolderId, string $snapshotId, string $userId, Callable $progressCallback = null): ?DiffTask { + function create(string $relativePathInGroupfolder, int $groupfolderId, string $snapshotId, string $userId, array $folderBlocklist, Callable $progressCallback = null): ?DiffTask { + $parentNode = $this->pathManager->getGroupfolderMountById($groupfolderId)->get($relativePathInGroupfolder); $snapshotPath = $this->pathManager->getGroupFolderSnapshotDirectory($groupfolderId, $relativePathInGroupfolder, $snapshotId); $groupfolderPath = $this->pathManager->getGroupFolderDirectory($groupfolderId, $relativePathInGroupfolder); @@ -80,16 +81,25 @@ class DiffTaskService { $snapshotPath, $groupfolderPath, "", - function(string $type, bool $beforeFileExists, ?string $beforePath, ?int $beforeSize, bool $currentFileExists, ?string $currentPath, ?int $currentSize) use ($task) { + $folderBlocklist, + function(string $type, bool $beforeFileExists, ?string $beforePath, ?int $beforeSize, bool $currentFileExists, ?string $currentPath, ?int $currentSize) use ($task, $parentNode) { $newResult = new DiffTaskResult(); $newResult->setTaskId($task->getId()); $newResult->setType($type); + $newResult->setBeforeFileExists($beforeFileExists); - $newResult->setBeforePath($beforePath); - $newResult->setBeforeSize($beforeSize); + if($beforeFileExists) { + $newResult->setBeforePath($beforePath); + $newResult->setBeforeSize($beforeSize); + } + $newResult->setCurrentFileExists($currentFileExists); - $newResult->setCurrentPath($currentPath); - $newResult->setCurrentSize($currentSize); + if($currentFileExists) { + $newResult->setCurrentFileId($parentNode->get($currentPath)?->getId()); + $newResult->setCurrentPath($currentPath); + $newResult->setCurrentSize($currentSize); + } + $newResult = $this->diffTaskResultMapper->insert($newResult); }, function($numDoneFiles) use ($progressCallback, &$numFiles) { @@ -97,8 +107,7 @@ class DiffTaskService { ($progressCallback)([ "overallFiles" => $numFiles, "doneFiles" => $numDoneFiles, - "progress" => number_format(($numDoneFiles / $numFiles),2), - "progressPercent" => (number_format(($numDoneFiles / $numFiles),2) * 100) . "%", + "progress" => floor(($numDoneFiles / $numFiles) * 100) / 100, ]); } }, @@ -113,7 +122,6 @@ class DiffTaskService { "overallFiles" => $numFiles, "doneFiles" => $numFiles, "progress" => 1.0, - "progressPercent" => "100.00%", "result" => $task, ]); } diff --git a/lib/Service/SettingsService.php b/lib/Service/SettingsService.php index 9e9a56b..9846e84 100644 --- a/lib/Service/SettingsService.php +++ b/lib/Service/SettingsService.php @@ -9,7 +9,7 @@ use OCP\IConfig; class SettingsService { - private static array $VALID_APP_SETTINGS = ["filesystem_mountpoint_path", "filesystem_snapshots_path"]; + private static array $VALID_APP_SETTINGS = ["filesystem_mountpoint_path", "filesystem_snapshots_path", "snapshot_naming_scheme"]; public function __construct(private IConfig $config) { } @@ -28,7 +28,7 @@ class SettingsService { } } - public function setAppValue(string $key, string $value): string { + public function setAppValue(string $key, string $value): string { if(in_array($key, self::$VALID_APP_SETTINGS)) { if($value !== '') { $this->config->setAppValue(Application::APP_ID, $key, $value); @@ -38,5 +38,5 @@ class SettingsService { return $value; } - } + } } \ No newline at end of file diff --git a/lib/Settings/SnapshotsAdmin.php b/lib/Settings/SnapshotsAdmin.php index 24bed92..848cb58 100644 --- a/lib/Settings/SnapshotsAdmin.php +++ b/lib/Settings/SnapshotsAdmin.php @@ -6,21 +6,21 @@ use OCP\Settings\ISettings; class SnapshotsAdmin implements ISettings { - public function __construct() { - } + public function __construct() { + } - /** - * @return TemplateResponse - */ - public function getForm() { - return new TemplateResponse('groupfolder_filesystem_snapshots', 'settings/admin'); - } + /** + * @return TemplateResponse + */ + public function getForm() { + return new TemplateResponse('groupfolder_filesystem_snapshots', 'settings/admin'); + } - public function getSection() { - return 'groupfolder_filesystem_snapshots'; - } + public function getSection() { + return 'groupfolder_filesystem_snapshots'; + } - public function getPriority() { - return 10; - } + public function getPriority() { + return 10; + } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3b99714..fcbb78f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "devDependencies": { "@nextcloud/babel-config": "^1.2.0", "@nextcloud/browserslist-config": "^3.0.1", - "@nextcloud/webpack-vue-config": "^6.0.0" + "@nextcloud/webpack-vue-config": "^5.4.0" }, "engines": { "node": "^16.0.0", @@ -1540,13 +1540,13 @@ } }, "node_modules/@discoveryjs/json-ext": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", - "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true, "peer": true, "engines": { - "node": ">=14.17.0" + "node": ">=10.0.0" } }, "node_modules/@floating-ui/core": { @@ -1635,63 +1635,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/json-pack": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", - "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", - "dev": true, - "peer": true, - "dependencies": { - "@jsonjoy.com/base64": "^1.1.1", - "@jsonjoy.com/util": "^1.1.2", - "hyperdyperid": "^1.2.0", - "thingies": "^1.20.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/util": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.6.0.tgz", - "integrity": "sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", @@ -2053,29 +1996,28 @@ } }, "node_modules/@nextcloud/webpack-vue-config": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@nextcloud/webpack-vue-config/-/webpack-vue-config-6.3.0.tgz", - "integrity": "sha512-Reciadvarap6j3d0arMH34zNiXx6d7B5QXDiosV6ZwDu63mR1lSm4ZUdLr6lv4gfmrADmQ5iP7PQMr99MBeTvw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@nextcloud/webpack-vue-config/-/webpack-vue-config-5.5.1.tgz", + "integrity": "sha512-2Q3kPnsvkKeENG3rruTjAE1oz/9w0u5QMKO8oh9arL2TIO2aswkDKBtkmu6q7Po3tE+3B2f+ggHq1PNkhtwu6w==", "dev": true, - "hasInstallScript": true, "engines": { - "node": "^20.0.0", - "npm": "^9.0.0 || ^10.0.0" + "node": "^16.0.0", + "npm": "^7.0.0 || ^8.0.0" }, "peerDependencies": { - "@babel/core": "^7.22.9", - "babel-loader": "^10.0.0", - "css-loader": "^7.1.1", - "node-polyfill-webpack-plugin": "4.0.0", - "sass": "^1.64.2", - "sass-loader": "^16.0.2", - "style-loader": "^4.0.0", - "ts-loader": "^9.4.4", - "vue": "^2.7.16 || ^3.5.13", - "vue-loader": "^15.11.1 || ^17.4.2", - "webpack": "^5.88.2", - "webpack-cli": "^6.0.1", - "webpack-dev-server": "^5.0.2" + "@babel/core": "^7.19.6", + "babel-loader": "^9.0.0", + "css-loader": "^6.7.1", + "node-polyfill-webpack-plugin": "2.0.1", + "sass": "^1.55.0", + "sass-loader": "^13.1.0", + "style-loader": "^3.3.1", + "vue": "^2.7.13", + "vue-loader": "^15.10.0", + "vue-template-compiler": "^2.7.13", + "webpack": "^5.74.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" } }, "node_modules/@types/body-parser": { @@ -2204,9 +2146,9 @@ "peer": true }, "node_modules/@types/http-proxy": { - "version": "1.17.16", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", - "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", "dev": true, "peer": true, "dependencies": { @@ -2299,9 +2241,9 @@ } }, "node_modules/@types/retry": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true, "peer": true }, @@ -2745,45 +2687,45 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", - "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "dev": true, "peer": true, "engines": { - "node": ">=18.12.0" + "node": ">=14.15.0" }, "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", - "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "dev": true, "peer": true, "engines": { - "node": ">=18.12.0" + "node": ">=14.15.0" }, "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", - "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "dev": true, "peer": true, "engines": { - "node": ">=18.12.0" + "node": ">=14.15.0" }, "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" }, "peerDependenciesMeta": { "webpack-dev-server": { @@ -2856,16 +2798,16 @@ } }, "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "peer": true, "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", + "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, "funding": { "type": "github", @@ -2927,22 +2869,6 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -3029,20 +2955,21 @@ } }, "node_modules/babel-loader": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", - "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", "dev": true, "peer": true, "dependencies": { - "find-up": "^5.0.0" + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" }, "engines": { - "node": "^18.20.0 || ^20.10.0 || >=22.0.0" + "node": ">= 14.15.0" }, "peerDependencies": { "@babel/core": "^7.12.0", - "webpack": ">=5.61.0" + "webpack": ">=5" } }, "node_modules/babel-plugin-polyfill-corejs2": { @@ -3096,6 +3023,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "peer": true + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -3167,9 +3101,9 @@ "peer": true }, "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "peer": true, "dependencies": { @@ -3181,7 +3115,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.13.0", + "qs": "6.11.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -3218,6 +3152,22 @@ "dev": true, "peer": true }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "peer": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/bonjour-service": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", @@ -3451,22 +3401,6 @@ "dev": true, "peer": true }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "dev": true, - "peer": true, - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -3518,23 +3452,6 @@ ], "peer": true }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/char-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", @@ -3634,26 +3551,6 @@ "node": ">=6" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true - }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -3688,6 +3585,13 @@ "dev": true, "peer": true }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true, + "peer": true + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -3744,6 +3648,13 @@ "dev": true, "peer": true }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "peer": true + }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -3813,9 +3724,9 @@ "peer": true }, "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "peer": true, "engines": { @@ -3954,9 +3865,9 @@ } }, "node_modules/css-loader": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", - "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", "dev": true, "peer": true, "dependencies": { @@ -3970,7 +3881,7 @@ "semver": "^7.5.4" }, "engines": { - "node": ">= 18.12.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -3978,7 +3889,7 @@ }, "peerDependencies": { "@rspack/core": "0.x || 1.x", - "webpack": "^5.27.0" + "webpack": "^5.0.0" }, "peerDependenciesMeta": { "@rspack/core": { @@ -4048,6 +3959,13 @@ "resolved": "https://registry.npmjs.org/date-format-parse/-/date-format-parse-0.2.7.tgz", "integrity": "sha512-/+lyMUKoRogMuTeOVii6lUwjbVlesN9YRYLzZT/g3TEZ3uD9QnpjResujeEqUW+OSNbT7T1+SYdyEkTcRv+KDQ==" }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "peer": true + }, "node_modules/debounce": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/debounce/-/debounce-2.2.0.tgz", @@ -4101,34 +4019,17 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/default-browser": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", - "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, "peer": true, "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" + "execa": "^5.0.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", - "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 10" } }, "node_modules/define-data-property": { @@ -4150,16 +4051,13 @@ } }, "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, "peer": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/define-properties": { @@ -4280,13 +4178,13 @@ } }, "node_modules/domain-browser": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-5.7.0.tgz", - "integrity": "sha512-edTFu0M/7wO1pXY6GDxVNVW086uqwWYIHP98txhcPyV995X21JIH2DtYp33sQJOupYoXKe9RwTw2Ya2vWaquTQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", + "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==", "dev": true, "peer": true, "engines": { - "node": ">=4" + "node": ">=10" }, "funding": { "url": "https://bevry.me/fund" @@ -4360,9 +4258,9 @@ } }, "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "peer": true, "engines": { @@ -4384,9 +4282,9 @@ } }, "node_modules/envinfo": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", - "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", + "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", "dev": true, "peer": true, "bin": { @@ -4546,39 +4444,63 @@ "safe-buffer": "^5.1.1" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, "peer": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.3", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.7.1", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~2.0.0", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.3.1", + "finalhandler": "1.2.0", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", + "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", + "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.13.0", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -4587,10 +4509,6 @@ }, "engines": { "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/debug": { @@ -4610,6 +4528,22 @@ "dev": true, "peer": true }, + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "peer": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -4629,23 +4563,6 @@ "dev": true, "peer": true }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "peer": true - }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -4682,15 +4599,25 @@ "node": ">=8" } }, + "node_modules/filter-obj": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", + "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, "peer": true, "dependencies": { "debug": "2.6.9", - "encodeurl": "~2.0.0", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -4718,18 +4645,35 @@ "dev": true, "peer": true }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", "dev": true, "peer": true, "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" }, "engines": { - "node": ">=10" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "peer": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4840,6 +4784,20 @@ "node": ">= 0.6" } }, + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", + "dev": true, + "peer": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "peer": true + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4895,6 +4853,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -4915,6 +4907,30 @@ "dev": true, "peer": true }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -4952,16 +4968,6 @@ "dev": true, "peer": true }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -5120,6 +5126,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "peer": true, + "bin": { + "he": "bin/he" + } + }, "node_modules/highlight.js": { "version": "11.11.1", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", @@ -5186,6 +5202,23 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "peer": true + }, "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -5233,9 +5266,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dev": true, "peer": true, "dependencies": { @@ -5277,14 +5310,14 @@ "dev": true, "peer": true }, - "node_modules/hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "peer": true, "engines": { - "node": ">=10.18" + "node": ">=10.17.0" } }, "node_modules/ical.js": { @@ -5422,6 +5455,16 @@ "node": ">=8" } }, + "node_modules/import-local/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/import-local/node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -5435,6 +5478,17 @@ "node": ">=8" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "peer": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -5540,16 +5594,16 @@ } }, "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "peer": true, "bin": { "is-docker": "cli.js" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5594,25 +5648,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "peer": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-nan": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", @@ -5630,19 +5665,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-network-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", - "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5677,6 +5699,19 @@ "node": ">=0.10.0" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", @@ -5694,19 +5729,16 @@ } }, "node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "peer": true, "dependencies": { - "is-inside-container": "^1.0.0" + "is-docker": "^2.0.0" }, "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/isarray": { @@ -5748,6 +5780,16 @@ "node": ">= 10.13.0" } }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -5885,16 +5927,16 @@ } }, "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, "peer": true, "dependencies": { - "p-locate": "^5.0.0" + "p-locate": "^6.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6132,34 +6174,24 @@ } }, "node_modules/memfs": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", - "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "peer": true, "dependencies": { - "@jsonjoy.com/json-pack": "^1.0.3", - "@jsonjoy.com/util": "^1.3.0", - "tree-dump": "^1.0.1", - "tslib": "^2.0.0" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" } }, "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "peer": true }, "node_modules/merge-source-map": { "version": "1.1.0", @@ -6676,6 +6708,16 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", @@ -6775,39 +6817,40 @@ } }, "node_modules/node-polyfill-webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-4.0.0.tgz", - "integrity": "sha512-WLk77vLpbcpmTekRj6s6vYxk30XoyaY5MDZ4+9g8OaKoG3Ij+TjOqhpQjVUlfDZBPBgpNATDltaQkzuXSnnkwg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-2.0.1.tgz", + "integrity": "sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A==", "dev": true, "peer": true, "dependencies": { - "assert": "^2.1.0", + "assert": "^2.0.0", "browserify-zlib": "^0.2.0", "buffer": "^6.0.3", "console-browserify": "^1.2.0", "constants-browserify": "^1.0.0", "crypto-browserify": "^3.12.0", - "domain-browser": "^5.7.0", + "domain-browser": "^4.22.0", "events": "^3.3.0", + "filter-obj": "^2.0.2", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", "process": "^0.11.10", - "punycode": "^2.3.1", + "punycode": "^2.1.1", "querystring-es3": "^0.2.1", - "readable-stream": "^4.5.2", + "readable-stream": "^4.0.0", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "string_decoder": "^1.3.0", "timers-browserify": "^2.0.12", "tty-browserify": "^0.0.1", - "type-fest": "^4.18.2", - "url": "^0.11.3", - "util": "^0.12.5", + "type-fest": "^2.14.0", + "url": "^0.11.0", + "util": "^0.12.4", "vm-browserify": "^1.1.2" }, "engines": { - "node": ">=14" + "node": ">=12" }, "peerDependencies": { "webpack": ">=5" @@ -6830,6 +6873,19 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -6916,20 +6972,45 @@ "node": ">= 0.8" } }, - "node_modules/open": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", - "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "peer": true, "dependencies": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^3.1.0" + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "peer": true, + "dependencies": { + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">=18" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "peer": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6943,32 +7024,32 @@ "peer": true }, "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dev": true, "peer": true, "dependencies": { - "yocto-queue": "^0.1.0" + "yocto-queue": "^1.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "dev": true, "peer": true, "dependencies": { - "p-limit": "^3.0.2" + "p-limit": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6995,21 +7076,17 @@ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, "node_modules/p-retry": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", - "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, "peer": true, "dependencies": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", + "@types/retry": "0.12.0", "retry": "^0.13.1" }, "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/p-timeout": { @@ -7076,13 +7153,23 @@ "peer": true }, "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "dev": true, "peer": true, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/path-key": { @@ -7103,9 +7190,9 @@ "peer": true }, "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true, "peer": true }, @@ -7144,6 +7231,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "peer": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -7375,9 +7478,9 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", "dev": true, "peer": true, "dependencies": { @@ -7972,6 +8075,22 @@ "node": ">= 4" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -7983,19 +8102,6 @@ "inherits": "^2.0.1" } }, - "node_modules/run-applescript": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", - "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", - "dev": true, - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -8043,30 +8149,30 @@ } }, "node_modules/sass-loader": { - "version": "16.0.5", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", - "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "version": "13.3.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz", + "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==", "dev": true, "peer": true, "dependencies": { "neo-async": "^2.6.2" }, "engines": { - "node": ">= 18.12.0" + "node": ">= 14.15.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "@rspack/core": "0.x || 1.x", + "fibers": ">= 3.1.0", "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", "sass": "^1.3.0", "sass-embedded": "*", "webpack": "^5.0.0" }, "peerDependenciesMeta": { - "@rspack/core": { + "fibers": { "optional": true }, "node-sass": { @@ -8077,16 +8183,13 @@ }, "sass-embedded": { "optional": true - }, - "webpack": { - "optional": true } } }, "node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "peer": true, "dependencies": { @@ -8096,7 +8199,7 @@ "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -8135,9 +8238,9 @@ } }, "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, "peer": true, "dependencies": { @@ -8176,16 +8279,6 @@ "dev": true, "peer": true }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -8290,16 +8383,16 @@ } }, "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, "peer": true, "dependencies": { - "encodeurl": "~2.0.0", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.19.0" + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" @@ -8416,6 +8509,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "peer": true + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -8629,26 +8729,36 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/striptags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.2.0.tgz", "integrity": "sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==" }, "node_modules/style-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", - "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", "dev": true, "peer": true, "engines": { - "node": ">= 18.12.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.27.0" + "webpack": "^5.0.0" } }, "node_modules/style-to-object": { @@ -8659,19 +8769,6 @@ "inline-style-parser": "0.1.1" } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -8807,19 +8904,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/thingies": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", - "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10.18" - }, - "peerDependencies": { - "tslib": "^2" - } - }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -8868,23 +8952,6 @@ "node": ">=0.6" } }, - "node_modules/tree-dump": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.3.tgz", - "integrity": "sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, "node_modules/tributejs": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz", @@ -8908,57 +8975,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ts-loader": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz", - "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==", - "dev": true, - "peer": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "peer": true - }, "node_modules/tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", @@ -8967,13 +8983,13 @@ "peer": true }, "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, "peer": true, "engines": { - "node": ">=16" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8993,20 +9009,6 @@ "node": ">= 0.6" } }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -9468,6 +9470,17 @@ "loader-utils": "^1.0.2" } }, + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "dev": true, + "peer": true, + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, "node_modules/vue-template-es2015-compiler": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", @@ -9568,40 +9581,43 @@ } }, "node_modules/webpack-cli": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", - "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "peer": true, "dependencies": { - "@discoveryjs/json-ext": "^0.6.1", - "@webpack-cli/configtest": "^3.0.1", - "@webpack-cli/info": "^3.0.1", - "@webpack-cli/serve": "^3.0.1", + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", "colorette": "^2.0.14", - "commander": "^12.1.0", + "commander": "^10.0.1", "cross-spawn": "^7.0.3", - "envinfo": "^7.14.0", + "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^3.1.1", "rechoir": "^0.8.0", - "webpack-merge": "^6.0.1" + "webpack-merge": "^5.7.3" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=18.12.0" + "node": ">=14.15.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.82.0" + "webpack": "5.x.x" }, "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, "webpack-bundle-analyzer": { "optional": true }, @@ -9611,93 +9627,89 @@ } }, "node_modules/webpack-cli/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, "peer": true, "engines": { - "node": ">=18" + "node": ">=14" } }, "node_modules/webpack-dev-middleware": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", - "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "peer": true, "dependencies": { "colorette": "^2.0.10", - "memfs": "^4.6.0", + "memfs": "^3.4.3", "mime-types": "^2.1.31", - "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 18.12.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } + "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/webpack-dev-server": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", - "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, "peer": true, "dependencies": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^4.17.21", - "@types/express-serve-static-core": "^4.17.21", - "@types/serve-index": "^1.9.4", - "@types/serve-static": "^1.15.5", - "@types/sockjs": "^0.3.36", - "@types/ws": "^8.5.10", + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.2.1", - "chokidar": "^3.6.0", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", "colorette": "^2.0.10", "compression": "^1.7.4", "connect-history-api-fallback": "^2.0.0", - "express": "^4.21.2", + "default-gateway": "^6.0.3", + "express": "^4.17.3", "graceful-fs": "^4.2.6", - "http-proxy-middleware": "^2.0.9", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "schema-utils": "^4.2.0", - "selfsigned": "^2.4.1", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^7.4.2", - "ws": "^8.18.0" + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { - "node": ">= 18.12.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" + "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { "webpack": { @@ -9709,18 +9721,18 @@ } }, "node_modules/webpack-merge": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, "peer": true, "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", - "wildcard": "^2.0.1" + "wildcard": "^2.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=10.0.0" } }, "node_modules/webpack-sources": { @@ -9854,10 +9866,17 @@ "dev": true, "peer": true }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "peer": true + }, "node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, "peer": true, "engines": { @@ -9894,13 +9913,13 @@ "peer": true }, "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", "dev": true, "peer": true, "engines": { - "node": ">=10" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index 1647848..f4c091a 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,6 @@ "devDependencies": { "@nextcloud/babel-config": "^1.2.0", "@nextcloud/browserslist-config": "^3.0.1", - "@nextcloud/webpack-vue-config": "^6.0.0" + "@nextcloud/webpack-vue-config": "^5.4.0" } } diff --git a/src/AdminSettings.vue b/src/AdminSettings.vue index fd5a7a3..e605975 100644 --- a/src/AdminSettings.vue +++ b/src/AdminSettings.vue @@ -4,12 +4,13 @@ name="Groupfolder Filesystem Snapshots" :limit-width="false">
-
@@ -18,7 +19,7 @@