Compare commits
1 Commits
renovate/e
...
3875ac299c
Author | SHA1 | Date | |
---|---|---|---|
3875ac299c |
10
.drone.yml
10
.drone.yml
@ -38,7 +38,6 @@ steps:
|
|||||||
- cd moneymgr_backend
|
- cd moneymgr_backend
|
||||||
- rustup component add clippy
|
- rustup component add clippy
|
||||||
- cargo clippy -- -D warnings
|
- cargo clippy -- -D warnings
|
||||||
- cargo clippy --example api_curl -- -D warnings
|
|
||||||
|
|
||||||
- name: backend_test
|
- name: backend_test
|
||||||
image: rust
|
image: rust
|
||||||
@ -52,7 +51,7 @@ steps:
|
|||||||
- cargo test
|
- cargo test
|
||||||
|
|
||||||
|
|
||||||
- name: backend_build
|
- name: backend_compile
|
||||||
image: rust
|
image: rust
|
||||||
volumes:
|
volumes:
|
||||||
- name: rust_registry
|
- name: rust_registry
|
||||||
@ -68,16 +67,15 @@ steps:
|
|||||||
- cd moneymgr_backend
|
- cd moneymgr_backend
|
||||||
- mv /tmp/web_build/dist static
|
- mv /tmp/web_build/dist static
|
||||||
- cargo build --release
|
- cargo build --release
|
||||||
- cargo build --release --example api_curl
|
- ls -lah target/release/moneymgr_backend
|
||||||
- ls -lah target/release/moneymgr_backend target/release/examples/api_curl
|
- cp target/release/moneymgr_backend /tmp/release
|
||||||
- cp target/release/moneymgr_backend target/release/examples/api_curl /tmp/release
|
|
||||||
|
|
||||||
|
|
||||||
# Release
|
# Release
|
||||||
- name: gitea_release
|
- name: gitea_release
|
||||||
image: plugins/gitea-release
|
image: plugins/gitea-release
|
||||||
depends_on:
|
depends_on:
|
||||||
- backend_build
|
- backend_compile
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
- tag
|
- tag
|
||||||
|
38
README.md
38
README.md
@ -3,46 +3,10 @@
|
|||||||
|
|
||||||
Open Source web-based personal expenses tool.
|
Open Source web-based personal expenses tool.
|
||||||
|
|
||||||
**Note :** This project does not handle authentication itself. Instead, it relies on OpenID to achieve users authentication.
|
|
||||||
|
|
||||||
## Setup prod env
|
|
||||||
1. Install prerequisites:
|
|
||||||
1. docker
|
|
||||||
2. docker compose
|
|
||||||
3. git
|
|
||||||
|
|
||||||
2. Clone this git repository:
|
|
||||||
```bash
|
|
||||||
git clone https://gitea.communiquons.org/pierre/MoneyMgr
|
|
||||||
cd MoneyMgr/docker_prod
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Copy and adapt env values
|
|
||||||
```bash
|
|
||||||
cp .env.sample .env
|
|
||||||
nano .env
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Create required directories:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
mkdir -p storage/{db,redis-data,redis-conf,minio}
|
|
||||||
```
|
|
||||||
|
|
||||||
5. Start containers
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose up
|
|
||||||
```
|
|
||||||
|
|
||||||
6. Checkout http://localhost:8000/
|
|
||||||
|
|
||||||
> The default credentials are `admin` / `admin`
|
|
||||||
|
|
||||||
## Setup dev env
|
## Setup dev env
|
||||||
1. Install prerequisites:
|
1. Install prerequisites:
|
||||||
1. docker
|
1. docker
|
||||||
2. docker compose
|
2. docker-compose
|
||||||
3. rust
|
3. rust
|
||||||
4. node
|
4. node
|
||||||
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
MINIO_ROOT_USER=rootuser
|
|
||||||
MINIO_ROOT_PASSWORD=rootpassword
|
|
||||||
DB_USER=db_user
|
|
||||||
DB_PASSWORD=db_password
|
|
||||||
REDIS_PASS=redis_password
|
|
||||||
WEBSITE_ORIGIN=http://localhost:8000
|
|
||||||
APP_SECRET=secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret
|
|
||||||
AUTH_SECRET_KEY=secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret
|
|
||||||
OIDC_CLIENT_ID=bar
|
|
||||||
OIDC_CLIENT_SECRET=foo
|
|
3
docker_prod/.gitignore
vendored
3
docker_prod/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
.env
|
|
||||||
storage
|
|
||||||
auth/users.json
|
|
@ -1,5 +0,0 @@
|
|||||||
- id: ${OIDC_CLIENT_ID}
|
|
||||||
name: MoneyMgr
|
|
||||||
description: Money management tool
|
|
||||||
secret: ${OIDC_CLIENT_SECRET}
|
|
||||||
redirect_uri: ${APP_ORIGIN}/oidc_cb
|
|
@ -1,79 +0,0 @@
|
|||||||
services:
|
|
||||||
minio:
|
|
||||||
image: minio/minio
|
|
||||||
user: "1000"
|
|
||||||
environment:
|
|
||||||
- MINIO_ROOT_USER=$MINIO_ROOT_USER
|
|
||||||
- MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD
|
|
||||||
volumes:
|
|
||||||
- ./storage/minio:/data
|
|
||||||
command: [ "minio", "server", "/data", "--console-address", ":9090" ]
|
|
||||||
ports:
|
|
||||||
- 9000:9000
|
|
||||||
- 9090:9090
|
|
||||||
expose:
|
|
||||||
- 9000
|
|
||||||
|
|
||||||
db:
|
|
||||||
image: postgres
|
|
||||||
user: "1000"
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
expose:
|
|
||||||
- 5432
|
|
||||||
environment:
|
|
||||||
- POSTGRES_USER=$DB_USER
|
|
||||||
- POSTGRES_PASSWORD=$DB_PASSWORD
|
|
||||||
- POSTGRES_DB=moneymgr
|
|
||||||
volumes:
|
|
||||||
- ./storage/db:/var/lib/postgresql/data
|
|
||||||
|
|
||||||
oidc:
|
|
||||||
image: pierre42100/basic_oidc
|
|
||||||
user: "1000"
|
|
||||||
environment:
|
|
||||||
- LISTEN_ADDRESS=0.0.0.0:9001
|
|
||||||
- STORAGE_PATH=/storage
|
|
||||||
- TOKEN_KEY=$AUTH_SECRET_KEY
|
|
||||||
- WEBSITE_ORIGIN=http://localhost:9001
|
|
||||||
- OIDC_CLIENT_ID=$OIDC_CLIENT_ID
|
|
||||||
- OIDC_CLIENT_SECRET=$OIDC_CLIENT_SECRET
|
|
||||||
- APP_ORIGIN=$WEBSITE_ORIGIN
|
|
||||||
expose:
|
|
||||||
- 9001
|
|
||||||
ports:
|
|
||||||
- 9001:9001
|
|
||||||
volumes:
|
|
||||||
- ./auth:/storage
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:alpine
|
|
||||||
user: "1000"
|
|
||||||
command: redis-server --requirepass ${REDIS_PASS:-secretredis}
|
|
||||||
expose:
|
|
||||||
- 6379
|
|
||||||
volumes:
|
|
||||||
- ./storage/redis-data:/data
|
|
||||||
- ./storage/redis-conf:/usr/local/etc/redis/redis.conf
|
|
||||||
|
|
||||||
moneymgr:
|
|
||||||
image: pierre42100/moneymgr_backend
|
|
||||||
user: "1000"
|
|
||||||
ports:
|
|
||||||
- 8000:8000
|
|
||||||
environment:
|
|
||||||
- WEBSITE_ORIGIN=${WEBSITE_ORIGIN}
|
|
||||||
- SECRET=${APP_SECRET}
|
|
||||||
- DB_HOST=db
|
|
||||||
- DB_USERNAME=$DB_USER
|
|
||||||
- DB_PASSWORD=$DB_PASSWORD
|
|
||||||
- DB_NAME=moneymgr
|
|
||||||
- OIDC_CONFIGURATION_URL=http://oidc:9001/.well-known/openid-configuration
|
|
||||||
- OIDC_PROVIDER_NAME=OIDC
|
|
||||||
- OIDC_CLIENT_ID=$OIDC_CLIENT_ID
|
|
||||||
- OIDC_CLIENT_SECRET=$OIDC_CLIENT_SECRET
|
|
||||||
- S3_ENDPOINT=http://minio:9000
|
|
||||||
- S3_ACCESS_KEY=$MINIO_ROOT_USER
|
|
||||||
- S3_SECRET_KEY=$MINIO_ROOT_PASSWORD
|
|
||||||
- REDIS_HOSTNAME=redis
|
|
||||||
- REDIS_PASSWORD=${REDIS_PASS:-secretredis}
|
|
38
moneymgr_backend/Cargo.lock
generated
38
moneymgr_backend/Cargo.lock
generated
@ -724,9 +724,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.40"
|
version = "4.5.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
|
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@ -734,9 +734,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.40"
|
version = "4.5.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
|
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@ -746,9 +746,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.40"
|
version = "4.5.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
|
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@ -948,9 +948,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.2.0-rc.3"
|
version = "0.2.0-rc.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a23fa214dea9efd4dacee5a5614646b30216ae0f05d4bb51bafb50e9da1c5be"
|
checksum = "170d71b5b14dec99db7739f6fc7d6ec2db80b78c3acb77db48392ccc3d8a9ea0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hybrid-array",
|
"hybrid-array",
|
||||||
]
|
]
|
||||||
@ -1100,9 +1100,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diesel"
|
name = "diesel"
|
||||||
version = "2.2.11"
|
version = "2.2.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a917a9209950404d5be011c81d081a2692a822f73c3d6af586f0cab5ff50f614"
|
checksum = "ff3e1edb1f37b4953dd5176916347289ed43d7119cc2e6c7c3f7849ff44ea506"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@ -1159,13 +1159,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.11.0-rc.0"
|
version = "0.11.0-pre.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "460dd7f37e4950526b54a5a6b1f41b6c8e763c58eb9a8fc8fc05ba5c2f44ca7b"
|
checksum = "6c478574b20020306f98d61c8ca3322d762e1ff08117422ac6106438605ea516"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer 0.11.0-rc.4",
|
"block-buffer 0.11.0-rc.4",
|
||||||
"const-oid 0.10.1",
|
"const-oid 0.10.1",
|
||||||
"crypto-common 0.2.0-rc.3",
|
"crypto-common 0.2.0-rc.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2304,7 +2304,7 @@ dependencies = [
|
|||||||
"rust_xlsxwriter",
|
"rust_xlsxwriter",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2 0.11.0-rc.0",
|
"sha2 0.11.0-pre.5",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
@ -3296,13 +3296,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.11.0-rc.0"
|
version = "0.11.0-pre.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aa1d2e6b3cc4e43a8258a9a3b17aa5dfd2cc5186c7024bba8a64aa65b2c71a59"
|
checksum = "19b4241d1a56954dce82cecda5c8e9c794eef6f53abe5e5216bac0a0ea71ffa7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
"digest 0.11.0-rc.0",
|
"digest 0.11.0-pre.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3571,9 +3571,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.45.1"
|
version = "1.45.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
|
checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -6,21 +6,21 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
env_logger = "0.11.8"
|
env_logger = "0.11.8"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
diesel = { version = "2.2.11", features = ["postgres", "r2d2"] }
|
diesel = { version = "2.2.10", features = ["postgres", "r2d2"] }
|
||||||
diesel_migrations = "2.2.0"
|
diesel_migrations = "2.1.0"
|
||||||
clap = { version = "4.5.40", features = ["env", "derive"] }
|
clap = { version = "4.5.38", features = ["env", "derive"] }
|
||||||
actix-web = "4.11.0"
|
actix-web = "4.11.0"
|
||||||
actix-cors = "0.7.1"
|
actix-cors = "0.7.1"
|
||||||
actix-multipart = "0.7.2"
|
actix-multipart = "0.7.2"
|
||||||
actix-remote-ip = "0.1.0"
|
actix-remote-ip = "0.1.0"
|
||||||
actix-session = { version = "0.10.1", features = ["redis-session"] }
|
actix-session = { version = "0.10.0", features = ["redis-session"] }
|
||||||
actix-files = "0.6.6"
|
actix-files = "0.6.6"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
rust-s3 = "0.36.0-beta.2"
|
rust-s3 = "0.36.0-beta.2"
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
tokio = "1.45.1"
|
tokio = "1.45.0"
|
||||||
futures-util = "0.3.31"
|
futures-util = "0.3.31"
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
light-openid = "1.0.4"
|
light-openid = "1.0.4"
|
||||||
@ -30,7 +30,7 @@ lazy-regex = "3.4.1"
|
|||||||
jwt-simple = { version = "0.12.12", default-features = false, features = ["pure-rust"] }
|
jwt-simple = { version = "0.12.12", default-features = false, features = ["pure-rust"] }
|
||||||
mime_guess = "2.0.5"
|
mime_guess = "2.0.5"
|
||||||
rust-embed = { version = "8.7.2" }
|
rust-embed = { version = "8.7.2" }
|
||||||
sha2 = "0.11.0-rc.0"
|
sha2 = "0.11.0-pre.5"
|
||||||
base16ct = "0.2.0"
|
base16ct = "0.2.0"
|
||||||
httpdate = "1.0.3"
|
httpdate = "1.0.3"
|
||||||
chrono = "0.4.41"
|
chrono = "0.4.41"
|
||||||
|
@ -14,7 +14,7 @@ use std::process::Command;
|
|||||||
struct Args {
|
struct Args {
|
||||||
/// URL to Money manager API
|
/// URL to Money manager API
|
||||||
#[arg(short('U'), long, env, default_value = "http://localhost:8000/api")]
|
#[arg(short('U'), long, env, default_value = "http://localhost:8000/api")]
|
||||||
moneymgr_url: String,
|
matrix_gw_url: String,
|
||||||
|
|
||||||
/// Token ID
|
/// Token ID
|
||||||
#[arg(short('i'), long, env)]
|
#[arg(short('i'), long, env)]
|
||||||
@ -39,8 +39,7 @@ struct Args {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let args: Args = Args::parse();
|
let args: Args = Args::parse();
|
||||||
|
|
||||||
let full_url = format!("{}{}", args.moneymgr_url, args.uri);
|
let full_url = format!("{}{}", args.matrix_gw_url, args.uri);
|
||||||
|
|
||||||
log::debug!("Full URL: {full_url}");
|
log::debug!("Full URL: {full_url}");
|
||||||
|
|
||||||
let key = HS256Key::from_bytes(args.token_secret.as_bytes());
|
let key = HS256Key::from_bytes(args.token_secret.as_bytes());
|
||||||
|
732
moneymgr_web/package-lock.json
generated
732
moneymgr_web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -12,32 +12,32 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.0",
|
"@emotion/styled": "^11.14.0",
|
||||||
"@fontsource/roboto": "^5.2.6",
|
"@fontsource/roboto": "^5.2.5",
|
||||||
"@jsonjoy.com/base64": "^1.1.2",
|
"@jsonjoy.com/base64": "^1.1.2",
|
||||||
"@mdi/js": "^7.4.47",
|
"@mdi/js": "^7.4.47",
|
||||||
"@mdi/react": "^1.6.1",
|
"@mdi/react": "^1.6.1",
|
||||||
"@mui/icons-material": "^7.1.1",
|
"@mui/icons-material": "^7.1.0",
|
||||||
"@mui/material": "^7.1.1",
|
"@mui/material": "^7.1.0",
|
||||||
"@mui/x-charts": "^8.5.3",
|
"@mui/x-charts": "^8.3.1",
|
||||||
"@mui/x-data-grid": "^8.5.3",
|
"@mui/x-data-grid": "^8.3.1",
|
||||||
"@mui/x-date-pickers": "^8.5.2",
|
"@mui/x-date-pickers": "^8.3.1",
|
||||||
"date-and-time": "^3.6.0",
|
"date-and-time": "^3.6.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"filesize": "^10.1.6",
|
"filesize": "^10.1.6",
|
||||||
"qrcode.react": "^4.2.0",
|
"qrcode.react": "^4.2.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
"react-router": "^7.6.2",
|
"react-router": "^7.6.0",
|
||||||
"react-router-dom": "^7.6.2",
|
"react-router-dom": "^7.6.0",
|
||||||
"ts-pattern": "^5.7.1"
|
"ts-pattern": "^5.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.29.0",
|
"@eslint/js": "^9.26.0",
|
||||||
"@types/react": "^19.1.8",
|
"@types/react": "^19.1.4",
|
||||||
"@types/react-dom": "^19.1.6",
|
"@types/react-dom": "^19.1.5",
|
||||||
"@vitejs/plugin-react": "^4.5.2",
|
"@vitejs/plugin-react": "^4.4.1",
|
||||||
"eslint": "^9.26.0",
|
"eslint": "^9.26.0",
|
||||||
"eslint-plugin-react-dom": "^1.52.2",
|
"eslint-plugin-react-dom": "^1.49.0",
|
||||||
"eslint-plugin-react-hooks": "^5.2.0",
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
"eslint-plugin-react-refresh": "^00.4.20",
|
"eslint-plugin-react-refresh": "^00.4.20",
|
||||||
"eslint-plugin-react-x": "^1.49.0",
|
"eslint-plugin-react-x": "^1.49.0",
|
||||||
|
Reference in New Issue
Block a user