refactor: remove loco-rs

This commit is contained in:
2025-02-28 03:19:48 +08:00
parent c0707d17bb
commit a68aab1452
66 changed files with 1321 additions and 829 deletions

View File

@@ -1,62 +1,33 @@
pub mod ext;
pub mod builder;
pub mod config;
pub mod context;
pub mod core;
pub mod env;
pub mod router;
use std::{
fs,
path::{self, Path, PathBuf},
sync::Arc,
};
pub use core::App;
use std::path::Path;
use async_trait::async_trait;
pub use ext::AppContextExt;
use itertools::Itertools;
pub use context::AppContext;
use loco_rs::{
Result,
app::{AppContext, Hooks},
app::{AppContext as LocoAppContext, Hooks},
boot::{BootResult, StartMode, create_app},
cache,
config::Config,
controller::{AppRoutes, middleware, middleware::MiddlewareLayer},
controller::AppRoutes,
db::truncate_table,
environment::Environment,
prelude::*,
task::Tasks,
};
use once_cell::sync::OnceCell;
use crate::{
auth::service::AppAuthServiceInitializer,
controllers::{self},
dal::AppDalInitalizer,
extract::mikan::client::AppMikanClientInitializer,
graphql::service::AppGraphQLServiceInitializer,
migrations::Migrator,
models::subscribers,
workers::subscription_worker::SubscriptionWorker,
};
use crate::{migrations::Migrator, models::subscribers};
pub const WORKING_ROOT_VAR_NAME: &str = "WORKING_ROOT";
static APP_WORKING_ROOT: OnceCell<quirks_path::PathBuf> = OnceCell::new();
pub struct App;
impl App {
pub fn set_working_root(path: PathBuf) {
APP_WORKING_ROOT.get_or_init(|| {
quirks_path::PathBuf::from(path.as_os_str().to_string_lossy().to_string())
});
}
pub fn get_working_root() -> &'static quirks_path::Path {
APP_WORKING_ROOT
.get()
.map(|p| p.as_path())
.expect("working root not set")
}
}
pub struct App1;
#[async_trait]
impl Hooks for App {
impl Hooks for App1 {
fn app_version() -> String {
format!(
"{} ({})",
@@ -79,130 +50,28 @@ impl Hooks for App {
create_app::<Self, Migrator>(mode, environment, config).await
}
async fn load_config(env: &Environment) -> Result<Config> {
let working_roots_to_search = [
std::env::var(WORKING_ROOT_VAR_NAME).ok(),
Some(String::from("./apps/recorder")),
Some(String::from(".")),
]
.into_iter()
.flatten()
.collect_vec();
for working_root in working_roots_to_search.iter() {
let working_root = PathBuf::from(working_root);
for env_file in [
working_root.join(format!(".env.{env}.local")),
working_root.join(format!(".env.{env}")),
working_root.join(".env.local"),
working_root.join(".env"),
] {
tracing::info!(env_file =? env_file);
if env_file.exists() && env_file.is_file() {
dotenv::from_path(&env_file).map_err(loco_rs::Error::wrap)?;
tracing::info!("loaded env from {} success.", env_file.to_string_lossy());
}
}
}
for working_root in working_roots_to_search.iter() {
let working_root = PathBuf::from(working_root);
let config_dir = working_root.as_path().join("config");
for config_file in [
config_dir.join(format!("{env}.local.yaml")),
config_dir.join(format!("{env}.yaml")),
] {
if config_file.exists() && config_file.is_file() {
let content = fs::read_to_string(config_file.clone())?;
let rendered = tera::Tera::one_off(
&content,
&tera::Context::from_value(serde_json::json!({}))?,
false,
)?;
App::set_working_root(working_root);
let config_file = &config_file.to_string_lossy();
let res = serde_yaml::from_str(&rendered)
.map_err(|err| loco_rs::Error::YAMLFile(err, config_file.to_string()))?;
tracing::info!("loading config from {} success", config_file);
return Ok(res);
}
}
}
Err(loco_rs::Error::Message(format!(
"no configuration file found in search paths: {}",
working_roots_to_search
.iter()
.flat_map(|p| path::absolute(PathBuf::from(p)))
.map(|p| p.to_string_lossy().to_string())
.join(",")
)))
}
async fn initializers(_ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {
let initializers: Vec<Box<dyn Initializer>> = vec![
Box::new(AppDalInitalizer),
Box::new(AppMikanClientInitializer),
Box::new(AppGraphQLServiceInitializer),
Box::new(AppAuthServiceInitializer),
];
async fn initializers(_ctx: &LocoAppContext) -> Result<Vec<Box<dyn Initializer>>> {
let initializers: Vec<Box<dyn Initializer>> = vec![];
Ok(initializers)
}
fn routes(ctx: &AppContext) -> AppRoutes {
let ctx = Arc::new(ctx.clone());
fn routes(_ctx: &LocoAppContext) -> AppRoutes {
AppRoutes::with_default_routes()
.prefix("/api")
.add_route(controllers::graphql::routes(ctx.clone()))
}
fn middlewares(ctx: &AppContext) -> Vec<Box<dyn MiddlewareLayer>> {
use loco_rs::controller::middleware::static_assets::{FolderConfig, StaticAssets};
let mut middlewares = middleware::default_middleware_stack(ctx);
middlewares.push(Box::new(StaticAssets {
enable: true,
must_exist: true,
folder: FolderConfig {
uri: String::from("/api/static"),
path: App::get_working_root().join("public").into(),
},
fallback: App::get_working_root()
.join("public/assets/404.html")
.into(),
precompressed: false,
}));
middlewares
}
async fn after_context(ctx: AppContext) -> Result<AppContext> {
Ok(AppContext {
cache: cache::Cache::new(cache::drivers::inmem::new()).into(),
..ctx
})
}
async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()> {
queue.register(SubscriptionWorker::build(ctx)).await?;
Ok(())
}
fn register_tasks(_tasks: &mut Tasks) {}
async fn truncate(ctx: &AppContext) -> Result<()> {
async fn truncate(ctx: &LocoAppContext) -> Result<()> {
truncate_table(&ctx.db, subscribers::Entity).await?;
Ok(())
}
async fn seed(_ctx: &AppContext, _base: &Path) -> Result<()> {
async fn seed(_ctx: &LocoAppContext, _base: &Path) -> Result<()> {
Ok(())
}
async fn connect_workers(_ctx: &LocoAppContext, _queue: &Queue) -> Result<()> {
Ok(())
}
}