feat: add base app
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
c3b45d9eb6
commit
74a16b4d7c
1
.env
Normal file
1
.env
Normal file
@ -0,0 +1 @@
|
||||
COMO_GATEWAY_PAT="MjE3MDg4ODQ0NzMyODI1ODU3OjVXSEhVT0U4djhGSHNuTFNYRzkzRGJGYmhrUUhRMGpwWm5NLUM1VE56UVdJSzhUdnlfaVBKMGVtMHdJZzhwUWRXcVdkeFVF"
|
1256
Cargo.lock
generated
1256
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
58
Cargo.toml
58
Cargo.toml
@ -1,5 +1,13 @@
|
||||
[workspace]
|
||||
|
||||
[workspace.dependencies]
|
||||
uuid = { version = "1.3.0", features = ["v4", "serde"] }
|
||||
chrono = { version = "0.4.23", features = ["serde"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
|
||||
[package]
|
||||
name = "leptos_start"
|
||||
name = "como_web"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
@ -7,31 +15,55 @@ edition = "2021"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
actix-files = { version = "0.6", optional = true }
|
||||
actix-web = { version = "4", optional = true, features = ["macros"] }
|
||||
console_error_panic_hook = "0.1"
|
||||
console_log = "0.2"
|
||||
cfg-if = "1"
|
||||
leptos = { version = "0.3", default-features = false, features = ["serde"] }
|
||||
leptos_meta = { version = "0.3", default-features = false }
|
||||
leptos_actix = { version = "0.3", optional = true }
|
||||
leptos_router = { version = "0.3", default-features = false }
|
||||
wasm-bindgen = "=0.2.84"
|
||||
lazy_static = "1"
|
||||
leptos = { version = "*", default-features = false, features = ["serde"] }
|
||||
leptos_meta = { version = "*", default-features = false }
|
||||
leptos_axum = { version = "*", default-features = false, optional = true }
|
||||
leptos_router = { version = "*", default-features = false }
|
||||
log = "0.4"
|
||||
simple_logger = "4"
|
||||
thiserror = "1"
|
||||
axum = { version = "0.6.1", optional = true }
|
||||
tower = { version = "0.4.13", optional = true }
|
||||
tower-http = { version = "0.3.4", features = ["fs"], optional = true }
|
||||
tokio = { version = "1", features = ["time"], optional = true }
|
||||
wasm-bindgen = "0.2"
|
||||
tracing-subscriber = { version = "0.3.16", optional = true, features = [
|
||||
"env-filter",
|
||||
] }
|
||||
tracing = { version = "0.1.37", features = ["log"], optional = true }
|
||||
anyhow = { version = "1.0.71", optional = true }
|
||||
|
||||
serde = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
uuid = { workspace = true, features = ["v4", "wasm-bindgen", "js", "serde"] }
|
||||
graphql_client = { version = "0.13.0", optional = true, features = ["reqwest"] }
|
||||
reqwest = { version = "0.11.18", optional = true }
|
||||
|
||||
[features]
|
||||
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
|
||||
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
|
||||
ssr = [
|
||||
"dep:actix-files",
|
||||
"dep:actix-web",
|
||||
"dep:leptos_actix",
|
||||
"dep:axum",
|
||||
"dep:tower",
|
||||
"dep:tower-http",
|
||||
"dep:tokio",
|
||||
"leptos/ssr",
|
||||
"leptos_meta/ssr",
|
||||
"leptos_router/ssr",
|
||||
"dep:leptos_axum",
|
||||
"dep:tracing-subscriber",
|
||||
"dep:tracing",
|
||||
"dep:graphql_client",
|
||||
"dep:reqwest",
|
||||
"dep:anyhow",
|
||||
]
|
||||
|
||||
[package.metadata.leptos]
|
||||
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
|
||||
output-name = "leptos_start"
|
||||
output-name = "como_web"
|
||||
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
|
||||
site-root = "target/site"
|
||||
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written
|
||||
|
@ -46,12 +46,12 @@ After running a `cargo leptos build --release` the minimum files needed are:
|
||||
|
||||
Copy these files to your remote server. The directory structure should be:
|
||||
```text
|
||||
leptos_start
|
||||
como_web
|
||||
site/
|
||||
```
|
||||
Set the following enviornment variables (updating for your project as needed):
|
||||
```text
|
||||
LEPTOS_OUTPUT_NAME="leptos_start"
|
||||
LEPTOS_OUTPUT_NAME="como_web"
|
||||
LEPTOS_SITE_ROOT="site"
|
||||
LEPTOS_SITE_PKG_DIR="pkg"
|
||||
LEPTOS_SITE_ADDR="127.0.0.1:3000"
|
||||
|
@ -23,3 +23,5 @@ scripts:
|
||||
type: "shell"
|
||||
"nodev":
|
||||
type: "shell"
|
||||
"refresh:schema":
|
||||
type: "shell"
|
||||
|
16
scripts/refresh:schema.sh
Executable file
16
scripts/refresh:schema.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
graphql-client introspect-schema \
|
||||
http://localhost:3001/graphql \
|
||||
--header "Authorization: Basic $COMO_GATEWAY_PAT" \
|
||||
--output src/api/graphql/schema/schema.json
|
||||
|
||||
graphql-client generate \
|
||||
--schema-path src/api/graphql/schema/schema.json \
|
||||
src/api/graphql/schema/mutations.graphql \
|
||||
--output-directory src/api/graphql/gen
|
||||
|
||||
graphql-client generate \
|
||||
--schema-path src/api/graphql/schema/schema.json \
|
||||
src/api/graphql/schema/queries.graphql \
|
||||
--output-directory src/api/graphql/gen
|
1738
src/api/graphql/schema/schema.json
Normal file
1738
src/api/graphql/schema/schema.json
Normal file
File diff suppressed because it is too large
Load Diff
2
src/api/mod.rs
Normal file
2
src/api/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
#[cfg(feature = "ssr")]
|
||||
pub fn register() {}
|
@ -12,7 +12,7 @@ pub fn App(cx: Scope) -> impl IntoView {
|
||||
|
||||
// injects a stylesheet into the document <head>
|
||||
// id=leptos means cargo-leptos will hot-reload this stylesheet
|
||||
<Stylesheet id="leptos" href="/pkg/leptos_start.css"/>
|
||||
<Stylesheet id="leptos" href="/pkg/como_web.css"/>
|
||||
|
||||
// sets the document title
|
||||
<Title text="Welcome to Leptos"/>
|
||||
|
45
src/fallback.rs
Normal file
45
src/fallback.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
use axum::{
|
||||
body::{boxed, Body, BoxBody},
|
||||
extract::Extension,
|
||||
response::IntoResponse,
|
||||
http::{Request, Response, StatusCode, Uri},
|
||||
};
|
||||
use axum::response::Response as AxumResponse;
|
||||
use tower::ServiceExt;
|
||||
use tower_http::services::ServeDir;
|
||||
use std::sync::Arc;
|
||||
use leptos::{LeptosOptions, Errors, view};
|
||||
use crate::app::{App, AppProps};
|
||||
|
||||
pub async fn file_and_error_handler(uri: Uri, Extension(options): Extension<Arc<LeptosOptions>>, req: Request<Body>) -> AxumResponse {
|
||||
let options = &*options;
|
||||
let root = options.site_root.clone();
|
||||
let res = get_static_file(uri.clone(), &root).await.unwrap();
|
||||
|
||||
if res.status() == StatusCode::OK {
|
||||
res.into_response()
|
||||
} else{
|
||||
let handler = leptos_axum::render_app_to_stream(
|
||||
options.to_owned(),
|
||||
move |cx| view!{ cx, <App/> }
|
||||
);
|
||||
handler(req).await.into_response()
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_static_file(uri: Uri, root: &str) -> Result<Response<BoxBody>, (StatusCode, String)> {
|
||||
let req = Request::builder().uri(uri.clone()).body(Body::empty()).unwrap();
|
||||
// `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
|
||||
// This path is relative to the cargo root
|
||||
match ServeDir::new(root).oneshot(req).await {
|
||||
Ok(res) => Ok(res.map(boxed)),
|
||||
Err(err) => Err((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Something went wrong: {err}"),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}}
|
@ -1,4 +1,6 @@
|
||||
pub mod api;
|
||||
pub mod app;
|
||||
pub mod fallback;
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
cfg_if! {
|
||||
|
71
src/main.rs
71
src/main.rs
@ -1,58 +1,45 @@
|
||||
#[cfg(feature = "ssr")]
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
use actix_files::Files;
|
||||
use actix_web::*;
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
use axum::{extract::Extension, routing::post, Router};
|
||||
use como_web::app::*;
|
||||
use como_web::fallback::file_and_error_handler;
|
||||
use leptos::*;
|
||||
use leptos_actix::{generate_route_list, LeptosRoutes};
|
||||
use leptos_start::app::*;
|
||||
use leptos_axum::{generate_route_list, LeptosRoutes};
|
||||
use std::sync::Arc;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
std::env::set_var("COMO_GATEWAY_URL", "https://api.como.i.kjuulh.io/graphql");
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.init();
|
||||
|
||||
let conf = get_configuration(None).await.unwrap();
|
||||
let addr = conf.leptos_options.site_addr;
|
||||
let leptos_options = conf.leptos_options;
|
||||
// Generate the list of routes in your Leptos App
|
||||
let routes = generate_route_list(|cx| view! { cx, <App/> });
|
||||
let routes = generate_route_list(|cx| view! { cx, <App/> }).await;
|
||||
|
||||
HttpServer::new(move || {
|
||||
let leptos_options = &conf.leptos_options;
|
||||
let site_root = &leptos_options.site_root;
|
||||
como_web::api::register();
|
||||
|
||||
App::new()
|
||||
.route("/api/{tail:.*}", leptos_actix::handle_server_fns())
|
||||
.leptos_routes(
|
||||
leptos_options.to_owned(),
|
||||
routes.to_owned(),
|
||||
|cx| view! { cx, <App/> },
|
||||
)
|
||||
.service(Files::new("/", site_root))
|
||||
//.wrap(middleware::Compress::default())
|
||||
})
|
||||
.bind(&addr)?
|
||||
.run()
|
||||
let app = Router::new()
|
||||
.route("/api/*fn_name", post(leptos_axum::handle_server_fns))
|
||||
.leptos_routes(leptos_options.clone(), routes, |cx| view! { cx, <App/> })
|
||||
.fallback(file_and_error_handler)
|
||||
.layer(Extension(Arc::new(leptos_options)));
|
||||
|
||||
// run our app with hyper
|
||||
// `axum::Server` is a re-export of `hyper::Server`
|
||||
log!("listening on http://{}", &addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "ssr", feature = "csr")))]
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub fn main() {
|
||||
// no client-side main function
|
||||
// unless we want this to work with e.g., Trunk for pure client-side testing
|
||||
// see lib.rs for hydration function instead
|
||||
// see optional feature `ssg` instead
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "ssr"), feature = "csr"))]
|
||||
pub fn main() {
|
||||
// a client-side main function is required for using `trunk serve`
|
||||
// prefer using `cargo leptos serve` instead
|
||||
// to run: `trunk serve --open --features ssg`
|
||||
use leptos::*;
|
||||
use leptos_start::app::*;
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
leptos::mount_to_body(move |cx| {
|
||||
// note: for testing it may be preferrable to replace this with a
|
||||
// more specific component, although leptos_router should still work
|
||||
view! {cx, <App/> }
|
||||
});
|
||||
}
|
||||
|
@ -522,6 +522,10 @@ video {
|
||||
--tw-backdrop-sepia: ;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.text-xl {
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.75rem;
|
||||
|
Loading…
Reference in New Issue
Block a user