mirror of https://github.com/FreshRSS/FreshRSS.git
Merge branch 'edge' into auto-update-5038
This commit is contained in:
commit
3e9c8a7d44
|
@ -21,7 +21,7 @@ Example for Linux Debian / Ubuntu:
|
|||
|
||||
```sh
|
||||
# Install default Docker Compose and automatically the corresponding version of Docker
|
||||
apt install docker-compose
|
||||
apt install docker-compose-v2
|
||||
```
|
||||
|
||||
## Quick run
|
||||
|
@ -194,6 +194,8 @@ docker run -d --restart unless-stopped --log-opt max-size=10m \
|
|||
|
||||
In the FreshRSS setup, you will then specify the name of the container (`freshrss-db`) as the host for the database.
|
||||
|
||||
See also the section [Docker Compose with PostgreSQL](#docker-compose-with-postgresql) below.
|
||||
|
||||
### [MySQL](https://hub.docker.com/_/mysql/) or [MariaDB](https://hub.docker.com/_/mariadb)
|
||||
|
||||
```sh
|
||||
|
@ -285,13 +287,13 @@ See [`docker-compose.yml`](./freshrss/docker-compose.yml)
|
|||
```sh
|
||||
cd ./FreshRSS/Docker/freshrss/
|
||||
# Update
|
||||
docker-compose pull
|
||||
docker compose pull
|
||||
# Run
|
||||
docker-compose -f docker-compose.yml -f docker-compose-local.yml up -d --remove-orphans
|
||||
docker compose -f docker-compose.yml -f docker-compose-local.yml up -d --remove-orphans
|
||||
# Logs
|
||||
docker-compose logs -f --timestamps
|
||||
docker compose logs -f --timestamps
|
||||
# Stop
|
||||
docker-compose down --remove-orphans
|
||||
docker compose down --remove-orphans
|
||||
```
|
||||
|
||||
Detailed (partial) example of Docker Compose for FreshRSS:
|
||||
|
@ -378,13 +380,15 @@ See [`docker-compose-db.yml`](./freshrss/docker-compose-db.yml)
|
|||
```sh
|
||||
cd ./FreshRSS/Docker/freshrss/
|
||||
# Update
|
||||
docker-compose -f docker-compose.yml -f docker-compose-db.yml pull
|
||||
docker compose -f docker-compose.yml -f docker-compose-db.yml pull
|
||||
# Run
|
||||
docker-compose -f docker-compose.yml -f docker-compose-db.yml -f docker-compose-local.yml up -d --remove-orphans
|
||||
docker compose -f docker-compose.yml -f docker-compose-db.yml -f docker-compose-local.yml up -d --remove-orphans
|
||||
# Logs
|
||||
docker-compose -f docker-compose.yml -f docker-compose-db.yml logs -f --timestamps
|
||||
docker compose -f docker-compose.yml -f docker-compose-db.yml logs -f --timestamps
|
||||
```
|
||||
|
||||
See also the section [Migrate database](#migrate-database) below to upgrade to a major PostgreSQL version with Docker Compose.
|
||||
|
||||
### Docker Compose for development
|
||||
|
||||
Use the local (git) FreshRSS source code instead of the one inside the Docker container,
|
||||
|
@ -396,11 +400,11 @@ See [`docker-compose-development.yml`](./freshrss/docker-compose-development.yml
|
|||
cd ./FreshRSS/Docker/freshrss/
|
||||
# Update
|
||||
git pull --ff-only --prune
|
||||
docker-compose pull
|
||||
docker compose pull
|
||||
# Run
|
||||
docker-compose -f docker-compose-development.yml -f docker-compose.yml -f docker-compose-local.yml up --remove-orphans
|
||||
docker compose -f docker-compose-development.yml -f docker-compose.yml -f docker-compose-local.yml up --remove-orphans
|
||||
# Stop with [Control]+[C] and purge
|
||||
docker-compose down --remove-orphans --volumes
|
||||
docker compose down --remove-orphans --volumes
|
||||
```
|
||||
|
||||
> ℹ️ You can combine it with `-f docker-compose-db.yml` to spin a PostgreSQL database.
|
||||
|
@ -446,13 +450,13 @@ See [`docker-compose-proxy.yml`](./freshrss/docker-compose-proxy.yml)
|
|||
```sh
|
||||
cd ./FreshRSS/Docker/freshrss/
|
||||
# Update
|
||||
docker-compose -f docker-compose.yml -f docker-compose-proxy.yml pull
|
||||
docker compose -f docker-compose.yml -f docker-compose-proxy.yml pull
|
||||
# Run
|
||||
docker-compose -f docker-compose.yml -f docker-compose-proxy.yml up -d --remove-orphans
|
||||
docker compose -f docker-compose.yml -f docker-compose-proxy.yml up -d --remove-orphans
|
||||
# Logs
|
||||
docker-compose -f docker-compose.yml -f docker-compose-proxy.yml logs -f --timestamps
|
||||
docker compose -f docker-compose.yml -f docker-compose-proxy.yml logs -f --timestamps
|
||||
# Stop
|
||||
docker-compose -f docker-compose.yml -f docker-compose-proxy.yml down --remove-orphans
|
||||
docker compose -f docker-compose.yml -f docker-compose-proxy.yml down --remove-orphans
|
||||
```
|
||||
|
||||
> ℹ️ You can combine it with `-f docker-compose-db.yml` to spin a PostgreSQL database.
|
||||
|
@ -650,3 +654,46 @@ docker run -d --restart unless-stopped --log-opt max-size=10m \
|
|||
--name freshrss_cron freshrss/freshrss:alpine \
|
||||
crond -f -d 6
|
||||
```
|
||||
|
||||
## Migrate database
|
||||
|
||||
Our [CLI](../cli/README.md) offers commands to back-up and migrate user databases,
|
||||
with `cli/db-backup.php` and `cli/db-restore.php` in particular.
|
||||
|
||||
Here is an example (assuming our [Docker Compose example](#docker-compose-with-postgresql))
|
||||
intended for migrating to a newer major version of PostgreSQL,
|
||||
but which can also be used to migrate between other databases (e.g. MySQL to PostgreSQL).
|
||||
|
||||
```sh
|
||||
# Stop FreshRSS container (Web server + cron) during maintenance
|
||||
docker compose down freshrss
|
||||
|
||||
# Optional additional pre-upgrade back-up using PostgreSQL own mechanism
|
||||
docker compose -f docker-compose-db.yml \
|
||||
exec freshrss-db pg_dump -U freshrss freshrss | gzip -9 > freshrss-postgres-backup.sql.gz
|
||||
# ------↑ Name of your PostgreSQL Docker container
|
||||
# -----------------------------↑ Name of your PostgreSQL user for FreshRSS
|
||||
# --------------------------------------↑ Name of your PostgreSQL database for FreshRSS
|
||||
|
||||
# Back-up all users’ respective tables to SQLite files
|
||||
docker compose -f docker-compose.yml -f docker-compose-db.yml \
|
||||
run --rm freshrss cli/db-backup.php
|
||||
|
||||
# Remove old database (PostgreSQL) container and its data volume
|
||||
docker compose -f docker-compose-db.yml \
|
||||
down --volumes freshrss-db
|
||||
|
||||
# Edit your Compose file to use new database (e.g. newest postgres:xx)
|
||||
nano docker-compose-db.yml
|
||||
|
||||
# Start new database (PostgreSQL) container and its new empty data volume
|
||||
docker compose -f docker-compose.yml -f docker-compose-db.yml \
|
||||
up -d freshrss-db
|
||||
|
||||
# Restore all users’ respective tables from SQLite files
|
||||
docker compose -f docker-compose.yml -f docker-compose-db.yml \
|
||||
run --rm freshrss cli/db-restore.php --delete-backup
|
||||
|
||||
# Restart a new FreshRSS container after maintenance
|
||||
docker compose -f docker-compose.yml -f docker-compose-db.yml up -d freshrss
|
||||
```
|
||||
|
|
|
@ -7,7 +7,7 @@ volumes:
|
|||
services:
|
||||
|
||||
traefik:
|
||||
image: traefik:2.11
|
||||
image: traefik:3.0
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
|
|
|
@ -455,8 +455,8 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
|
|||
continue; //When PubSubHubbub is used, do not pull refresh so often
|
||||
}
|
||||
|
||||
if ($feed->mute()) {
|
||||
continue; //Feed refresh is disabled
|
||||
if ($feed->mute() && $feed_id === null) {
|
||||
continue; // If the feed is disabled, only allow refresh if manually requested for that specific feed
|
||||
}
|
||||
$mtime = $feed->cacheModifiedTime() ?: 0;
|
||||
$ttl = $feed->ttl();
|
||||
|
@ -1121,7 +1121,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
|
|||
$feed_id = Minz_Request::paramInt('id');
|
||||
$content_selector = Minz_Request::paramString('selector');
|
||||
|
||||
if (!$content_selector) {
|
||||
if ($content_selector === '') {
|
||||
$this->view->fatalError = _t('feedback.sub.feed.selector_preview.selector_empty');
|
||||
return;
|
||||
}
|
||||
|
@ -1143,11 +1143,12 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
|
|||
|
||||
//Get feed.
|
||||
$feed = $entry->feed();
|
||||
|
||||
if ($feed === null) {
|
||||
$this->view->fatalError = _t('feedback.sub.feed.selector_preview.no_feed');
|
||||
return;
|
||||
}
|
||||
$feed->_pathEntries($content_selector);
|
||||
$feed->_attribute('path_entries_filter', Minz_Request::paramString('selector_filter', true));
|
||||
|
||||
//Fetch & select content.
|
||||
try {
|
||||
|
|
|
@ -48,6 +48,18 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
|
|||
}
|
||||
}
|
||||
|
||||
public function exits(): bool {
|
||||
$sql = 'SELECT * FROM `_entry` LIMIT 1';
|
||||
$stm = $this->pdo->query($sql);
|
||||
if ($stm !== false) {
|
||||
$res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||
if ($res !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function tablesAreCorrect(): bool {
|
||||
$res = $this->fetchAssoc('SHOW TABLES');
|
||||
if ($res == null) {
|
||||
|
@ -261,6 +273,7 @@ SQL;
|
|||
}
|
||||
$error = '';
|
||||
|
||||
$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
|
||||
$userDAO = FreshRSS_Factory::createUserDao();
|
||||
$catDAO = FreshRSS_Factory::createCategoryDao();
|
||||
$feedDAO = FreshRSS_Factory::createFeedDao();
|
||||
|
@ -278,15 +291,18 @@ SQL;
|
|||
$error = 'Error: SQLite import file is not readable: ' . $filename;
|
||||
} elseif ($clearFirst) {
|
||||
$userDAO->deleteUser();
|
||||
$userDAO = FreshRSS_Factory::createUserDao();
|
||||
if ($this->pdo->dbType() === 'sqlite') {
|
||||
//We cannot just delete the .sqlite file otherwise PDO gets buggy.
|
||||
//SQLite is the only one with database-level optimization, instead of at table level.
|
||||
$this->optimize();
|
||||
}
|
||||
} else {
|
||||
$nbEntries = $entryDAO->countUnreadRead();
|
||||
if (!empty($nbEntries['all'])) {
|
||||
$error = 'Error: Destination database already contains some entries!';
|
||||
if ($databaseDAO->exits()) {
|
||||
$nbEntries = $entryDAO->countUnreadRead();
|
||||
if (isset($nbEntries['all']) && $nbEntries['all'] > 0) {
|
||||
$error = 'Error: Destination database already contains some entries!';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -748,11 +748,14 @@ HTML;
|
|||
}
|
||||
|
||||
$content = '';
|
||||
$nodes = $xpath->query((new Gt\CssXPath\Translator($feed->pathEntries()))->asXPath());
|
||||
$cssSelector = htmlspecialchars_decode($feed->pathEntries(), ENT_QUOTES);
|
||||
$cssSelector = trim($cssSelector, ', ');
|
||||
$nodes = $xpath->query((new Gt\CssXPath\Translator($cssSelector))->asXPath());
|
||||
if ($nodes != false) {
|
||||
$path_entries_filter = $feed->attributeString('path_entries_filter');
|
||||
$path_entries_filter = $feed->attributeString('path_entries_filter') ?? '';
|
||||
$path_entries_filter = trim($path_entries_filter, ', ');
|
||||
foreach ($nodes as $node) {
|
||||
if ($path_entries_filter != null) {
|
||||
if ($path_entries_filter !== '') {
|
||||
$filterednodes = $xpath->query((new Gt\CssXPath\Translator($path_entries_filter))->asXPath(), $node) ?: [];
|
||||
foreach ($filterednodes as $filterednode) {
|
||||
if ($filterednode->parentNode === null) {
|
||||
|
|
|
@ -48,6 +48,8 @@ class FreshRSS_UserQuery {
|
|||
$this->labels = $labels;
|
||||
if (isset($query['get'])) {
|
||||
$this->parseGet($query['get']);
|
||||
} else {
|
||||
$this->get_type = 'all';
|
||||
}
|
||||
if (isset($query['name'])) {
|
||||
$this->name = trim($query['name']);
|
||||
|
@ -107,7 +109,9 @@ class FreshRSS_UserQuery {
|
|||
*/
|
||||
private function parseGet(string $get): void {
|
||||
$this->get = $get;
|
||||
if (preg_match('/(?P<type>[acfistT])(_(?P<id>\d+))?/', $get, $matches)) {
|
||||
if ($this->get === '') {
|
||||
$this->get_type = 'all';
|
||||
} elseif (preg_match('/(?P<type>[acfistT])(_(?P<id>\d+))?/', $get, $matches)) {
|
||||
$id = intval($matches['id'] ?? '0');
|
||||
switch ($matches['type']) {
|
||||
case 'a':
|
||||
|
@ -155,22 +159,22 @@ class FreshRSS_UserQuery {
|
|||
|
||||
/**
|
||||
* Check if the user query has parameters.
|
||||
* If the type is 'all', it is considered equal to no parameters
|
||||
*/
|
||||
public function hasParameters(): bool {
|
||||
if ($this->get_type === 'all') {
|
||||
return false;
|
||||
if ($this->get_type !== 'all') {
|
||||
return true;
|
||||
}
|
||||
if ($this->hasSearch()) {
|
||||
return true;
|
||||
}
|
||||
if ($this->state) {
|
||||
if (!in_array($this->state, [
|
||||
0,
|
||||
FreshRSS_Entry::STATE_READ | FreshRSS_Entry::STATE_NOT_READ,
|
||||
FreshRSS_Entry::STATE_READ | FreshRSS_Entry::STATE_NOT_READ | FreshRSS_Entry::STATE_FAVORITE | FreshRSS_Entry::STATE_NOT_FAVORITE
|
||||
], true)) {
|
||||
return true;
|
||||
}
|
||||
if ($this->order) {
|
||||
return true;
|
||||
}
|
||||
if ($this->get) {
|
||||
if ($this->order !== '' && $this->order !== FreshRSS_Context::userConf()->sort_order) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -154,7 +154,7 @@ class FreshRSS_Export_Service {
|
|||
$zip_filename = 'freshrss_' . $this->username . '_' . $day . '_export.zip';
|
||||
|
||||
// From https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly
|
||||
$zip_file = tempnam('/tmp', 'zip');
|
||||
$zip_file = tempnam(TMP_PATH, 'zip');
|
||||
if ($zip_file == false) {
|
||||
return [$zip_filename, false];
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
?><div class="dropdown no-mobile">
|
||||
<div class="dropdown-target"></div><a class="dropdown-toggle" data-fweb="<?= $feed->website() ?>"><?= _i('configure') ?></a><?php /* feed_config_template */ ?>
|
||||
</div><?php
|
||||
if (FreshRSS_Context::userConf()->show_favicons) { ?><img class="favicon test" src="<?= $feed->favicon() ?>" alt="✇" loading="lazy" /><?php }
|
||||
if (FreshRSS_Context::userConf()->show_favicons) { ?><img class="favicon" src="<?= $feed->favicon() ?>" alt="✇" loading="lazy" /><?php }
|
||||
endif;
|
||||
?><a class="item-title" data-unread="<?= format_number($feed->nbNotRead()) ?>" href="<?=
|
||||
_url('index', $actual_view, 'get', 'f_' . $feed->id()) . $state_filter_manual ?>"><?= $feed->name() ?></a></li>
|
||||
|
|
|
@ -121,6 +121,14 @@ cd /usr/share/FreshRSS
|
|||
```sh
|
||||
cd /usr/share/FreshRSS
|
||||
|
||||
./cli/db-backup.php
|
||||
# Back-up all users respective database to `data/users/*/backup.sqlite`
|
||||
|
||||
./cli/db-restore.php --delete-backup --force-overwrite
|
||||
# Restore all users respective database from `data/users/*/backup.sqlite`
|
||||
# --delete-backup: delete `data/users/*/backup.sqlite` after successful import
|
||||
# --force-overwrite: will clear the users respective database before import
|
||||
|
||||
./cli/db-optimize.php --user username
|
||||
# Optimize database (reduces the size) for a given user (perform `OPTIMIZE TABLE` in MySQL, `VACUUM` in SQLite)
|
||||
```
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::systemConf()->db['type'] ?? '');
|
||||
$ok = true;
|
||||
|
||||
foreach (listUsers() as $username) {
|
||||
$username = cliInitUser($username);
|
||||
$filename = DATA_PATH . '/users/' . $username . '/backup.sqlite';
|
||||
@unlink($filename);
|
||||
|
||||
echo 'FreshRSS backup database to SQLite for user “', $username, "”…\n";
|
||||
|
||||
$databaseDAO = FreshRSS_Factory::createDatabaseDAO($username);
|
||||
$ok &= $databaseDAO->dbCopy($filename, FreshRSS_DatabaseDAO::SQLITE_EXPORT);
|
||||
}
|
||||
|
||||
done((bool)$ok);
|
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::systemConf()->db['type'] ?? '');
|
||||
|
||||
$cliOptions = new class extends CliOptionsParser {
|
||||
public string $deleteBackup;
|
||||
public string $forceOverwrite;
|
||||
|
||||
public function __construct() {
|
||||
$this->addOption('deleteBackup', (new CliOption('delete-backup'))->withValueNone());
|
||||
$this->addOption('forceOverwrite', (new CliOption('force-overwrite'))->withValueNone());
|
||||
parent::__construct();
|
||||
}
|
||||
};
|
||||
|
||||
if (!empty($cliOptions->errors)) {
|
||||
fail('FreshRSS error: ' . array_shift($cliOptions->errors) . "\n" . $cliOptions->usage);
|
||||
}
|
||||
|
||||
FreshRSS_Context::initSystem(true);
|
||||
Minz_User::change(Minz_User::INTERNAL_USER);
|
||||
$ok = false;
|
||||
try {
|
||||
$error = initDb();
|
||||
if ($error != '') {
|
||||
$_SESSION['bd_error'] = $error;
|
||||
} else {
|
||||
$ok = true;
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
$_SESSION['bd_error'] = $ex->getMessage();
|
||||
}
|
||||
if (!$ok) {
|
||||
fail('FreshRSS database error: ' . (empty($_SESSION['bd_error']) ? 'Unknown error' : $_SESSION['bd_error']));
|
||||
}
|
||||
|
||||
foreach (listUsers() as $username) {
|
||||
$username = cliInitUser($username);
|
||||
$filename = DATA_PATH . "/users/{$username}/backup.sqlite";
|
||||
if (!file_exists($filename)) {
|
||||
fwrite(STDERR, "FreshRSS SQLite backup not found for user “{$username}”!\n");
|
||||
$ok = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
echo 'FreshRSS restore database from SQLite for user “', $username, "”…\n";
|
||||
|
||||
$databaseDAO = FreshRSS_Factory::createDatabaseDAO($username);
|
||||
$clearFirst = isset($cliOptions->forceOverwrite);
|
||||
$ok &= $databaseDAO->dbCopy($filename, FreshRSS_DatabaseDAO::SQLITE_IMPORT, $clearFirst);
|
||||
if ($ok) {
|
||||
if (isset($cliOptions->deleteBackup)) {
|
||||
unlink($filename);
|
||||
}
|
||||
} else {
|
||||
fwrite(STDERR, "FreshRSS database already exists for user “{$username}”!\n");
|
||||
fwrite(STDERR, "If you would like to clear the user database first, use the option --force-overwrite\n");
|
||||
}
|
||||
invalidateHttpCache($username);
|
||||
}
|
||||
|
||||
done((bool)$ok);
|
|
@ -314,16 +314,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.10.66",
|
||||
"version": "1.10.67",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "94779c987e4ebd620025d9e5fdd23323903950bd"
|
||||
"reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/94779c987e4ebd620025d9e5fdd23323903950bd",
|
||||
"reference": "94779c987e4ebd620025d9e5fdd23323903950bd",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/16ddbe776f10da6a95ebd25de7c1dbed397dc493",
|
||||
"reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -366,13 +366,9 @@
|
|||
{
|
||||
"url": "https://github.com/phpstan",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-28T16:17:31+00:00"
|
||||
"time": "2024-04-16T07:22:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
|
@ -428,16 +424,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-strict-rules",
|
||||
"version": "1.5.3",
|
||||
"version": "1.5.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
|
||||
"reference": "568210bd301f94a0d4b1e5a0808c374c1b9cf11b"
|
||||
"reference": "2e193a07651a6f4be3baa44ddb21d822681f5918"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/568210bd301f94a0d4b1e5a0808c374c1b9cf11b",
|
||||
"reference": "568210bd301f94a0d4b1e5a0808c374c1b9cf11b",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/2e193a07651a6f4be3baa44ddb21d822681f5918",
|
||||
"reference": "2e193a07651a6f4be3baa44ddb21d822681f5918",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -471,9 +467,9 @@
|
|||
"description": "Extra strict and opinionated rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
|
||||
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.3"
|
||||
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.5"
|
||||
},
|
||||
"time": "2024-04-06T07:43:25+00:00"
|
||||
"time": "2024-04-19T15:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
|
@ -1862,16 +1858,16 @@
|
|||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "3.9.1",
|
||||
"version": "3.9.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
|
||||
"reference": "267a4405fff1d9c847134db3a3c92f1ab7f77909"
|
||||
"reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/267a4405fff1d9c847134db3a3c92f1ab7f77909",
|
||||
"reference": "267a4405fff1d9c847134db3a3c92f1ab7f77909",
|
||||
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/aac1f6f347a5c5ac6bc98ad395007df00990f480",
|
||||
"reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1938,7 +1934,7 @@
|
|||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-31T21:03:09+00:00"
|
||||
"time": "2024-04-23T20:25:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
|
@ -2028,5 +2024,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "7.4"
|
||||
},
|
||||
"plugin-api-version": "2.3.0"
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
|
|
@ -11,19 +11,32 @@ Learn how to install, update, and backup FreshRSS, as well as how to use the com
|
|||
|
||||
## Tutorials and Examples
|
||||
|
||||
* [User management](12_User_management.md)
|
||||
### General
|
||||
|
||||
* [Backing up FreshRSS](05_Backup.md)
|
||||
* [Installing and managing extensions](15_extensions.md)
|
||||
* [Installing themes](11_Themes.md)
|
||||
* [Setting Up Automatic Feed Updating](08_FeedUpdates.md)
|
||||
* [Database configuration](DatabaseConfig.md)
|
||||
* [Using the command line interface (CLI)](https://github.com/FreshRSS/FreshRSS/tree/edge/cli)
|
||||
* [Configuration without an user interface](17_configs_not_ui.md)
|
||||
* [Frequently asked questions](04_Frequently_Asked_Questions.md)
|
||||
|
||||
### User access
|
||||
|
||||
* [User management](12_User_management.md)
|
||||
* [Access Control](09_AccessControl.md)
|
||||
* [OpenID Connect](16_OpenID-Connect.md)
|
||||
* [Configuring the email address validation](05_Configuring_email_validation.md)
|
||||
|
||||
### Web server configuration
|
||||
|
||||
* [Apache/Nginx configuration files](10_ServerConfig.md)
|
||||
* [Reverse proxy with Caddy](Caddy.md)
|
||||
|
||||
### Special server information
|
||||
|
||||
* [Installation on Debian 9/Ubuntu 16.04](06_LinuxInstall.md)
|
||||
* [Installation on Cloud Providers](14_CloudProviders.md)
|
||||
* [Updating on Debian 9/Ubuntu 16.04](07_LinuxUpdate.md)
|
||||
* [Setting Up Automatic Feed Updating](08_FeedUpdates.md)
|
||||
* [Access Control](09_AccessControl.md)
|
||||
* [OpenID Connect](16_OpenID-Connect.md)
|
||||
* [Apache/Nginx configuration files](10_ServerConfig.md)
|
||||
* [Database configuration](DatabaseConfig.md)
|
||||
* [Using the command line interface (CLI)](https://github.com/FreshRSS/FreshRSS/tree/edge/cli)
|
||||
* [Configuring the email address validation](05_Configuring_email_validation.md)
|
||||
* [Reverse proxy with Caddy](Caddy.md)
|
||||
* [Frequently asked questions](04_Frequently_Asked_Questions.md)
|
||||
|
||||
|
|
|
@ -10,9 +10,19 @@ Do this before an upgrade.
|
|||
|
||||
This following tutorial demonstrates commands for backing up FreshRSS. It assumes that your main FreshRSS directory is `/usr/share/FreshRSS`. If you’ve installed it somewhere else, substitute your path as necessary.
|
||||
|
||||
### Creating a database backup
|
||||
|
||||
Back-up all users respective database to `data/users/*/backup.sqlite`
|
||||
|
||||
```sh
|
||||
cd /usr/share/FreshRSS/
|
||||
./cli/db-backup.php
|
||||
```
|
||||
|
||||
### Creating a Backup of all Files
|
||||
|
||||
First, Enter the directory you wish to save your backup to. Here, for example, we’ll save the backup to the user home directory
|
||||
Enter the directory you wish to save your backup to.
|
||||
Here, for example, we’ll save the backup to the user home directory
|
||||
|
||||
```sh
|
||||
cd ~
|
||||
|
@ -52,7 +62,39 @@ And optionally, as cleanup, remove the copy of your backup from the FreshRSS dir
|
|||
rm FreshRSS-backup.tgz
|
||||
```
|
||||
|
||||
## Backing up Feeds
|
||||
### Restore a database backup
|
||||
|
||||
> ℹ️ It is safer to stop your Web server and cron during maintenance operations.
|
||||
|
||||
Restore all users respective database from `data/users/*/backup.sqlite`
|
||||
|
||||
```sh
|
||||
cd /usr/share/FreshRSS/
|
||||
./cli/db-restore.php --delete-backup --force-overwrite
|
||||
```
|
||||
|
||||
## Migrate database
|
||||
|
||||
Start by making an automatic backup of the all the user databases to SQLite files:
|
||||
|
||||
```sh
|
||||
cd /usr/share/FreshRSS/
|
||||
./cli/db-backup.php
|
||||
```
|
||||
|
||||
Change your database setup:
|
||||
- if you like to change database type (e.g. from MySQL to PostgreSQL), edit `data/config.php` accordingly.
|
||||
- if you upgrade to a major PostgreSQL version, after a PostgreSQL backup, you may delete the old instance and start a new instance (remove the PostgreSQL volume if using Docker).
|
||||
|
||||
Restore all the user databases from the SQLite files:
|
||||
|
||||
```sh
|
||||
./cli/db-restore.php --delete-backup --force-overwrite
|
||||
```
|
||||
|
||||
See also our [Docker documentation to migrate database](https://github.com/FreshRSS/FreshRSS/blob/edge/Docker/README.md#migrate-database).
|
||||
|
||||
## Backing up selected content
|
||||
|
||||
### Feed list Export
|
||||
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
# System Configurations without an User Interface
|
||||
|
||||
Most of configurations are available in the user interface.
|
||||
|
||||
Here is an overview of not available configs
|
||||
|
||||
## System wide configuration
|
||||
|
||||
see `./config.default.php` for all options. This file is very well documented.
|
||||
|
||||
Do not modify this file, which defines default values,
|
||||
but instead edit `./data/config.php` after the install process is completed,
|
||||
or edit `./data/config.custom.php` before the install process.
|
||||
|
||||
### Some selected options
|
||||
|
||||
#### System config: environment
|
||||
|
||||
(recommended) `'production'`: Does not PHP error messages within the application, just in the error log.
|
||||
|
||||
`'development'`: Displays PHP error messages within the application not just in the error log. Useful for code writing and testing. Use it on your secure development environment. Do not use it on production systems.
|
||||
|
||||
It does not have any effect for choosing the release channels.
|
||||
|
||||
`'environment'` default value `'production'`
|
||||
|
||||
#### System config: base_url
|
||||
|
||||
This option is displayed in Administration -> System configuration, but is not editable there.
|
||||
|
||||
This settings needs to be changed after moving the FreshRSS application from one server to another.
|
||||
|
||||
`'base_url'` value will be set while install process and depends on your server environment.
|
||||
|
||||
#### System config: logo_html
|
||||
|
||||
Replace the FreshRSS logo in the user interface with an own HTML code that includes the `<img>` tag as well.
|
||||
|
||||
It is rendered inside an `<a>...</a>` element and must be valid HTML or text.
|
||||
|
||||
It does not replace the FreshRSS logo as favicon, in the browser notification, and shortcut icon.
|
||||
|
||||
`'logo_html'` default value `''`
|
||||
|
||||
Example: `'<img class="logo" src="https://example.net/Hello.png" alt="Logo Example" /> Hello'`
|
||||
|
||||
#### System config: Sending an email
|
||||
|
||||
See the documentation directly in the source code `config.default.php`
|
||||
|
||||
## Application wide constants
|
||||
|
||||
See `./constants.php`. Do not edit this file. Create/edit `./constants.local.php` instead.
|
||||
|
||||
Some constants cannot be `update safe` changed. They are marked with `Not customisable`
|
||||
|
||||
### Example of constants.local.php
|
||||
|
||||
``` php
|
||||
<?php
|
||||
define('CLEANCACHE_HOURS', 100);
|
||||
```
|
||||
|
||||
File name: `constants.local.php`
|
||||
|
||||
Location: root directory of FreshRSS
|
||||
|
||||
### Some selected constants
|
||||
|
||||
#### Application constant: FRESHRSS_USERAGENT
|
||||
|
||||
FreshRSS has a default user agent string that can be overwritten in each feed setting.
|
||||
|
||||
`'FRESHRSS_USERAGENT'` default value starts with `'FreshRSS/'` and the FreshRSS version, used operating system and link to FreshRSS website.
|
||||
|
||||
|
||||
#### Application constant: CLEANCACHE_HOURS
|
||||
|
||||
FreshRSS keeps feeds and fetched websites as `.spc` or `.html` file in `./data/cache` for a limited time. In some cases the storage could use a lot of storage space. Reducing the clean cache hours reduces the space.
|
||||
|
||||
`'CLEANCACHE_HOURS'` default value `720` (hours = 30 days)
|
||||
|
||||
|
||||
## User wide configuration
|
||||
|
||||
Available for each user in `config.php` in `./data/users/username`. Edit there. Do not edit `./config-user.default.php` (it will be overwritten by the next system update and overruled by the user config file).
|
||||
|
||||
|
||||
### User: simplify_over_n_feeds
|
||||
|
||||
Advanced property to automatically simplify the layout when there are many (1k+) feeds so that FreshRSS works out of the box with 20k+ feeds scenarios
|
||||
|
||||
`'simplify_over_n_feeds'` default value: `1000`
|
|
@ -49,7 +49,7 @@ To set up FreshRSS behind a reverse proxy with Caddy and using a subfolder, foll
|
|||
Restart FreshRSS to ensure that it recognizes the new base URL:
|
||||
|
||||
```bash
|
||||
docker-compose restart freshrss
|
||||
docker compose restart freshrss
|
||||
```
|
||||
|
||||
4. **Access FreshRSS:**
|
||||
|
|
|
@ -1286,10 +1286,6 @@ a.website:hover .favicon {
|
|||
z-index: 2;
|
||||
}
|
||||
|
||||
.flux:not(.current):hover .flux_header .item .date {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.flux:not(.current):hover .item .title {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
|
|
@ -1286,10 +1286,6 @@ a.website:hover .favicon {
|
|||
z-index: 2;
|
||||
}
|
||||
|
||||
.flux:not(.current):hover .flux_header .item .date {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.flux:not(.current):hover .item .title {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
"name": "freshrss",
|
||||
"license": "AGPL-3.0",
|
||||
"devDependencies": {
|
||||
"@stylistic/stylelint-plugin": "^2.1.1",
|
||||
"@stylistic/stylelint-plugin": "^2.1.2",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-standard": "^17.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-n": "^16.6.2",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"markdownlint-cli": "^0.39.0",
|
||||
"markdownlint-cli": "^0.40.0",
|
||||
"rtlcss": "^4.1.1",
|
||||
"sass": "^1.74.1",
|
||||
"stylelint": "^16.3.1",
|
||||
"sass": "^1.76.0",
|
||||
"stylelint": "^16.4.0",
|
||||
"stylelint-config-recommended-scss": "^14.0.0",
|
||||
"stylelint-order": "^6.0.4"
|
||||
},
|
||||
|
@ -416,19 +416,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@stylistic/stylelint-plugin": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-2.1.1.tgz",
|
||||
"integrity": "sha512-xqHTmQZN7EbnFDW7jw0rAsdFNO4IRqvXhrh3qhUlIwF/x09Zm7kgs/ADktHxsTJYcw346PpGihsB0t4pZhpeHw==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-2.1.2.tgz",
|
||||
"integrity": "sha512-JsSqu0Y3vsX+PBl+DwULxC0cIv9C1yIcq1MXkx7pBOGtTqU26a75I8MPYMiEYvrsXgsKLi65xVgy1iLVSZquJA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@csstools/css-parser-algorithms": "^2.5.0",
|
||||
"@csstools/css-tokenizer": "^2.2.3",
|
||||
"@csstools/media-query-list-parser": "^2.1.7",
|
||||
"@csstools/css-parser-algorithms": "^2.6.1",
|
||||
"@csstools/css-tokenizer": "^2.2.4",
|
||||
"@csstools/media-query-list-parser": "^2.1.9",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"postcss-selector-parser": "^6.0.15",
|
||||
"postcss-selector-parser": "^6.0.16",
|
||||
"postcss-value-parser": "^4.2.0",
|
||||
"style-search": "^0.1.0",
|
||||
"stylelint": "^16.2.1"
|
||||
"stylelint": "^16.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12 || >=20.9"
|
||||
|
@ -869,12 +869,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz",
|
||||
"integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
|
@ -924,9 +924,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/css-functions-list": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz",
|
||||
"integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz",
|
||||
"integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12 || >=16"
|
||||
|
@ -2698,6 +2698,15 @@
|
|||
"integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/jsonpointer": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz",
|
||||
"integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
|
@ -2787,9 +2796,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.0.0.tgz",
|
||||
"integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==",
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
|
@ -2797,20 +2806,20 @@
|
|||
"linkify-it": "^5.0.0",
|
||||
"mdurl": "^2.0.0",
|
||||
"punycode.js": "^2.3.1",
|
||||
"uc.micro": "^2.0.0"
|
||||
"uc.micro": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/markdownlint": {
|
||||
"version": "0.33.0",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.33.0.tgz",
|
||||
"integrity": "sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==",
|
||||
"version": "0.34.0",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz",
|
||||
"integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"markdown-it": "14.0.0",
|
||||
"markdownlint-micromark": "0.1.8"
|
||||
"markdown-it": "14.1.0",
|
||||
"markdownlint-micromark": "0.1.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
@ -2820,20 +2829,22 @@
|
|||
}
|
||||
},
|
||||
"node_modules/markdownlint-cli": {
|
||||
"version": "0.39.0",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.39.0.tgz",
|
||||
"integrity": "sha512-ZuFN7Xpsbn1Nbp0YYkeLOfXOMOfLQBik2lKRy8pVI/llmKQ2uW7x+8k5OMgF6o7XCsTDSYC/OOmeJ+3qplvnJQ==",
|
||||
"version": "0.40.0",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.40.0.tgz",
|
||||
"integrity": "sha512-JXhI3dRQcaqwiFYpPz6VJ7aKYheD53GmTz9y4D/d0F1MbZDGOp9pqKlbOfUX/pHP/iAoeiE4wYRmk8/kjLakxA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"commander": "~11.1.0",
|
||||
"commander": "~12.0.0",
|
||||
"get-stdin": "~9.0.0",
|
||||
"glob": "~10.3.10",
|
||||
"ignore": "~5.3.0",
|
||||
"glob": "~10.3.12",
|
||||
"ignore": "~5.3.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jsonc-parser": "~3.2.1",
|
||||
"markdownlint": "~0.33.0",
|
||||
"minimatch": "~9.0.3",
|
||||
"run-con": "~1.3.2"
|
||||
"jsonpointer": "5.0.1",
|
||||
"markdownlint": "~0.34.0",
|
||||
"minimatch": "~9.0.4",
|
||||
"run-con": "~1.3.2",
|
||||
"toml": "~3.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"markdownlint": "markdownlint.js"
|
||||
|
@ -2867,12 +2878,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/markdownlint-micromark": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.8.tgz",
|
||||
"integrity": "sha512-1ouYkMRo9/6gou9gObuMDnvZM8jC/ly3QCFQyoSPCS2XV1ZClU0xpKbL1Ar3bWWRT1RnBZkWUEiNKrI2CwiBQA==",
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz",
|
||||
"integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/DavidAnson"
|
||||
|
@ -3637,9 +3648,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.75.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz",
|
||||
"integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==",
|
||||
"version": "1.76.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.76.0.tgz",
|
||||
"integrity": "sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
|
@ -3947,20 +3958,20 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/stylelint": {
|
||||
"version": "16.3.1",
|
||||
"resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.3.1.tgz",
|
||||
"integrity": "sha512-/JOwQnBvxEKOT2RtNgGpBVXnCSMBgKOL2k7w0K52htwCyJls4+cHvc4YZgXlVoAZS9QJd2DgYAiRnja96pTgxw==",
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.4.0.tgz",
|
||||
"integrity": "sha512-uSx7VMuXwLuYcNSIg+0/fFNv0WinsfLAqsVVy7h7p80clKOHiGE8pfY6UjqwylTHiJrRIahTl6a8FPxGezhWoA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@csstools/css-parser-algorithms": "^2.6.1",
|
||||
"@csstools/css-tokenizer": "^2.2.4",
|
||||
"@csstools/media-query-list-parser": "^2.1.9",
|
||||
"@csstools/selector-specificity": "^3.0.2",
|
||||
"@csstools/selector-specificity": "^3.0.3",
|
||||
"@dual-bundle/import-meta-resolve": "^4.0.0",
|
||||
"balanced-match": "^2.0.0",
|
||||
"colord": "^2.9.3",
|
||||
"cosmiconfig": "^9.0.0",
|
||||
"css-functions-list": "^3.2.1",
|
||||
"css-functions-list": "^3.2.2",
|
||||
"css-tree": "^2.3.1",
|
||||
"debug": "^4.3.4",
|
||||
"fast-glob": "^3.3.2",
|
||||
|
@ -3989,7 +4000,7 @@
|
|||
"strip-ansi": "^7.1.0",
|
||||
"supports-hyperlinks": "^3.0.0",
|
||||
"svg-tags": "^1.0.0",
|
||||
"table": "^6.8.1",
|
||||
"table": "^6.8.2",
|
||||
"write-file-atomic": "^5.0.1"
|
||||
},
|
||||
"bin": {
|
||||
|
@ -4294,6 +4305,12 @@
|
|||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/toml": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
|
||||
"integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tsconfig-paths": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
|
||||
|
|
|
@ -38,13 +38,13 @@
|
|||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-n": "^16.6.2",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"markdownlint-cli": "^0.39.0",
|
||||
"markdownlint-cli": "^0.40.0",
|
||||
"rtlcss": "^4.1.1",
|
||||
"sass": "^1.74.1",
|
||||
"stylelint": "^16.3.1",
|
||||
"sass": "^1.76.0",
|
||||
"stylelint": "^16.4.0",
|
||||
"stylelint-config-recommended-scss": "^14.0.0",
|
||||
"stylelint-order": "^6.0.4",
|
||||
"@stylistic/stylelint-plugin": "^2.1.1"
|
||||
"@stylistic/stylelint-plugin": "^2.1.2"
|
||||
},
|
||||
"rtlcssConfig": {}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue