Compare commits
	
		
			1 Commits
		
	
	
		
			renovate/e
			...
			6c226bfbe1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6c226bfbe1 | 
@@ -5,7 +5,7 @@ name: default
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
- name: frontend_build
 | 
			
		||||
  image: node:24
 | 
			
		||||
  image: node:23
 | 
			
		||||
  volumes:
 | 
			
		||||
    - name: frontend_app
 | 
			
		||||
      path: /tmp/frontend_build
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							@@ -1,11 +1,4 @@
 | 
			
		||||
# VirtWeb Remote
 | 
			
		||||
Web UI that allows to start and stop VMs managed by VirtWEB without having to expose the VirtWEB directly on the Internet.
 | 
			
		||||
WIP project
 | 
			
		||||
 | 
			
		||||
VirtWebRemote rely on OpenID to authenticate users.
 | 
			
		||||
 | 
			
		||||
VirtWebRemote authenticates against VirtWEB API using an API token. Both the token ID and private key are required to be able to authenticate against the VirtWEB API.
 | 
			
		||||
 | 
			
		||||
## Docker image options
 | 
			
		||||
```bash
 | 
			
		||||
docker run --rm -it pierre42100/virtweb_remote --help
 | 
			
		||||
```
 | 
			
		||||
This project aims to use the VirtWeb API to start and stop VM without directly exposing the VirtWEB API to the Internet.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										892
									
								
								remote_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										892
									
								
								remote_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,28 +1,28 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "remote_backend"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
edition = "2024"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
log = "0.4.28"
 | 
			
		||||
env_logger = "0.11.8"
 | 
			
		||||
clap = { version = "4.5.51", features = ["derive", "env"] }
 | 
			
		||||
serde = { version = "1.0.228", features = ["derive"] }
 | 
			
		||||
light-openid = { version = "1.0.4", features = ["crypto-wrapper"] }
 | 
			
		||||
basic-jwt = "0.3.0"
 | 
			
		||||
actix-web = "4.11.0"
 | 
			
		||||
log = "0.4.21"
 | 
			
		||||
env_logger = "0.11.3"
 | 
			
		||||
clap = { version = "4.5.21", features = ["derive", "env"] }
 | 
			
		||||
serde = { version = "1.0.215", features = ["derive"] }
 | 
			
		||||
light-openid = { version = "1.0.2", features = ["crypto-wrapper"] }
 | 
			
		||||
basic-jwt = "0.2.0"
 | 
			
		||||
actix-web = "4.5.1"
 | 
			
		||||
actix-remote-ip = "0.1.0"
 | 
			
		||||
actix-session = { version = "0.11.0", features = ["cookie-session"] }
 | 
			
		||||
actix-identity = "0.9.0"
 | 
			
		||||
actix-cors = "0.7.1"
 | 
			
		||||
lazy_static = "1.5.0"
 | 
			
		||||
anyhow = "1.0.100"
 | 
			
		||||
reqwest = { version = "0.12.24", features = ["json"] }
 | 
			
		||||
thiserror = "2.0.17"
 | 
			
		||||
uuid = { version = "1.18.1", features = ["v4", "serde"] }
 | 
			
		||||
futures-util = "0.3.31"
 | 
			
		||||
lazy-regex = "3.4.2"
 | 
			
		||||
mime_guess = "2.0.5"
 | 
			
		||||
rust-embed = { version = "8.7.2" }
 | 
			
		||||
actix-session = { version = "0.10.1", features = ["cookie-session"] }
 | 
			
		||||
actix-identity = "0.8.0"
 | 
			
		||||
actix-cors = "0.7.0"
 | 
			
		||||
lazy_static = "1.4.0"
 | 
			
		||||
anyhow = "1.0.93"
 | 
			
		||||
reqwest = { version = "0.12.9", features = ["json"] }
 | 
			
		||||
thiserror = "2.0.3"
 | 
			
		||||
uuid = { version = "1.8.0", features = ["v4", "serde"] }
 | 
			
		||||
futures-util = "0.3.30"
 | 
			
		||||
lazy-regex = "3.1.0"
 | 
			
		||||
mime_guess = "2.0.4"
 | 
			
		||||
rust-embed = { version = "8.3.0" }
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
use actix_remote_ip::RemoteIP;
 | 
			
		||||
use actix_web::web::Data;
 | 
			
		||||
use actix_web::{HttpResponse, Responder, web};
 | 
			
		||||
use actix_web::{web, HttpResponse, Responder};
 | 
			
		||||
use light_openid::basic_state_manager::BasicStateManager;
 | 
			
		||||
 | 
			
		||||
use crate::app_config::AppConfig;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
use crate::controllers::HttpResult;
 | 
			
		||||
use crate::virtweb_client;
 | 
			
		||||
use crate::virtweb_client::{GroupID, VMUuid};
 | 
			
		||||
use actix_web::{HttpResponse, web};
 | 
			
		||||
use actix_web::{web, HttpResponse};
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
pub struct GroupIDInPath {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
use actix_web::HttpResponse;
 | 
			
		||||
use actix_web::body::BoxBody;
 | 
			
		||||
use actix_web::http::StatusCode;
 | 
			
		||||
use actix_web::HttpResponse;
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
use std::fmt::{Display, Formatter};
 | 
			
		||||
use std::io::ErrorKind;
 | 
			
		||||
 | 
			
		||||
pub mod auth_controller;
 | 
			
		||||
pub mod group_controller;
 | 
			
		||||
@@ -37,7 +38,7 @@ impl actix_web::error::ResponseError for HttpErr {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fn error_response(&self) -> HttpResponse<BoxBody> {
 | 
			
		||||
        log::error!("Error while processing request! {self}");
 | 
			
		||||
        log::error!("Error while processing request! {}", self);
 | 
			
		||||
 | 
			
		||||
        HttpResponse::InternalServerError().body("Failed to execute request!")
 | 
			
		||||
    }
 | 
			
		||||
@@ -51,7 +52,7 @@ impl From<anyhow::Error> for HttpErr {
 | 
			
		||||
 | 
			
		||||
impl From<Box<dyn Error>> for HttpErr {
 | 
			
		||||
    fn from(value: Box<dyn Error>) -> Self {
 | 
			
		||||
        HttpErr::Err(std::io::Error::other(value.to_string()).into())
 | 
			
		||||
        HttpErr::Err(std::io::Error::new(ErrorKind::Other, value.to_string()).into())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -81,7 +82,7 @@ impl From<reqwest::header::ToStrError> for HttpErr {
 | 
			
		||||
 | 
			
		||||
impl From<actix_web::Error> for HttpErr {
 | 
			
		||||
    fn from(value: actix_web::Error) -> Self {
 | 
			
		||||
        HttpErr::Err(std::io::Error::other(value.to_string()).into())
 | 
			
		||||
        HttpErr::Err(std::io::Error::new(ErrorKind::Other, value.to_string()).into())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ mod serve_static_debug {
 | 
			
		||||
 | 
			
		||||
#[cfg(not(debug_assertions))]
 | 
			
		||||
mod serve_static_release {
 | 
			
		||||
    use actix_web::{HttpResponse, Responder, web};
 | 
			
		||||
    use actix_web::{web, HttpResponse, Responder};
 | 
			
		||||
    use rust_embed::RustEmbed;
 | 
			
		||||
 | 
			
		||||
    #[derive(RustEmbed)]
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
use crate::controllers::HttpResult;
 | 
			
		||||
use crate::virtweb_client;
 | 
			
		||||
use crate::virtweb_client::VMUuid;
 | 
			
		||||
use actix_web::{HttpResponse, web};
 | 
			
		||||
use actix_web::{web, HttpResponse};
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
pub struct ReqPath {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
use actix_identity::Identity;
 | 
			
		||||
use actix_web::dev::Payload;
 | 
			
		||||
use actix_web::{Error, FromRequest, HttpMessage, HttpRequest};
 | 
			
		||||
use futures_util::future::{Ready, ready};
 | 
			
		||||
use futures_util::future::{ready, Ready};
 | 
			
		||||
use std::fmt::Display;
 | 
			
		||||
 | 
			
		||||
pub struct AuthExtractor {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
use actix_cors::Cors;
 | 
			
		||||
use actix_identity::config::LogoutBehaviour;
 | 
			
		||||
use actix_identity::IdentityMiddleware;
 | 
			
		||||
use actix_identity::config::LogoutBehavior;
 | 
			
		||||
use actix_remote_ip::RemoteIPConfig;
 | 
			
		||||
use actix_session::SessionMiddleware;
 | 
			
		||||
use actix_session::storage::CookieSessionStore;
 | 
			
		||||
use actix_session::SessionMiddleware;
 | 
			
		||||
use actix_web::cookie::{Key, SameSite};
 | 
			
		||||
use actix_web::middleware::Logger;
 | 
			
		||||
use actix_web::web::Data;
 | 
			
		||||
use actix_web::{App, HttpServer, web};
 | 
			
		||||
use actix_web::{web, App, HttpServer};
 | 
			
		||||
use light_openid::basic_state_manager::BasicStateManager;
 | 
			
		||||
use remote_backend::app_config::AppConfig;
 | 
			
		||||
use remote_backend::constants;
 | 
			
		||||
@@ -37,7 +37,7 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
        .build();
 | 
			
		||||
 | 
			
		||||
        let identity_middleware = IdentityMiddleware::builder()
 | 
			
		||||
            .logout_behavior(LogoutBehavior::PurgeSession)
 | 
			
		||||
            .logout_behaviour(LogoutBehaviour::PurgeSession)
 | 
			
		||||
            .visit_deadline(Some(Duration::from_secs(
 | 
			
		||||
                constants::MAX_INACTIVITY_DURATION,
 | 
			
		||||
            )))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
use std::future::{Ready, ready};
 | 
			
		||||
use std::future::{ready, Ready};
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
 | 
			
		||||
use crate::app_config::AppConfig;
 | 
			
		||||
@@ -7,8 +7,8 @@ use crate::extractors::auth_extractor::AuthExtractor;
 | 
			
		||||
use actix_web::body::EitherBody;
 | 
			
		||||
use actix_web::dev::Payload;
 | 
			
		||||
use actix_web::{
 | 
			
		||||
    dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
 | 
			
		||||
    Error, FromRequest, HttpResponse,
 | 
			
		||||
    dev::{Service, ServiceRequest, ServiceResponse, Transform, forward_ready},
 | 
			
		||||
};
 | 
			
		||||
use futures_util::future::LocalBoxFuture;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								remote_frontend/.eslintrc.cjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								remote_frontend/.eslintrc.cjs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
module.exports = {
 | 
			
		||||
  root: true,
 | 
			
		||||
  env: { browser: true, es2020: true },
 | 
			
		||||
  extends: [
 | 
			
		||||
    'eslint:recommended',
 | 
			
		||||
    'plugin:@typescript-eslint/recommended',
 | 
			
		||||
    'plugin:react-hooks/recommended',
 | 
			
		||||
  ],
 | 
			
		||||
  ignorePatterns: ['dist', '.eslintrc.cjs'],
 | 
			
		||||
  parser: '@typescript-eslint/parser',
 | 
			
		||||
  plugins: ['react-refresh'],
 | 
			
		||||
  rules: {
 | 
			
		||||
    'react-refresh/only-export-components': [
 | 
			
		||||
      'warn',
 | 
			
		||||
      { allowConstantExport: true },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
import js from '@eslint/js'
 | 
			
		||||
import globals from 'globals'
 | 
			
		||||
import reactHooks from 'eslint-plugin-react-hooks'
 | 
			
		||||
import reactRefresh from 'eslint-plugin-react-refresh'
 | 
			
		||||
import tseslint from 'typescript-eslint'
 | 
			
		||||
 | 
			
		||||
export default tseslint.config(
 | 
			
		||||
  { ignores: ['dist'] },
 | 
			
		||||
  {
 | 
			
		||||
    extends: [js.configs.recommended, ...tseslint.configs.recommended],
 | 
			
		||||
    files: ['**/*.{ts,tsx}'],
 | 
			
		||||
    languageOptions: {
 | 
			
		||||
      ecmaVersion: 2020,
 | 
			
		||||
      globals: globals.browser,
 | 
			
		||||
    },
 | 
			
		||||
    plugins: {
 | 
			
		||||
      'react-hooks': reactHooks,
 | 
			
		||||
      'react-refresh': reactRefresh,
 | 
			
		||||
    },
 | 
			
		||||
    rules: {
 | 
			
		||||
      ...reactHooks.configs.recommended.rules,
 | 
			
		||||
      'react-refresh/only-export-components': [
 | 
			
		||||
        'warn',
 | 
			
		||||
        { allowConstantExport: true },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										4012
									
								
								remote_frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4012
									
								
								remote_frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -10,25 +10,22 @@
 | 
			
		||||
    "preview": "vite preview"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@fluentui/react-components": "^9.72.4",
 | 
			
		||||
    "@fluentui/react-icons": "^2.0.313",
 | 
			
		||||
    "filesize": "^11.0.13",
 | 
			
		||||
    "react": "^18.3.1",
 | 
			
		||||
    "react-dom": "^18.3.1"
 | 
			
		||||
    "@fluentui/react-components": "^9.56.3",
 | 
			
		||||
    "@fluentui/react-icons": "^2.0.266",
 | 
			
		||||
    "filesize": "^10.1.6",
 | 
			
		||||
    "react": "^18.2.0",
 | 
			
		||||
    "react-dom": "^18.2.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@eslint/js": "^9.39.0",
 | 
			
		||||
    "@types/react": "^18.3.26",
 | 
			
		||||
    "@types/react-dom": "^18.3.7",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^8.46.2",
 | 
			
		||||
    "@typescript-eslint/parser": "^8.46.2",
 | 
			
		||||
    "@vitejs/plugin-react": "^5.1.0",
 | 
			
		||||
    "eslint": "^9.39.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^5.2.0",
 | 
			
		||||
    "eslint-plugin-react-refresh": "^0.4.24",
 | 
			
		||||
    "globals": "^16.4.0",
 | 
			
		||||
    "typescript": "^5.9.3",
 | 
			
		||||
    "typescript-eslint": "^8.43.0",
 | 
			
		||||
    "vite": "^7.1.12"
 | 
			
		||||
    "@types/react": "^18.3.12",
 | 
			
		||||
    "@types/react-dom": "^18.3.1",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^8.16.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^8.16.0",
 | 
			
		||||
    "@vitejs/plugin-react": "^4.3.4",
 | 
			
		||||
    "eslint": "^9.0.0",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^5.0.0",
 | 
			
		||||
    "eslint-plugin-react-refresh": "^0.4.14",
 | 
			
		||||
    "typescript": "^5.7.2",
 | 
			
		||||
    "vite": "^6.0.1"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -123,7 +123,7 @@ function GroupInfo(p: { group: VMGroup }): React.ReactElement {
 | 
			
		||||
                </TableCell>
 | 
			
		||||
                <TableCell>
 | 
			
		||||
                  {item.architecture} • RAM :{" "}
 | 
			
		||||
                  {filesize(item.memory)} •{" "}
 | 
			
		||||
                  {filesize(item.memory * 1000 * 1000)} •{" "}
 | 
			
		||||
                  {item.number_vcpu} vCPU
 | 
			
		||||
                </TableCell>
 | 
			
		||||
                <TableCell>{state?.[item.uuid] ?? ""}</TableCell>
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@ function VMWidget(p: { vm: VMInfoAndCaps }): React.ReactElement {
 | 
			
		||||
        }
 | 
			
		||||
      />
 | 
			
		||||
      <p className={styles.caption1} style={{ margin: "0px auto" }}>
 | 
			
		||||
        {p.vm.architecture} • RAM : {filesize(p.vm.memory)}{" "}
 | 
			
		||||
        {p.vm.architecture} • RAM : {filesize(p.vm.memory * 1000 * 1000)}{" "}
 | 
			
		||||
        • {p.vm.number_vcpu} vCPU
 | 
			
		||||
      </p>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
 | 
			
		||||
    "target": "ES2020",
 | 
			
		||||
    "useDefineForClassFields": true,
 | 
			
		||||
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
 | 
			
		||||
    "module": "ESNext",
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
 | 
			
		||||
    /* Bundler mode */
 | 
			
		||||
    "moduleResolution": "bundler",
 | 
			
		||||
    "allowImportingTsExtensions": true,
 | 
			
		||||
    "isolatedModules": true,
 | 
			
		||||
    "moduleDetection": "force",
 | 
			
		||||
    "noEmit": true,
 | 
			
		||||
    "jsx": "react-jsx",
 | 
			
		||||
 | 
			
		||||
    /* Linting */
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "noUnusedLocals": true,
 | 
			
		||||
    "noUnusedParameters": true,
 | 
			
		||||
    "noFallthroughCasesInSwitch": true,
 | 
			
		||||
    "noUncheckedSideEffectImports": true
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["src"]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +1,25 @@
 | 
			
		||||
{
 | 
			
		||||
  "files": [],
 | 
			
		||||
  "references": [
 | 
			
		||||
    { "path": "./tsconfig.app.json" },
 | 
			
		||||
    { "path": "./tsconfig.node.json" }
 | 
			
		||||
  ]
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "target": "ES2020",
 | 
			
		||||
    "useDefineForClassFields": true,
 | 
			
		||||
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
 | 
			
		||||
    "module": "ESNext",
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
 | 
			
		||||
    /* Bundler mode */
 | 
			
		||||
    "moduleResolution": "bundler",
 | 
			
		||||
    "allowImportingTsExtensions": true,
 | 
			
		||||
    "resolveJsonModule": true,
 | 
			
		||||
    "isolatedModules": true,
 | 
			
		||||
    "noEmit": true,
 | 
			
		||||
    "jsx": "react-jsx",
 | 
			
		||||
 | 
			
		||||
    /* Linting */
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "noUnusedLocals": true,
 | 
			
		||||
    "noUnusedParameters": true,
 | 
			
		||||
    "noFallthroughCasesInSwitch": true
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["src"],
 | 
			
		||||
  "references": [{ "path": "./tsconfig.node.json" }]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
 | 
			
		||||
    "target": "ES2022",
 | 
			
		||||
    "lib": ["ES2023"],
 | 
			
		||||
    "module": "ESNext",
 | 
			
		||||
    "composite": true,
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
 | 
			
		||||
    /* Bundler mode */
 | 
			
		||||
    "module": "ESNext",
 | 
			
		||||
    "moduleResolution": "bundler",
 | 
			
		||||
    "allowImportingTsExtensions": true,
 | 
			
		||||
    "isolatedModules": true,
 | 
			
		||||
    "moduleDetection": "force",
 | 
			
		||||
    "noEmit": true,
 | 
			
		||||
 | 
			
		||||
    /* Linting */
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "noUnusedLocals": true,
 | 
			
		||||
    "noUnusedParameters": true,
 | 
			
		||||
    "noFallthroughCasesInSwitch": true,
 | 
			
		||||
    "noUncheckedSideEffectImports": true
 | 
			
		||||
    "allowSyntheticDefaultImports": true,
 | 
			
		||||
    "strict": true
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["vite.config.ts"]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import { defineConfig } from 'vite'
 | 
			
		||||
import react from '@vitejs/plugin-react'
 | 
			
		||||
 | 
			
		||||
// https://vite.dev/config/
 | 
			
		||||
// https://vitejs.dev/config/
 | 
			
		||||
export default defineConfig({
 | 
			
		||||
  plugins: [react()],
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "extends": ["local>renovate/presets"]
 | 
			
		||||
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
 | 
			
		||||
  "packageRules": [
 | 
			
		||||
    {
 | 
			
		||||
      "matchUpdateTypes": ["major", "minor", "patch"],
 | 
			
		||||
      "automerge": true
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user