mirror of
https://github.com/leptos-rs/leptos.git
synced 2025-12-28 11:21:55 -05:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef4c628994 |
2
.github/workflows/ci-changed-examples.yml
vendored
2
.github/workflows/ci-changed-examples.yml
vendored
@@ -29,4 +29,4 @@ jobs:
|
||||
with:
|
||||
directory: ${{ matrix.directory }}
|
||||
cargo_make_task: "ci"
|
||||
toolchain: nightly-2024-03-31
|
||||
toolchain: nightly-2024-01-29
|
||||
|
||||
2
.github/workflows/ci-examples.yml
vendored
2
.github/workflows/ci-examples.yml
vendored
@@ -24,4 +24,4 @@ jobs:
|
||||
with:
|
||||
directory: ${{ matrix.directory }}
|
||||
cargo_make_task: "ci"
|
||||
toolchain: nightly-2024-03-31
|
||||
toolchain: nightly-2024-01-29
|
||||
|
||||
28
.github/workflows/ci-semver.yml
vendored
28
.github/workflows/ci-semver.yml
vendored
@@ -1,28 +0,0 @@
|
||||
name: CI semver
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
get-leptos-changed:
|
||||
uses: ./.github/workflows/get-leptos-changed.yml
|
||||
|
||||
test:
|
||||
needs: [get-leptos-changed]
|
||||
if: needs.get-leptos-changed.outputs.leptos_changed == 'true'
|
||||
name: Run semver check (nightly-2024-03-31)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Sember Checks
|
||||
uses: obi1kenobi/cargo-semver-checks-action@v2
|
||||
with:
|
||||
rust-toolchain: nightly-2024-03-31
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -40,4 +40,4 @@ jobs:
|
||||
with:
|
||||
directory: ${{ matrix.directory }}
|
||||
cargo_make_task: "ci"
|
||||
toolchain: nightly-2024-03-31
|
||||
toolchain: nightly-2024-01-29
|
||||
|
||||
2
.github/workflows/get-example-changed.yml
vendored
2
.github/workflows/get-example-changed.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
- name: Get example files that changed
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v43
|
||||
uses: tj-actions/changed-files@v41
|
||||
with:
|
||||
files: |
|
||||
examples/**
|
||||
|
||||
4
.github/workflows/get-examples-matrix.yml
vendored
4
.github/workflows/get-examples-matrix.yml
vendored
@@ -17,8 +17,8 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install jq
|
||||
run: sudo apt-get install jq
|
||||
- name: Install JQ Tool
|
||||
uses: mbround18/install-jq@v1
|
||||
|
||||
- name: Set Matrix
|
||||
id: set-matrix
|
||||
|
||||
2
.github/workflows/get-leptos-changed.yml
vendored
2
.github/workflows/get-leptos-changed.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
|
||||
- name: Get source files that changed
|
||||
id: changed-source
|
||||
uses: tj-actions/changed-files@v43
|
||||
uses: tj-actions/changed-files@v41
|
||||
with:
|
||||
files: |
|
||||
integrations/**
|
||||
|
||||
18
.github/workflows/run-cargo-make-task.yml
vendored
18
.github/workflows/run-cargo-make-task.yml
vendored
@@ -27,9 +27,11 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ inputs.toolchain }}
|
||||
override: true
|
||||
components: rustfmt
|
||||
|
||||
- name: Add wasm32-unknown-unknown
|
||||
run: rustup target add wasm32-unknown-unknown
|
||||
@@ -42,18 +44,6 @@ jobs:
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Install binstall
|
||||
uses: cargo-bins/cargo-binstall@main
|
||||
|
||||
- name: Install wasm-bindgen
|
||||
run: cargo binstall wasm-bindgen-cli --no-confirm
|
||||
|
||||
- name: Install wasm-pack
|
||||
run: cargo binstall wasm-pack --no-confirm
|
||||
|
||||
- name: Install cargo-leptos
|
||||
run: cargo binstall cargo-leptos --no-confirm
|
||||
|
||||
- name: Install Trunk
|
||||
uses: jetli/trunk-action@v0.4.0
|
||||
with:
|
||||
@@ -79,7 +69,7 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
|
||||
26
Cargo.toml
26
Cargo.toml
@@ -25,23 +25,23 @@ members = [
|
||||
exclude = ["benchmarks", "examples"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.6.10"
|
||||
version = "0.6.6"
|
||||
rust-version = "1.75"
|
||||
|
||||
[workspace.dependencies]
|
||||
leptos = { path = "./leptos", version = "0.6.10" }
|
||||
leptos_dom = { path = "./leptos_dom", version = "0.6.10" }
|
||||
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.6.10" }
|
||||
leptos_macro = { path = "./leptos_macro", version = "0.6.10" }
|
||||
leptos_reactive = { path = "./leptos_reactive", version = "0.6.10" }
|
||||
leptos_server = { path = "./leptos_server", version = "0.6.10" }
|
||||
server_fn = { path = "./server_fn", version = "0.6.10" }
|
||||
server_fn_macro = { path = "./server_fn_macro", version = "0.6.10" }
|
||||
leptos = { path = "./leptos", version = "0.6.5" }
|
||||
leptos_dom = { path = "./leptos_dom", version = "0.6.5" }
|
||||
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.6.5" }
|
||||
leptos_macro = { path = "./leptos_macro", version = "0.6.5" }
|
||||
leptos_reactive = { path = "./leptos_reactive", version = "0.6.5" }
|
||||
leptos_server = { path = "./leptos_server", version = "0.6.5" }
|
||||
server_fn = { path = "./server_fn", version = "0.6.5" }
|
||||
server_fn_macro = { path = "./server_fn_macro", version = "0.6.5" }
|
||||
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.6" }
|
||||
leptos_config = { path = "./leptos_config", version = "0.6.10" }
|
||||
leptos_router = { path = "./router", version = "0.6.10" }
|
||||
leptos_meta = { path = "./meta", version = "0.6.10" }
|
||||
leptos_integration_utils = { path = "./integrations/utils", version = "0.6.10" }
|
||||
leptos_config = { path = "./leptos_config", version = "0.6.5" }
|
||||
leptos_router = { path = "./router", version = "0.6.5" }
|
||||
leptos_meta = { path = "./meta", version = "0.6.5" }
|
||||
leptos_integration_utils = { path = "./integrations/utils", version = "0.6.5" }
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
|
||||
@@ -3,5 +3,5 @@ alias = "check-all"
|
||||
|
||||
[tasks.check-all]
|
||||
command = "cargo"
|
||||
args = ["+nightly-2024-03-31", "check-all-features"]
|
||||
args = ["+nightly-2024-01-29", "check-all-features"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
@@ -8,11 +8,4 @@ args = ["fmt", "--", "--check", "--config-path", "${LEPTOS_PROJECT_DIRECTORY}"]
|
||||
[tasks.clippy-each-feature]
|
||||
dependencies = ["install-clippy"]
|
||||
command = "cargo"
|
||||
args = [
|
||||
"clippy",
|
||||
"--all-features",
|
||||
"--no-deps",
|
||||
"--",
|
||||
"-D",
|
||||
"clippy::print_stdout",
|
||||
]
|
||||
args = ["hack", "clippy", "--all", "--each-feature", "--no-dev-deps"]
|
||||
|
||||
@@ -3,5 +3,5 @@ alias = "test-all"
|
||||
|
||||
[tasks.test-all]
|
||||
command = "cargo"
|
||||
args = ["+nightly-2024-03-31", "test-all-features"]
|
||||
args = ["+nightly-2024-01-29", "test-all-features"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
@@ -5,7 +5,6 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = ""
|
||||
CARGO_MAKE_WORKSPACE_EMULATION = true
|
||||
CARGO_MAKE_CRATE_WORKSPACE_MEMBERS = [
|
||||
"action-form-error-handling",
|
||||
"animated_show",
|
||||
"counter",
|
||||
"counter_isomorphic",
|
||||
@@ -13,33 +12,27 @@ CARGO_MAKE_CRATE_WORKSPACE_MEMBERS = [
|
||||
"counters_stable",
|
||||
"counter_url_query",
|
||||
"counter_without_macros",
|
||||
"directives",
|
||||
"error_boundary",
|
||||
"errors_axum",
|
||||
"fetch",
|
||||
"hackernews",
|
||||
"hackernews_axum",
|
||||
"hackernews_islands_axum",
|
||||
"hackernews_js_fetch",
|
||||
"js-framework-benchmark",
|
||||
"login_with_token_csr_only",
|
||||
"parent_child",
|
||||
"portal",
|
||||
"router",
|
||||
"server_fns_axum",
|
||||
"session_auth_axum",
|
||||
"slots",
|
||||
"sso_auth_axum",
|
||||
"ssr_modes",
|
||||
"ssr_modes_axum",
|
||||
"suspense_tests",
|
||||
"tailwind_actix",
|
||||
"tailwind_axum",
|
||||
"tailwind_csr",
|
||||
"tailwind_axum",
|
||||
"timer",
|
||||
"todo_app_sqlite",
|
||||
"todo_app_sqlite_axum",
|
||||
"todo_app_sqlite_csr",
|
||||
"todomvc",
|
||||
]
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ clear = true
|
||||
dependencies = ["check-debug", "check-release"]
|
||||
|
||||
[tasks.check-debug]
|
||||
toolchain = "nightly-2024-03-31"
|
||||
toolchain = "nightly-2024-01-29"
|
||||
command = "cargo"
|
||||
args = ["check-all-features"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
[tasks.check-release]
|
||||
toolchain = "nightly-2024-03-31"
|
||||
toolchain = "nightly-2024-01-29"
|
||||
command = "cargo"
|
||||
args = ["check-all-features", "--release"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
@@ -4,13 +4,11 @@ dependencies = [
|
||||
"clean-trunk",
|
||||
"clean-node_modules",
|
||||
"clean-playwright",
|
||||
"clean-pkg",
|
||||
]
|
||||
|
||||
[tasks.clean-cargo]
|
||||
script = '''
|
||||
find . -type d -name target | xargs rm -rf
|
||||
'''
|
||||
command = "rm"
|
||||
args = ["-rf", "target"]
|
||||
|
||||
[tasks.clean-trunk]
|
||||
script = '''
|
||||
@@ -29,8 +27,3 @@ fi
|
||||
script = '''
|
||||
find . -name playwright-report -name playwright -name test-results | xargs rm -rf
|
||||
'''
|
||||
|
||||
[tasks.clean-pkg]
|
||||
script = '''
|
||||
find . -type d -name pkg | xargs rm -rf
|
||||
'''
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[tasks.build]
|
||||
toolchain = "nightly-2024-03-31"
|
||||
toolchain = "nightly-2024-01-29"
|
||||
command = "cargo"
|
||||
args = ["build-all-features"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
[tasks.check]
|
||||
toolchain = "nightly-2024-03-31"
|
||||
toolchain = "nightly-2024-01-29"
|
||||
command = "cargo"
|
||||
args = ["check-all-features"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
@@ -12,13 +12,13 @@ clear = true
|
||||
dependencies = ["check-debug", "check-release"]
|
||||
|
||||
[tasks.check-debug]
|
||||
toolchain = "nightly-2024-03-31"
|
||||
toolchain = "nightly-2024-01-29"
|
||||
command = "cargo"
|
||||
args = ["check-all-features"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
[tasks.check-release]
|
||||
toolchain = "nightly-2024-03-31"
|
||||
toolchain = "nightly-2024-01-29"
|
||||
command = "cargo"
|
||||
args = ["check-all-features", "--release"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
@@ -6,17 +6,9 @@ extend = [
|
||||
[tasks.integration-test]
|
||||
description = "Run integration test with automated start and stop of processes"
|
||||
env = { SPAWN_CLIENT_PROCESS = "1" }
|
||||
run_task = { name = ["start", "wait-test-stop"], parallel = true }
|
||||
dependencies = ["start", "wait-one", "test-playwright", "stop"]
|
||||
|
||||
[tasks.wait-test-stop]
|
||||
private = true
|
||||
dependencies = ["wait-server", "test-playwright", "stop"]
|
||||
|
||||
[tasks.wait-server]
|
||||
[tasks.wait-one]
|
||||
script = '''
|
||||
for run in {1..12}; do
|
||||
echo "Waiting to ensure server is started..."
|
||||
sleep 10
|
||||
done
|
||||
echo "Times up, running tests"
|
||||
sleep 1
|
||||
'''
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -25,7 +25,7 @@ leptos_router = { path = "../../router" }
|
||||
log = "0.4"
|
||||
once_cell = "1.18"
|
||||
gloo-net = { git = "https://github.com/rustwasm/gloo" }
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen = "0.2.87"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
simple_logger = "4.3"
|
||||
tracing = { version = "0.1", optional = true }
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -15,7 +15,7 @@ log = "0.4"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen = "0.2.84"
|
||||
wasm-bindgen-test = "0.3.34"
|
||||
pretty_assertions = "1.3.0"
|
||||
rstest = "0.17.0"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use leptos::{html::*, *};
|
||||
use leptos::{ev, html::*, *};
|
||||
|
||||
/// A simple counter view.
|
||||
// A component is really just a function call: it runs once to create the DOM and reactive system
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use leptos::*;
|
||||
use leptos::{For, *};
|
||||
|
||||
const MANY_COUNTERS: usize = 1000;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ console_log = "1"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen = "0.2.87"
|
||||
wasm-bindgen-test = "0.3.37"
|
||||
pretty_assertions = "1.4.0"
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::errors::AppError;
|
||||
use leptos::{logging::log, *};
|
||||
use leptos::{logging::log, Errors, *};
|
||||
#[cfg(feature = "ssr")]
|
||||
use leptos_axum::ResponseOptions;
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -5,13 +5,13 @@ extend = [
|
||||
]
|
||||
|
||||
[tasks.build]
|
||||
toolchain = "nightly-2024-03-31"
|
||||
toolchain = "nightly-2024-01-29"
|
||||
command = "cargo"
|
||||
args = ["build-all-features", "--target", "wasm32-unknown-unknown"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
[tasks.check]
|
||||
toolchain = "nightly-2024-03-31"
|
||||
toolchain = "nightly-2024-01-29"
|
||||
command = "cargo"
|
||||
args = ["check-all-features", "--target", "wasm32-unknown-unknown"]
|
||||
install_crate = "cargo-all-features"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use leptos::*;
|
||||
use leptos::{ev, *};
|
||||
|
||||
#[component]
|
||||
pub fn CredentialsForm(
|
||||
|
||||
@@ -16,7 +16,7 @@ impl AppState {
|
||||
credentials: Credentials,
|
||||
) -> Result<(), CreateUserError> {
|
||||
let Credentials { email, password } = credentials;
|
||||
let user_exists = self.users.contains_key(&email);
|
||||
let user_exists = self.users.get(&email).is_some();
|
||||
if user_exists {
|
||||
return Err(CreateUserError::UserExists);
|
||||
}
|
||||
@@ -124,7 +124,6 @@ impl EmailAddress {
|
||||
#[derive(Clone)]
|
||||
pub struct CurrentUser {
|
||||
pub email: EmailAddress,
|
||||
#[allow(dead_code)] // possibly a lint regression, this is used at line 65
|
||||
pub token: Uuid,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
CREATE TABLE IF NOT EXISTS todos
|
||||
(
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
title VARCHAR,
|
||||
completed BOOLEAN
|
||||
);
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::errors::TodoAppError;
|
||||
use leptos::*;
|
||||
use leptos::{Errors, *};
|
||||
#[cfg(feature = "ssr")]
|
||||
use leptos_axum::ResponseOptions;
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -6,13 +6,10 @@ use std::collections::HashSet;
|
||||
pub struct User {
|
||||
pub id: i64,
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub permissions: HashSet<String>,
|
||||
}
|
||||
|
||||
// Explicitly is not Serialize/Deserialize!
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct UserPasshash(String);
|
||||
|
||||
impl Default for User {
|
||||
fn default() -> Self {
|
||||
let permissions = HashSet::new();
|
||||
@@ -20,6 +17,7 @@ impl Default for User {
|
||||
Self {
|
||||
id: -1,
|
||||
username: "Guest".into(),
|
||||
password: "".into(),
|
||||
permissions,
|
||||
}
|
||||
}
|
||||
@@ -27,7 +25,7 @@ impl Default for User {
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
pub mod ssr {
|
||||
pub use super::{User, UserPasshash};
|
||||
pub use super::User;
|
||||
pub use axum_session_auth::{
|
||||
Authentication, HasPermission, SessionSqlitePool,
|
||||
};
|
||||
@@ -44,10 +42,7 @@ pub mod ssr {
|
||||
pub use bcrypt::{hash, verify, DEFAULT_COST};
|
||||
|
||||
impl User {
|
||||
pub async fn get_with_passhash(
|
||||
id: i64,
|
||||
pool: &SqlitePool,
|
||||
) -> Option<(Self, UserPasshash)> {
|
||||
pub async fn get(id: i64, pool: &SqlitePool) -> Option<Self> {
|
||||
let sqluser = sqlx::query_as::<_, SqlUser>(
|
||||
"SELECT * FROM users WHERE id = ?",
|
||||
)
|
||||
@@ -68,16 +63,10 @@ pub mod ssr {
|
||||
Some(sqluser.into_user(Some(sql_user_perms)))
|
||||
}
|
||||
|
||||
pub async fn get(id: i64, pool: &SqlitePool) -> Option<Self> {
|
||||
User::get_with_passhash(id, pool)
|
||||
.await
|
||||
.map(|(user, _)| user)
|
||||
}
|
||||
|
||||
pub async fn get_from_username_with_passhash(
|
||||
pub async fn get_from_username(
|
||||
name: String,
|
||||
pool: &SqlitePool,
|
||||
) -> Option<(Self, UserPasshash)> {
|
||||
) -> Option<Self> {
|
||||
let sqluser = sqlx::query_as::<_, SqlUser>(
|
||||
"SELECT * FROM users WHERE username = ?",
|
||||
)
|
||||
@@ -97,15 +86,6 @@ pub mod ssr {
|
||||
|
||||
Some(sqluser.into_user(Some(sql_user_perms)))
|
||||
}
|
||||
|
||||
pub async fn get_from_username(
|
||||
name: String,
|
||||
pool: &SqlitePool,
|
||||
) -> Option<Self> {
|
||||
User::get_from_username_with_passhash(name, pool)
|
||||
.await
|
||||
.map(|(user, _)| user)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Clone)]
|
||||
@@ -157,22 +137,20 @@ pub mod ssr {
|
||||
pub fn into_user(
|
||||
self,
|
||||
sql_user_perms: Option<Vec<SqlPermissionTokens>>,
|
||||
) -> (User, UserPasshash) {
|
||||
(
|
||||
User {
|
||||
id: self.id,
|
||||
username: self.username,
|
||||
permissions: if let Some(user_perms) = sql_user_perms {
|
||||
user_perms
|
||||
.into_iter()
|
||||
.map(|x| x.token)
|
||||
.collect::<HashSet<String>>()
|
||||
} else {
|
||||
HashSet::<String>::new()
|
||||
},
|
||||
) -> User {
|
||||
User {
|
||||
id: self.id,
|
||||
username: self.username,
|
||||
password: self.password,
|
||||
permissions: if let Some(user_perms) = sql_user_perms {
|
||||
user_perms
|
||||
.into_iter()
|
||||
.map(|x| x.token)
|
||||
.collect::<HashSet<String>>()
|
||||
} else {
|
||||
HashSet::<String>::new()
|
||||
},
|
||||
UserPasshash(self.password),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,12 +180,11 @@ pub async fn login(
|
||||
let pool = pool()?;
|
||||
let auth = auth()?;
|
||||
|
||||
let (user, UserPasshash(expected_passhash)) =
|
||||
User::get_from_username_with_passhash(username, &pool)
|
||||
.await
|
||||
.ok_or_else(|| ServerFnError::new("User does not exist."))?;
|
||||
let user: User = User::get_from_username(username, &pool)
|
||||
.await
|
||||
.ok_or_else(|| ServerFnError::new("User does not exist."))?;
|
||||
|
||||
match verify(password, &expected_passhash)? {
|
||||
match verify(password, &user.password)? {
|
||||
true => {
|
||||
auth.login_user(user.id);
|
||||
auth.remember_user(remember.is_some());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::errors::TodoAppError;
|
||||
use leptos::*;
|
||||
use leptos::{Errors, *};
|
||||
#[cfg(feature = "ssr")]
|
||||
use leptos_axum::ResponseOptions;
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -8,12 +8,12 @@ use axum::{
|
||||
Router,
|
||||
};
|
||||
use axum_session::{Key, SessionConfig, SessionLayer, SessionStore};
|
||||
use axum_session_auth::{AuthConfig, AuthSessionLayer};
|
||||
use axum_session_auth::{AuthConfig, AuthSessionLayer, SessionSqlitePool};
|
||||
use leptos::{get_configuration, logging::log, provide_context, view};
|
||||
use leptos_axum::{
|
||||
generate_route_list, handle_server_fns_with_context, LeptosRoutes,
|
||||
};
|
||||
use sqlx::sqlite::SqlitePoolOptions;
|
||||
use sqlx::{sqlite::SqlitePoolOptions, SqlitePool};
|
||||
use sso_auth_axum::{
|
||||
auth::*, fallback::file_and_error_handler, state::AppState,
|
||||
};
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -16,7 +16,7 @@ leptos_actix = { path = "../../integrations/actix", optional = true }
|
||||
leptos_router = { path = "../../router" }
|
||||
log = "0.4"
|
||||
simple_logger = "4"
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen = "0.2.87"
|
||||
serde = "1.0.159"
|
||||
tokio = { version = "1.29", features = ["time", "rt"], optional = true }
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
908
examples/tailwind_axum/package-lock.json
generated
Normal file
908
examples/tailwind_axum/package-lock.json
generated
Normal file
@@ -0,0 +1,908 @@
|
||||
{
|
||||
"name": "leptos-tailwind",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "leptos-tailwind",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"tailwindcss": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
|
||||
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
|
||||
"integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.0.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/set-array": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
||||
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.18",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
|
||||
"integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
|
||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "2.0.5",
|
||||
"run-parallel": "^1.1.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.stat": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.walk": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
"fastq": "^1.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/any-promise": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
|
||||
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/camelcase-css": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
||||
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.10.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar/node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/cssesc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"bin": {
|
||||
"cssesc": "bin/cssesc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/didyoumean": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
|
||||
},
|
||||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
|
||||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.2.12",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
|
||||
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
"glob-parent": "^5.1.2",
|
||||
"merge2": "^1.3.0",
|
||||
"micromatch": "^4.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-glob/node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
|
||||
"integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
|
||||
"integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-glob": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz",
|
||||
"integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==",
|
||||
"bin": {
|
||||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
||||
"integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/lines-and-columns": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/mz": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
|
||||
"dependencies": {
|
||||
"any-promise": "^1.0.0",
|
||||
"object-assign": "^4.0.1",
|
||||
"thenify-all": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-hash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pirates": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
|
||||
"integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.23",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
|
||||
"integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.6",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-import": {
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
|
||||
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.0.0",
|
||||
"read-cache": "^1.0.0",
|
||||
"resolve": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-js": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
|
||||
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
|
||||
"dependencies": {
|
||||
"camelcase-css": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12 || ^14 || >= 16"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.21"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-load-config": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz",
|
||||
"integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==",
|
||||
"dependencies": {
|
||||
"lilconfig": "^2.0.5",
|
||||
"yaml": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": ">=8.0.9",
|
||||
"ts-node": ">=9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"postcss": {
|
||||
"optional": true
|
||||
},
|
||||
"ts-node": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-nested": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
|
||||
"integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
|
||||
"dependencies": {
|
||||
"postcss-selector-parser": "^6.0.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.2.14"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-selector-parser": {
|
||||
"version": "6.0.13",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
|
||||
"integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-value-parser": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
|
||||
"dependencies": {
|
||||
"pify": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||
"integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.11.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sucrase": {
|
||||
"version": "3.32.0",
|
||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz",
|
||||
"integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"commander": "^4.0.0",
|
||||
"glob": "7.1.6",
|
||||
"lines-and-columns": "^1.1.6",
|
||||
"mz": "^2.7.0",
|
||||
"pirates": "^4.0.1",
|
||||
"ts-interface-checker": "^0.1.9"
|
||||
},
|
||||
"bin": {
|
||||
"sucrase": "bin/sucrase",
|
||||
"sucrase-node": "bin/sucrase-node"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz",
|
||||
"integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==",
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"didyoumean": "^1.2.2",
|
||||
"dlv": "^1.1.3",
|
||||
"fast-glob": "^3.2.12",
|
||||
"glob-parent": "^6.0.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"jiti": "^1.18.2",
|
||||
"lilconfig": "^2.1.0",
|
||||
"micromatch": "^4.0.5",
|
||||
"normalize-path": "^3.0.0",
|
||||
"object-hash": "^3.0.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-import": "^15.1.0",
|
||||
"postcss-js": "^4.0.1",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"postcss-selector-parser": "^6.0.11",
|
||||
"postcss-value-parser": "^4.2.0",
|
||||
"resolve": "^1.22.2",
|
||||
"sucrase": "^3.32.0"
|
||||
},
|
||||
"bin": {
|
||||
"tailwind": "lib/cli.js",
|
||||
"tailwindcss": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/thenify": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
||||
"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
|
||||
"dependencies": {
|
||||
"any-promise": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/thenify-all": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
|
||||
"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
|
||||
"dependencies": {
|
||||
"thenify": ">= 3.1.0 < 4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-interface-checker": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
|
||||
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz",
|
||||
"integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==",
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "<picture>\r <source srcset=\"https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_Solid_White.svg\" media=\"(prefers-color-scheme: dark)\">\r <img src=\"https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_RGB.svg\" alt=\"Leptos Logo\">\r </picture>",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "npx tailwindcss -i ./input.css -o ./style/output.css",
|
||||
"watch": "npx tailwindcss -i ./input.css -o ./style/output.css --watch"
|
||||
"build":"npx tailwindcss -i ./input.css -o ./style/output.css",
|
||||
"watch":"npx tailwindcss -i ./input.css -o ./style/output.css --watch"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"tailwindcss": "^3.4.1"
|
||||
"tailwindcss": "^3.3.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::errors::TodoAppError;
|
||||
use leptos::*;
|
||||
use leptos::{Errors, *};
|
||||
#[cfg(feature = "ssr")]
|
||||
use leptos_axum::ResponseOptions;
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::errors::TodoAppError;
|
||||
use leptos::*;
|
||||
use leptos::{Errors, *};
|
||||
#[cfg(feature = "ssr")]
|
||||
use leptos_axum::ResponseOptions;
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-03-31"
|
||||
channel = "nightly-2024-01-29"
|
||||
|
||||
@@ -7,8 +7,9 @@ pub struct Todos(pub Vec<Todo>);
|
||||
|
||||
const STORAGE_KEY: &str = "todos-leptos";
|
||||
|
||||
impl Default for Todos {
|
||||
fn default() -> Self {
|
||||
// Basic operations to manipulate the todo list: nothing really interesting here
|
||||
impl Todos {
|
||||
pub fn new() -> Self {
|
||||
let starting_todos =
|
||||
window()
|
||||
.local_storage()
|
||||
@@ -22,10 +23,7 @@ impl Default for Todos {
|
||||
.unwrap_or_default();
|
||||
Self(starting_todos)
|
||||
}
|
||||
}
|
||||
|
||||
// Basic operations to manipulate the todo list: nothing really interesting here
|
||||
impl Todos {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
@@ -88,6 +86,12 @@ impl Todos {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Todos {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||
pub struct Todo {
|
||||
pub id: Uuid,
|
||||
@@ -132,7 +136,7 @@ const ENTER_KEY: u32 = 13;
|
||||
#[component]
|
||||
pub fn TodoMVC() -> impl IntoView {
|
||||
// The `todos` are a signal, since we need to reactively update the list
|
||||
let (todos, set_todos) = create_signal(Todos::default());
|
||||
let (todos, set_todos) = create_signal(Todos::new());
|
||||
|
||||
// We provide a context that each <Todo/> component can use to update the list
|
||||
// Here, I'm just passing the `WriteSignal`; a <Todo/> doesn't need to read the whole list
|
||||
|
||||
@@ -1210,15 +1210,6 @@ where
|
||||
IV: IntoView + 'static,
|
||||
{
|
||||
let mut router = self;
|
||||
|
||||
// register server functions first to allow for wildcard route in Leptos's Router
|
||||
for (path, _) in server_fn::actix::server_fn_paths() {
|
||||
let additional_context = additional_context.clone();
|
||||
let handler = handle_server_fns_with_context(additional_context);
|
||||
router = router.route(path, handler);
|
||||
}
|
||||
|
||||
// register routes defined in Leptos's Router
|
||||
for listing in paths.iter() {
|
||||
let path = listing.path();
|
||||
let mode = listing.mode();
|
||||
@@ -1281,6 +1272,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// register server functions
|
||||
for (path, _) in server_fn::actix::server_fn_paths() {
|
||||
let additional_context = additional_context.clone();
|
||||
let handler = handle_server_fns_with_context(additional_context);
|
||||
router = router.route(path, handler);
|
||||
}
|
||||
|
||||
router
|
||||
}
|
||||
}
|
||||
@@ -1313,15 +1311,6 @@ impl LeptosRoutes for &mut ServiceConfig {
|
||||
IV: IntoView + 'static,
|
||||
{
|
||||
let mut router = self;
|
||||
|
||||
// register server functions first to allow for wildcard route in Leptos's Router
|
||||
for (path, _) in server_fn::actix::server_fn_paths() {
|
||||
let additional_context = additional_context.clone();
|
||||
let handler = handle_server_fns_with_context(additional_context);
|
||||
router = router.route(path, handler);
|
||||
}
|
||||
|
||||
// register routes defined in Leptos's Router
|
||||
for listing in paths.iter() {
|
||||
let path = listing.path();
|
||||
let mode = listing.mode();
|
||||
@@ -1366,6 +1355,13 @@ impl LeptosRoutes for &mut ServiceConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// register server functions
|
||||
for (path, _) in server_fn::actix::server_fn_paths() {
|
||||
let additional_context = additional_context.clone();
|
||||
let handler = handle_server_fns_with_context(additional_context);
|
||||
router = router.route(path, handler);
|
||||
}
|
||||
|
||||
router
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,17 +79,10 @@ impl ResponseParts {
|
||||
}
|
||||
|
||||
/// Allows you to override details of the HTTP response like the status code and add Headers/Cookies.
|
||||
///
|
||||
/// `ResponseOptions` is provided via context when you use most of the handlers provided in this
|
||||
/// crate, including [`.leptos_routes`](LeptosRoutes::leptos_routes),
|
||||
/// [`.leptos_routes_with_context`](LeptosRoutes::leptos_routes_with_context), [`handle_server_fns`], etc.
|
||||
/// You can find the full set of provided context types in each handler function.
|
||||
///
|
||||
/// If you provide your own handler, you will need to provide `ResponseOptions` via context
|
||||
/// yourself if you want to access it via context.
|
||||
/// ```rust,ignore
|
||||
/// ResponseOptions is stored in your server's context if you've called `.leptos_routes` on your router.
|
||||
/// ```rust
|
||||
/// #[server]
|
||||
/// pub async fn get_opts() -> Result<(), ServerFnError> {
|
||||
/// pub async fn get_opts() -> Result<(),ServerFnError> {
|
||||
/// let opts = expect_context::<leptos_axum::ResponseOptions>();
|
||||
/// Ok(())
|
||||
/// }
|
||||
@@ -302,8 +295,14 @@ async fn handle_server_fns_inner(
|
||||
// actually run the server fn
|
||||
let mut res = service.run(req).await;
|
||||
|
||||
// if it accepts text/html (i.e., is a plain form post) and doesn't already have a
|
||||
// Location set, then redirect to Referer
|
||||
// update response as needed
|
||||
let res_options = expect_context::<ResponseOptions>().0;
|
||||
let res_options_inner = res_options.read();
|
||||
let (status, mut res_headers) =
|
||||
(res_options_inner.status, res_options_inner.headers.clone());
|
||||
|
||||
// it it accepts text/html (i.e., is a plain form post) and doesn't already have a
|
||||
// Location set, then redirect to to Referer
|
||||
if accepts_html {
|
||||
if let Some(referrer) = referrer {
|
||||
let has_location = res.headers().get(LOCATION).is_some();
|
||||
@@ -314,22 +313,11 @@ async fn handle_server_fns_inner(
|
||||
}
|
||||
}
|
||||
|
||||
// update response as needed
|
||||
if let Some(res_options) = use_context::<ResponseOptions>() {
|
||||
let res_options_inner = res_options.0.read();
|
||||
let (status, mut res_headers) = (
|
||||
res_options_inner.status,
|
||||
res_options_inner.headers.clone(),
|
||||
);
|
||||
|
||||
// apply status code and headers if used changed them
|
||||
if let Some(status) = status {
|
||||
*res.status_mut() = status;
|
||||
}
|
||||
res.headers_mut().extend(res_headers.drain());
|
||||
} else {
|
||||
eprintln!("Failed to find ResponseOptions for {path}");
|
||||
// apply status code and headers if used changed them
|
||||
if let Some(status) = status {
|
||||
*res.status_mut() = status;
|
||||
}
|
||||
res.headers_mut().extend(res_headers.drain());
|
||||
|
||||
// clean up the scope
|
||||
runtime.dispose();
|
||||
@@ -1080,7 +1068,7 @@ where
|
||||
|
||||
headers.extend(res_headers.drain());
|
||||
|
||||
// This one doesn't use generate_response(), so we need to do this separately
|
||||
// This one doesn't use generate_response(), so we need to do this seperately
|
||||
if !headers.contains_key(header::CONTENT_TYPE) {
|
||||
// Set the Content Type headers on all responses. This makes Firefox show the page source
|
||||
// without complaining
|
||||
@@ -1629,30 +1617,6 @@ where
|
||||
|
||||
let mut router = self;
|
||||
|
||||
// register server functions first to allow for wildcard router path
|
||||
for (path, method) in server_fn::axum::server_fn_paths() {
|
||||
let cx_with_state = cx_with_state.clone();
|
||||
let handler = move |req: Request<Body>| async move {
|
||||
handle_server_fns_with_context(cx_with_state, req).await
|
||||
};
|
||||
router = router.route(
|
||||
path,
|
||||
match method {
|
||||
Method::GET => get(handler),
|
||||
Method::POST => post(handler),
|
||||
Method::PUT => put(handler),
|
||||
Method::DELETE => delete(handler),
|
||||
Method::PATCH => patch(handler),
|
||||
_ => {
|
||||
panic!(
|
||||
"Unsupported server function HTTP method: \
|
||||
{method:?}"
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// register router paths
|
||||
for listing in paths.iter() {
|
||||
let path = listing.path();
|
||||
@@ -1751,6 +1715,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// register server functions
|
||||
for (path, method) in server_fn::axum::server_fn_paths() {
|
||||
let cx_with_state = cx_with_state.clone();
|
||||
let handler = move |req: Request<Body>| async move {
|
||||
handle_server_fns_with_context(cx_with_state, req).await
|
||||
};
|
||||
router = router.route(
|
||||
path,
|
||||
match method {
|
||||
Method::GET => get(handler),
|
||||
Method::POST => post(handler),
|
||||
Method::PUT => put(handler),
|
||||
Method::DELETE => delete(handler),
|
||||
Method::PATCH => patch(handler),
|
||||
_ => {
|
||||
panic!(
|
||||
"Unsupported server function HTTP method: \
|
||||
{method:?}"
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
router
|
||||
}
|
||||
|
||||
|
||||
@@ -56,14 +56,9 @@ pub fn html_parts_separated(
|
||||
options: &LeptosOptions,
|
||||
meta: Option<&MetaContext>,
|
||||
) -> (String, &'static str) {
|
||||
// First check runtime env, then build time, then default:
|
||||
let pkg_path = match std::env::var("CDN_PKG_PATH").ok().map(Cow::from) {
|
||||
Some(path) => path,
|
||||
None => match option_env!("CDN_PKG_PATH").map(Cow::from) {
|
||||
Some(path) => path,
|
||||
None => format!("/{}", options.site_pkg_dir).into(),
|
||||
},
|
||||
};
|
||||
let pkg_path = option_env!("CDN_PKG_PATH")
|
||||
.map(Cow::from)
|
||||
.unwrap_or_else(|| format!("/{}", options.site_pkg_dir).into());
|
||||
let output_name = &options.output_name;
|
||||
let nonce = use_nonce();
|
||||
let nonce = nonce
|
||||
@@ -109,7 +104,7 @@ pub fn html_parts_separated(
|
||||
"() => mod.hydrate()"
|
||||
};
|
||||
|
||||
let (js_hash, wasm_hash, css_hash) = get_hashes(options);
|
||||
let (js_hash, wasm_hash, css_hash) = get_hashes(&options);
|
||||
|
||||
let head = head.replace(
|
||||
&format!("{output_name}.css"),
|
||||
@@ -155,7 +150,7 @@ fn get_hashes(options: &LeptosOptions) -> (String, String, String) {
|
||||
("css".to_string(), "".to_string()),
|
||||
]);
|
||||
|
||||
if options.hash_files {
|
||||
if options.frontend_files_content_hashes {
|
||||
let hash_path = env::current_exe()
|
||||
.map(|path| {
|
||||
path.parent().map(|p| p.to_path_buf()).unwrap_or_default()
|
||||
|
||||
@@ -16,18 +16,13 @@ leptos_macro = { workspace = true }
|
||||
leptos_reactive = { workspace = true }
|
||||
leptos_server = { workspace = true }
|
||||
leptos_config = { workspace = true }
|
||||
leptos-spin-macro = { version = "0.1", optional = true }
|
||||
leptos-spin-macro = { version="0.1", optional = true}
|
||||
tracing = "0.1"
|
||||
typed-builder = "0.18"
|
||||
typed-builder-macro = "0.18"
|
||||
serde = { version = "1", optional = true }
|
||||
serde_json = { version = "1", optional = true }
|
||||
server_fn = { workspace = true, features = [
|
||||
"form-redirects",
|
||||
"browser",
|
||||
"url",
|
||||
"cbor",
|
||||
] }
|
||||
server_fn = { workspace = true, features = ["form-redirects", "browser", "url", "cbor"] }
|
||||
web-sys = { version = "0.3.63", features = [
|
||||
"ShadowRoot",
|
||||
"ShadowRootInit",
|
||||
@@ -73,7 +68,10 @@ miniserde = ["leptos_reactive/miniserde"]
|
||||
rkyv = ["leptos_reactive/rkyv"]
|
||||
tracing = ["leptos_macro/tracing"]
|
||||
nonce = ["leptos_dom/nonce"]
|
||||
spin = ["leptos_reactive/spin", "leptos-spin-macro"]
|
||||
spin = [
|
||||
"leptos_reactive/spin",
|
||||
"leptos-spin-macro"
|
||||
]
|
||||
experimental-islands = [
|
||||
"leptos_dom/experimental-islands",
|
||||
"leptos_macro/experimental-islands",
|
||||
@@ -83,7 +81,7 @@ experimental-islands = [
|
||||
]
|
||||
trace-component-props = [
|
||||
"leptos_dom/trace-component-props",
|
||||
"leptos_macro/trace-component-props",
|
||||
"leptos_macro/trace-component-props"
|
||||
]
|
||||
|
||||
[package.metadata.cargo-all-features]
|
||||
@@ -94,10 +92,9 @@ denylist = [
|
||||
"rustls",
|
||||
"default-tls",
|
||||
"wasm-bindgen",
|
||||
"rkyv", # was causing clippy issues on nightly
|
||||
"trace-component-props",
|
||||
"spin",
|
||||
"experimental-islands",
|
||||
"experimental-islands"
|
||||
]
|
||||
skip_feature_sets = [
|
||||
[
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use crate::Children;
|
||||
use leptos_dom::{Errors, HydrationCtx, IntoView};
|
||||
use leptos_macro::{component, view};
|
||||
use leptos_reactive::{provide_context, run_as_child, signal_prelude::*};
|
||||
use leptos_reactive::{
|
||||
create_rw_signal, provide_context, run_as_child, signal_prelude::*,
|
||||
RwSignal,
|
||||
};
|
||||
|
||||
/// When you render a `Result<_, _>` in your view, in the `Err` case it will
|
||||
/// render nothing, and search up through the view tree for an `<ErrorBoundary/>`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use leptos::{component, ChildrenFn, ViewFn};
|
||||
use leptos_dom::IntoView;
|
||||
use leptos_reactive::signal_prelude::*;
|
||||
use leptos_reactive::{create_memo, signal_prelude::*};
|
||||
|
||||
/// A component that will show its children when the `when` condition is `true`,
|
||||
/// and show the fallback when it is `false`, without rerendering every time
|
||||
|
||||
@@ -173,9 +173,6 @@ where
|
||||
runtime,
|
||||
);
|
||||
|
||||
#[cfg(feature = "experimental-islands")]
|
||||
let prev_no_hydrate =
|
||||
SharedContext::no_hydrate();
|
||||
#[cfg(feature = "experimental-islands")]
|
||||
{
|
||||
SharedContext::set_no_hydrate(
|
||||
@@ -183,7 +180,7 @@ where
|
||||
);
|
||||
}
|
||||
|
||||
let rendered = with_owner(owner, {
|
||||
with_owner(owner, {
|
||||
move || {
|
||||
HydrationCtx::continue_from(
|
||||
current_id,
|
||||
@@ -197,15 +194,7 @@ where
|
||||
.render_to_string()
|
||||
.to_string()
|
||||
}
|
||||
});
|
||||
|
||||
#[cfg(feature = "experimental-islands")]
|
||||
SharedContext::set_no_hydrate(
|
||||
prev_no_hydrate,
|
||||
);
|
||||
|
||||
#[allow(clippy::let_and_return)]
|
||||
rendered
|
||||
})
|
||||
}
|
||||
},
|
||||
// in-order streaming
|
||||
@@ -216,9 +205,6 @@ where
|
||||
runtime,
|
||||
);
|
||||
|
||||
#[cfg(feature = "experimental-islands")]
|
||||
let prev_no_hydrate =
|
||||
SharedContext::no_hydrate();
|
||||
#[cfg(feature = "experimental-islands")]
|
||||
{
|
||||
SharedContext::set_no_hydrate(
|
||||
@@ -226,7 +212,7 @@ where
|
||||
);
|
||||
}
|
||||
|
||||
let rendered = with_owner(owner, {
|
||||
with_owner(owner, {
|
||||
move || {
|
||||
HydrationCtx::continue_from(
|
||||
current_id,
|
||||
@@ -239,15 +225,7 @@ where
|
||||
.into_view()
|
||||
.into_stream_chunks()
|
||||
}
|
||||
});
|
||||
|
||||
#[cfg(feature = "experimental-islands")]
|
||||
SharedContext::set_no_hydrate(
|
||||
prev_no_hydrate,
|
||||
);
|
||||
|
||||
#[allow(clippy::let_and_return)]
|
||||
rendered
|
||||
})
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -206,3 +206,5 @@ fn ssr_option() {
|
||||
|
||||
runtime.dispose();
|
||||
}
|
||||
|
||||
// TODO: remove simulated change
|
||||
|
||||
@@ -10,7 +10,7 @@ readme = "../README.md"
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
config = { version = "0.14", default-features = false, features = ["toml", "convert-case"] }
|
||||
config = { version = "0.14", default-features = false, features = ["toml"] }
|
||||
regex = "1.7.0"
|
||||
serde = { version = "1.0.151", features = ["derive"] }
|
||||
thiserror = "1.0.38"
|
||||
@@ -19,4 +19,3 @@ typed-builder = "0.18"
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1", features = ["rt", "macros"] }
|
||||
tempfile = "3"
|
||||
temp-env = { version = "0.3.6", features = ["async_closure"] }
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
pub mod errors;
|
||||
|
||||
use crate::errors::LeptosConfigError;
|
||||
use config::{Case, Config, File, FileFormat};
|
||||
use config::{Config, File, FileFormat};
|
||||
use regex::Regex;
|
||||
use std::{env::VarError, fs, net::SocketAddr, path::Path, str::FromStr};
|
||||
use std::{
|
||||
convert::TryFrom, env::VarError, fs, net::SocketAddr, path::Path,
|
||||
str::FromStr,
|
||||
};
|
||||
use typed_builder::TypedBuilder;
|
||||
|
||||
/// A Struct to allow us to parse LeptosOptions from the file. Not really needed, most interactions should
|
||||
@@ -73,9 +76,9 @@ pub struct LeptosOptions {
|
||||
pub hash_file: String,
|
||||
/// If true, hashes will be generated for all files in the site_root and added to their file names.
|
||||
/// Defaults to `true`.
|
||||
#[builder(default = default_hash_files())]
|
||||
#[serde(default = "default_hash_files")]
|
||||
pub hash_files: bool,
|
||||
#[builder(default = default_frontend_files_content_hashes())]
|
||||
#[serde(default = "default_frontend_files_content_hashes")]
|
||||
pub frontend_files_content_hashes: bool,
|
||||
}
|
||||
|
||||
impl LeptosOptions {
|
||||
@@ -115,7 +118,14 @@ impl LeptosOptions {
|
||||
)?,
|
||||
not_found_path: env_w_default("LEPTOS_NOT_FOUND_PATH", "/404")?,
|
||||
hash_file: env_w_default("LEPTOS_HASH_FILE_NAME", "hash.txt")?,
|
||||
hash_files: env_w_default("LEPTOS_HASH_FILES", "false")?.parse()?,
|
||||
frontend_files_content_hashes: env_w_default(
|
||||
"LEPTOS_FRONTEND_FILES_CONTENT_HASHES",
|
||||
"ON",
|
||||
)?
|
||||
.to_uppercase()
|
||||
.replace("ON", "true")
|
||||
.replace("OFF", "false")
|
||||
.parse()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -158,8 +168,8 @@ fn default_hash_file_name() -> String {
|
||||
"hash.txt".to_string()
|
||||
}
|
||||
|
||||
fn default_hash_files() -> bool {
|
||||
false
|
||||
fn default_frontend_files_content_hashes() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn env_wo_default(key: &str) -> Result<Option<String>, LeptosConfigError> {
|
||||
@@ -297,9 +307,7 @@ impl TryFrom<String> for ReloadWSProtocol {
|
||||
|
||||
/// Loads [LeptosOptions] from a Cargo.toml text content with layered overrides.
|
||||
/// If an env var is specified, like `LEPTOS_ENV`, it will override a setting in the file.
|
||||
pub fn get_config_from_str(
|
||||
text: &str,
|
||||
) -> Result<LeptosOptions, LeptosConfigError> {
|
||||
pub fn get_config_from_str(text: &str) -> Result<ConfFile, LeptosConfigError> {
|
||||
let re: Regex = Regex::new(r"(?m)^\[package.metadata.leptos\]").unwrap();
|
||||
let re_workspace: Regex =
|
||||
Regex::new(r"(?m)^\[\[workspace.metadata.leptos\]\]").unwrap();
|
||||
@@ -323,18 +331,14 @@ pub fn get_config_from_str(
|
||||
// so that serde error messages have right line number
|
||||
let newlines = text[..start].matches('\n').count();
|
||||
let input = "\n".repeat(newlines) + &text[start..];
|
||||
// so the settings will be interpreted as root level settings
|
||||
let toml = input.replace(metadata_name, "");
|
||||
let toml = input.replace(metadata_name, "[leptos-options]");
|
||||
let settings = Config::builder()
|
||||
// Read the "default" configuration file
|
||||
.add_source(File::from_str(&toml, FileFormat::Toml))
|
||||
// Layer on the environment-specific values.
|
||||
// Add in settings from environment variables (with a prefix of LEPTOS)
|
||||
// Add in settings from environment variables (with a prefix of LEPTOS and '_' as separator)
|
||||
// E.g. `LEPTOS_RELOAD_PORT=5001 would set `LeptosOptions.reload_port`
|
||||
.add_source(
|
||||
config::Environment::with_prefix("LEPTOS")
|
||||
.convert_case(Case::Kebab),
|
||||
)
|
||||
.add_source(config::Environment::with_prefix("LEPTOS").separator("_"))
|
||||
.build()?;
|
||||
|
||||
settings
|
||||
@@ -364,8 +368,7 @@ pub async fn get_config_from_file<P: AsRef<Path>>(
|
||||
) -> Result<ConfFile, LeptosConfigError> {
|
||||
let text = fs::read_to_string(path)
|
||||
.map_err(|_| LeptosConfigError::ConfigNotFound)?;
|
||||
let leptos_options = get_config_from_str(&text)?;
|
||||
Ok(ConfFile { leptos_options })
|
||||
get_config_from_str(&text)
|
||||
}
|
||||
|
||||
/// Loads [LeptosOptions] from environment variables or rely on the defaults
|
||||
|
||||
@@ -30,53 +30,44 @@ fn ws_from_str_test() {
|
||||
|
||||
#[test]
|
||||
fn env_w_default_test() {
|
||||
_ = temp_env::with_var("LEPTOS_CONFIG_ENV_TEST", Some("custom"), || {
|
||||
assert_eq!(
|
||||
env_w_default("LEPTOS_CONFIG_ENV_TEST", "default").unwrap(),
|
||||
String::from("custom")
|
||||
);
|
||||
});
|
||||
|
||||
_ = temp_env::with_var_unset("LEPTOS_CONFIG_ENV_TEST", || {
|
||||
assert_eq!(
|
||||
env_w_default("LEPTOS_CONFIG_ENV_TEST", "default").unwrap(),
|
||||
String::from("default")
|
||||
);
|
||||
});
|
||||
std::env::set_var("LEPTOS_CONFIG_ENV_TEST", "custom");
|
||||
assert_eq!(
|
||||
env_w_default("LEPTOS_CONFIG_ENV_TEST", "default").unwrap(),
|
||||
String::from("custom")
|
||||
);
|
||||
std::env::remove_var("LEPTOS_CONFIG_ENV_TEST");
|
||||
assert_eq!(
|
||||
env_w_default("LEPTOS_CONFIG_ENV_TEST", "default").unwrap(),
|
||||
String::from("default")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn env_wo_default_test() {
|
||||
_ = temp_env::with_var("LEPTOS_CONFIG_ENV_TEST", Some("custom"), || {
|
||||
assert_eq!(
|
||||
env_wo_default("LEPTOS_CONFIG_ENV_TEST").unwrap(),
|
||||
Some(String::from("custom"))
|
||||
);
|
||||
});
|
||||
|
||||
_ = temp_env::with_var_unset("LEPTOS_CONFIG_ENV_TEST", || {
|
||||
assert_eq!(env_wo_default("LEPTOS_CONFIG_ENV_TEST").unwrap(), None);
|
||||
});
|
||||
std::env::set_var("LEPTOS_CONFIG_ENV_TEST", "custom");
|
||||
assert_eq!(
|
||||
env_wo_default("LEPTOS_CONFIG_ENV_TEST").unwrap(),
|
||||
Some(String::from("custom"))
|
||||
);
|
||||
std::env::remove_var("LEPTOS_CONFIG_ENV_TEST");
|
||||
assert_eq!(env_wo_default("LEPTOS_CONFIG_ENV_TEST").unwrap(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_from_env_test() {
|
||||
// Test config values from environment variables
|
||||
let config = temp_env::with_vars(
|
||||
[
|
||||
("LEPTOS_OUTPUT_NAME", Some("app_test")),
|
||||
("LEPTOS_SITE_ROOT", Some("my_target/site")),
|
||||
("LEPTOS_SITE_PKG_DIR", Some("my_pkg")),
|
||||
("LEPTOS_SITE_ADDR", Some("0.0.0.0:80")),
|
||||
("LEPTOS_RELOAD_PORT", Some("8080")),
|
||||
("LEPTOS_RELOAD_EXTERNAL_PORT", Some("8080")),
|
||||
("LEPTOS_ENV", Some("PROD")),
|
||||
("LEPTOS_RELOAD_WS_PROTOCOL", Some("WSS")),
|
||||
],
|
||||
|| LeptosOptions::try_from_env().unwrap(),
|
||||
);
|
||||
std::env::set_var("LEPTOS_OUTPUT_NAME", "app_test");
|
||||
std::env::set_var("LEPTOS_SITE_ROOT", "my_target/site");
|
||||
std::env::set_var("LEPTOS_SITE_PKG_DIR", "my_pkg");
|
||||
std::env::set_var("LEPTOS_SITE_ADDR", "0.0.0.0:80");
|
||||
std::env::set_var("LEPTOS_RELOAD_PORT", "8080");
|
||||
std::env::set_var("LEPTOS_RELOAD_EXTERNAL_PORT", "8080");
|
||||
std::env::set_var("LEPTOS_ENV", "PROD");
|
||||
std::env::set_var("LEPTOS_RELOAD_WS_PROTOCOL", "WSS");
|
||||
|
||||
let config = LeptosOptions::try_from_env().unwrap();
|
||||
assert_eq!(config.output_name, "app_test");
|
||||
|
||||
assert_eq!(config.site_root, "my_target/site");
|
||||
assert_eq!(config.site_pkg_dir, "my_pkg");
|
||||
assert_eq!(
|
||||
|
||||
@@ -23,7 +23,13 @@ env = "PROD"
|
||||
|
||||
const CARGO_TOML_CONTENT_ERR: &str = r#"\
|
||||
[package.metadata.leptos]
|
||||
- invalid toml -
|
||||
_output-name = "app-test"
|
||||
_site-root = "my_target/site"
|
||||
_site-pkg-dir = "my_pkg"
|
||||
_site-addr = "0.0.0.0:80"
|
||||
_reload-port = "8080"
|
||||
_reload-external-port = "8080"
|
||||
_env = "PROD"
|
||||
"#;
|
||||
|
||||
#[tokio::test]
|
||||
@@ -37,23 +43,10 @@ async fn get_configuration_from_file_ok() {
|
||||
let path: &Path = cargo_tmp.as_ref();
|
||||
let path_s = path.to_string_lossy().to_string();
|
||||
|
||||
let config = temp_env::async_with_vars(
|
||||
[
|
||||
("LEPTOS_OUTPUT_NAME", None::<&str>),
|
||||
("LEPTOS_SITE_ROOT", None::<&str>),
|
||||
("LEPTOS_SITE_PKG_DIR", None::<&str>),
|
||||
("LEPTOS_SITE_ADDR", None::<&str>),
|
||||
("LEPTOS_RELOAD_PORT", None::<&str>),
|
||||
("LEPTOS_RELOAD_EXTERNAL_PORT", None::<&str>),
|
||||
],
|
||||
async {
|
||||
get_configuration(Some(&path_s))
|
||||
.await
|
||||
.unwrap()
|
||||
.leptos_options
|
||||
},
|
||||
)
|
||||
.await;
|
||||
let config = get_configuration(Some(&path_s))
|
||||
.await
|
||||
.unwrap()
|
||||
.leptos_options;
|
||||
|
||||
assert_eq!(config.output_name, "app-test");
|
||||
assert_eq!(config.site_root, "my_target/site");
|
||||
@@ -98,23 +91,10 @@ async fn get_config_from_file_ok() {
|
||||
write!(output, "{CARGO_TOML_CONTENT_OK}").unwrap();
|
||||
}
|
||||
|
||||
let config = temp_env::async_with_vars(
|
||||
[
|
||||
("LEPTOS_OUTPUT_NAME", None::<&str>),
|
||||
("LEPTOS_SITE_ROOT", None::<&str>),
|
||||
("LEPTOS_SITE_PKG_DIR", None::<&str>),
|
||||
("LEPTOS_SITE_ADDR", None::<&str>),
|
||||
("LEPTOS_RELOAD_PORT", None::<&str>),
|
||||
("LEPTOS_RELOAD_EXTERNAL_PORT", None::<&str>),
|
||||
],
|
||||
async {
|
||||
get_config_from_file(&cargo_tmp)
|
||||
.await
|
||||
.unwrap()
|
||||
.leptos_options
|
||||
},
|
||||
)
|
||||
.await;
|
||||
let config = get_config_from_file(&cargo_tmp)
|
||||
.await
|
||||
.unwrap()
|
||||
.leptos_options;
|
||||
|
||||
assert_eq!(config.output_name, "app-test");
|
||||
assert_eq!(config.site_root, "my_target/site");
|
||||
@@ -149,18 +129,9 @@ async fn get_config_from_file_empty() {
|
||||
|
||||
#[test]
|
||||
fn get_config_from_str_content() {
|
||||
let config = temp_env::with_vars_unset(
|
||||
[
|
||||
"LEPTOS_OUTPUT_NAME",
|
||||
"LEPTOS_SITE_ROOT",
|
||||
"LEPTOS_SITE_PKG_DIR",
|
||||
"LEPTOS_SITE_ADDR",
|
||||
"LEPTOS_RELOAD_PORT",
|
||||
"LEPTOS_RELOAD_EXTERNAL_PORT",
|
||||
],
|
||||
|| get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(),
|
||||
);
|
||||
|
||||
let config = get_config_from_str(CARGO_TOML_CONTENT_OK)
|
||||
.unwrap()
|
||||
.leptos_options;
|
||||
assert_eq!(config.output_name, "app-test");
|
||||
assert_eq!(config.site_root, "my_target/site");
|
||||
assert_eq!(config.site_pkg_dir, "my_pkg");
|
||||
@@ -175,20 +146,16 @@ fn get_config_from_str_content() {
|
||||
#[tokio::test]
|
||||
async fn get_config_from_env() {
|
||||
// Test config values from environment variables
|
||||
let config = temp_env::async_with_vars(
|
||||
[
|
||||
("LEPTOS_OUTPUT_NAME", Some("app-test")),
|
||||
("LEPTOS_SITE_ROOT", Some("my_target/site")),
|
||||
("LEPTOS_SITE_PKG_DIR", Some("my_pkg")),
|
||||
("LEPTOS_SITE_ADDR", Some("0.0.0.0:80")),
|
||||
("LEPTOS_RELOAD_PORT", Some("8080")),
|
||||
("LEPTOS_RELOAD_EXTERNAL_PORT", Some("8080")),
|
||||
],
|
||||
async { get_configuration(None).await.unwrap().leptos_options },
|
||||
)
|
||||
.await;
|
||||
std::env::set_var("LEPTOS_OUTPUT_NAME", "app-test");
|
||||
std::env::set_var("LEPTOS_SITE_ROOT", "my_target/site");
|
||||
std::env::set_var("LEPTOS_SITE_PKG_DIR", "my_pkg");
|
||||
std::env::set_var("LEPTOS_SITE_ADDR", "0.0.0.0:80");
|
||||
std::env::set_var("LEPTOS_RELOAD_PORT", "8080");
|
||||
std::env::set_var("LEPTOS_RELOAD_EXTERNAL_PORT", "8080");
|
||||
|
||||
let config = get_configuration(None).await.unwrap().leptos_options;
|
||||
assert_eq!(config.output_name, "app-test");
|
||||
|
||||
assert_eq!(config.site_root, "my_target/site");
|
||||
assert_eq!(config.site_pkg_dir, "my_pkg");
|
||||
assert_eq!(
|
||||
@@ -199,19 +166,13 @@ async fn get_config_from_env() {
|
||||
assert_eq!(config.reload_external_port, Some(8080));
|
||||
|
||||
// Test default config values
|
||||
let config = temp_env::async_with_vars(
|
||||
[
|
||||
("LEPTOS_OUTPUT_NAME", None::<&str>),
|
||||
("LEPTOS_SITE_ROOT", None::<&str>),
|
||||
("LEPTOS_SITE_PKG_DIR", None::<&str>),
|
||||
("LEPTOS_SITE_ADDR", None::<&str>),
|
||||
("LEPTOS_RELOAD_PORT", None::<&str>),
|
||||
("LEPTOS_RELOAD_EXTERNAL_PORT", None::<&str>),
|
||||
],
|
||||
async { get_configuration(None).await.unwrap().leptos_options },
|
||||
)
|
||||
.await;
|
||||
std::env::remove_var("LEPTOS_SITE_ROOT");
|
||||
std::env::remove_var("LEPTOS_SITE_PKG_DIR");
|
||||
std::env::remove_var("LEPTOS_SITE_ADDR");
|
||||
std::env::remove_var("LEPTOS_RELOAD_PORT");
|
||||
std::env::set_var("LEPTOS_RELOAD_EXTERNAL_PORT", "443");
|
||||
|
||||
let config = get_configuration(None).await.unwrap().leptos_options;
|
||||
assert_eq!(config.site_root, "target/site");
|
||||
assert_eq!(config.site_pkg_dir, "pkg");
|
||||
assert_eq!(
|
||||
@@ -219,7 +180,7 @@ async fn get_config_from_env() {
|
||||
SocketAddr::from_str("127.0.0.1:3000").unwrap()
|
||||
);
|
||||
assert_eq!(config.reload_port, 3001);
|
||||
assert_eq!(config.reload_external_port, None);
|
||||
assert_eq!(config.reload_external_port, Some(443));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -236,52 +197,3 @@ fn leptos_options_builder_default() {
|
||||
assert_eq!(conf.reload_port, 3001);
|
||||
assert_eq!(conf.reload_external_port, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn environment_variable_override() {
|
||||
// first check without variables set
|
||||
let config = temp_env::with_vars_unset(
|
||||
[
|
||||
"LEPTOS_OUTPUT_NAME",
|
||||
"LEPTOS_SITE_ROOT",
|
||||
"LEPTOS_SITE_PKG_DIR",
|
||||
"LEPTOS_SITE_ADDR",
|
||||
"LEPTOS_RELOAD_PORT",
|
||||
"LEPTOS_RELOAD_EXTERNAL_PORT",
|
||||
],
|
||||
|| get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(config.output_name, "app-test");
|
||||
assert_eq!(config.site_root, "my_target/site");
|
||||
assert_eq!(config.site_pkg_dir, "my_pkg");
|
||||
assert_eq!(
|
||||
config.site_addr,
|
||||
SocketAddr::from_str("0.0.0.0:80").unwrap()
|
||||
);
|
||||
assert_eq!(config.reload_port, 8080);
|
||||
assert_eq!(config.reload_external_port, Some(8080));
|
||||
|
||||
// check the override
|
||||
let config = temp_env::with_vars(
|
||||
[
|
||||
("LEPTOS_OUTPUT_NAME", Some("app-test2")),
|
||||
("LEPTOS_SITE_ROOT", Some("my_target/site2")),
|
||||
("LEPTOS_SITE_PKG_DIR", Some("my_pkg2")),
|
||||
("LEPTOS_SITE_ADDR", Some("0.0.0.0:82")),
|
||||
("LEPTOS_RELOAD_PORT", Some("8082")),
|
||||
("LEPTOS_RELOAD_EXTERNAL_PORT", Some("8082")),
|
||||
],
|
||||
|| get_config_from_str(CARGO_TOML_CONTENT_OK).unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(config.output_name, "app-test2");
|
||||
assert_eq!(config.site_root, "my_target/site2");
|
||||
assert_eq!(config.site_pkg_dir, "my_pkg2");
|
||||
assert_eq!(
|
||||
config.site_addr,
|
||||
SocketAddr::from_str("0.0.0.0:82").unwrap()
|
||||
);
|
||||
assert_eq!(config.reload_port, 8082);
|
||||
assert_eq!(config.reload_external_port, Some(8082));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-recursion = "1"
|
||||
base64 = { version = "0.22", optional = true }
|
||||
base64 = { version = "0.21", optional = true }
|
||||
cfg-if = "1"
|
||||
drain_filter_polyfill = "0.1"
|
||||
futures = "0.3"
|
||||
|
||||
@@ -516,10 +516,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
struct HashRun<T>(T);
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
impl<T> fmt::Debug for HashRun<T> {
|
||||
#[inline]
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -1067,7 +1065,7 @@ fn unpack_moves(diff: &Diff) -> (Vec<DiffOpMove>, Vec<DiffOpAdd>) {
|
||||
// ]
|
||||
// );
|
||||
|
||||
// // Now we're going to do the same as above, just with more items
|
||||
// // Now we're going to to the same as above, just with more items
|
||||
// //
|
||||
// // A = 1
|
||||
// // B = 2, 3
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{HydrationCtx, IntoView};
|
||||
use cfg_if::cfg_if;
|
||||
use leptos_reactive::{signal_prelude::*, use_context};
|
||||
use leptos_reactive::{signal_prelude::*, use_context, RwSignal};
|
||||
use server_fn::error::Error;
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
|
||||
|
||||
@@ -70,12 +70,6 @@ pub fn add_event_listener<E>(
|
||||
|
||||
let cb = Closure::wrap(cb as Box<dyn FnMut(E)>).into_js_value();
|
||||
let key = intern(&key);
|
||||
debug_assert_eq!(
|
||||
Ok(false),
|
||||
js_sys::Reflect::has(target, &JsValue::from_str(&key)),
|
||||
"Error while adding {key} event listener, a listener of type {key} \
|
||||
already present."
|
||||
);
|
||||
_ = js_sys::Reflect::set(target, &JsValue::from_str(&key), &cb);
|
||||
add_delegated_event_listener(&key, event_name, options);
|
||||
}
|
||||
@@ -156,10 +150,7 @@ pub(crate) fn add_delegated_event_listener(
|
||||
if !maybe_handler.is_undefined() {
|
||||
let f = maybe_handler
|
||||
.unchecked_ref::<js_sys::Function>();
|
||||
|
||||
if let Err(e) = f.call1(&node, &ev) {
|
||||
wasm_bindgen::throw_val(e);
|
||||
}
|
||||
let _ = f.call1(&node, &ev);
|
||||
|
||||
if ev.cancel_bubble() {
|
||||
return;
|
||||
|
||||
@@ -39,13 +39,7 @@ pub fn location_hash() -> Option<String> {
|
||||
if is_server() {
|
||||
None
|
||||
} else {
|
||||
location()
|
||||
.hash()
|
||||
.ok()
|
||||
.map(|hash| match hash.chars().next() {
|
||||
Some('#') => hash[1..].to_string(),
|
||||
_ => hash,
|
||||
})
|
||||
location().hash().ok().map(|hash| hash.replace('#', ""))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -771,26 +771,9 @@ impl View {
|
||||
});
|
||||
}
|
||||
Self::CoreComponent(c) => match c {
|
||||
CoreComponent::DynChild(d) => {
|
||||
if let Some(subview) = *d.child.take() {
|
||||
let subview = subview.on(event, event_handler);
|
||||
d.child.replace(Box::new(Some(subview)));
|
||||
}
|
||||
}
|
||||
CoreComponent::Each(each) => {
|
||||
let event_handler = Rc::new(RefCell::new(event_handler));
|
||||
let new_children = each.children.take().into_iter().map(|item| {
|
||||
if let Some(mut item) = item {
|
||||
let event_handler = Rc::clone(&event_handler);
|
||||
item.child = item.child.on(event.clone(), Box::new(move |e| event_handler.borrow_mut()(e)));
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
each.children.replace(new_children);
|
||||
}
|
||||
CoreComponent::Unit(_) => {}
|
||||
CoreComponent::DynChild(_) => {}
|
||||
CoreComponent::Each(_) => {}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ macro_rules! debug_warn {
|
||||
/// Log a string to the console (in the browser)
|
||||
/// or via `println!()` (if not in the browser).
|
||||
pub fn console_log(s: &str) {
|
||||
#[allow(clippy::print_stdout)]
|
||||
if is_server() {
|
||||
println!("{s}");
|
||||
} else {
|
||||
|
||||
@@ -155,8 +155,9 @@ fn match_serialize() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::needless_borrow)]
|
||||
fn match_no_serialize() {
|
||||
#![allow(clippy::needless_borrow)]
|
||||
|
||||
struct CustomStruct {
|
||||
field: &'static str,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::{html::ElementDescriptor, HtmlElement};
|
||||
use leptos_reactive::{create_render_effect, signal_prelude::*};
|
||||
use leptos_reactive::{
|
||||
create_render_effect, create_rw_signal, signal_prelude::*, RwSignal,
|
||||
};
|
||||
use std::cell::Cell;
|
||||
|
||||
/// Contains a shared reference to a DOM node created while using the `view`
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
use cfg_if::cfg_if;
|
||||
use futures::{stream::FuturesUnordered, Future, Stream, StreamExt};
|
||||
use itertools::Itertools;
|
||||
use leptos_reactive::*;
|
||||
use leptos_reactive::{Oco, *};
|
||||
use std::pin::Pin;
|
||||
|
||||
type PinnedFuture<T> = Pin<Box<dyn Future<Output = T>>>;
|
||||
|
||||
@@ -78,20 +78,12 @@ impl ViewMacros {
|
||||
for view in visitor.views {
|
||||
let span = view.span();
|
||||
let id = span_to_stable_id(path, span.start().line);
|
||||
if view.tokens.is_empty() {
|
||||
views.push(MacroInvocation {
|
||||
id,
|
||||
template: LNode::Fragment(Vec::new()),
|
||||
});
|
||||
} else {
|
||||
let tokens = view.tokens.clone().into_iter();
|
||||
// TODO handle class = ...
|
||||
let rsx = rstml::parse2(
|
||||
tokens.collect::<proc_macro2::TokenStream>(),
|
||||
)?;
|
||||
let template = LNode::parse_view(rsx)?;
|
||||
views.push(MacroInvocation { id, template });
|
||||
}
|
||||
let tokens = view.tokens.clone().into_iter();
|
||||
// TODO handle class = ...
|
||||
let rsx =
|
||||
rstml::parse2(tokens.collect::<proc_macro2::TokenStream>())?;
|
||||
let template = LNode::parse_view(rsx)?;
|
||||
views.push(MacroInvocation { id, template });
|
||||
}
|
||||
Ok(views)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ rust-version.workspace = true
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
attribute-derive = { version = "0.9", features = ["syn-full"]}
|
||||
attribute-derive = { version = "0.8", features = ["syn-full"] }
|
||||
cfg-if = "1"
|
||||
html-escape = "0.2"
|
||||
itertools = "0.12"
|
||||
|
||||
@@ -11,13 +11,13 @@ dependencies = [
|
||||
[tasks.test-leptos_macro-example]
|
||||
description = "Tests the leptos_macro/example to check if macro handles doc comments correctly"
|
||||
command = "cargo"
|
||||
args = ["+nightly-2024-03-31", "test", "--doc"]
|
||||
args = ["+nightly-2024-01-29", "test", "--doc"]
|
||||
cwd = "example"
|
||||
install_crate = false
|
||||
|
||||
[tasks.doc-leptos_macro-example]
|
||||
description = "Docs the leptos_macro/example to check if macro handles doc comments correctly"
|
||||
command = "cargo"
|
||||
args = ["+nightly-2024-03-31", "doc"]
|
||||
args = ["+nightly-2024-01-29", "doc"]
|
||||
cwd = "example"
|
||||
install_crate = false
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use attribute_derive::FromAttr;
|
||||
use attribute_derive::Attribute as AttributeDerive;
|
||||
use convert_case::{
|
||||
Case::{Pascal, Snake},
|
||||
Casing,
|
||||
@@ -447,7 +447,7 @@ impl ToTokens for Model {
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[::leptos::wasm_bindgen::prelude::wasm_bindgen(wasm_bindgen = ::leptos::wasm_bindgen)]
|
||||
#[::leptos::wasm_bindgen::prelude::wasm_bindgen]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn #hydrate_fn_name(el: ::leptos::web_sys::HtmlElement) {
|
||||
if let Some(Ok(key)) = el.dataset().get(::leptos::wasm_bindgen::intern("hkc")).map(|key| std::str::FromStr::from_str(&key)) {
|
||||
@@ -688,7 +688,7 @@ impl Docs {
|
||||
const RSX_START: &str = "# ::leptos::view! {";
|
||||
const RSX_END: &str = "# };";
|
||||
|
||||
// Separated out of chain to allow rustfmt to work
|
||||
// Seperated out of chain to allow rustfmt to work
|
||||
let map = |(doc, span): (String, Span)| {
|
||||
doc.split('\n')
|
||||
.map(str::trim_end)
|
||||
@@ -705,8 +705,8 @@ impl Docs {
|
||||
{
|
||||
view_code_fence_state = ViewCodeFenceState::Rust;
|
||||
let view = trimmed_doc.find('v').unwrap();
|
||||
trimmed_doc[..view].clone_into(&mut quotes);
|
||||
leading_ws.clone_into(&mut quote_ws);
|
||||
quotes = trimmed_doc[..view].to_owned();
|
||||
quote_ws = leading_ws.to_owned();
|
||||
let rust_options = &trimmed_doc
|
||||
[view + "view".len()..]
|
||||
.trim_start();
|
||||
@@ -808,7 +808,7 @@ impl Docs {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromAttr)]
|
||||
#[derive(Clone, Debug, AttributeDerive)]
|
||||
#[attribute(ident = prop)]
|
||||
struct PropOpt {
|
||||
#[attribute(conflicts = [optional_no_strip, strip_option])]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::component::{
|
||||
convert_from_snake_case, drain_filter, is_option, unwrap_option, Docs,
|
||||
};
|
||||
use attribute_derive::FromAttr;
|
||||
use attribute_derive::Attribute as AttributeDerive;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{quote, ToTokens, TokenStreamExt};
|
||||
use syn::{
|
||||
@@ -65,10 +65,8 @@ impl ToTokens for Model {
|
||||
body,
|
||||
} = self;
|
||||
|
||||
let (impl_generics, generics, where_clause) =
|
||||
body.generics.split_for_impl();
|
||||
let (_, generics, where_clause) = body.generics.split_for_impl();
|
||||
|
||||
let builder_name = quote::format_ident!("{name}Builder");
|
||||
let prop_builder_fields = prop_builder_fields(vis, props);
|
||||
let prop_docs = generate_prop_docs(props);
|
||||
let builder_name_doc = LitStr::new(
|
||||
@@ -76,39 +74,6 @@ impl ToTokens for Model {
|
||||
name.span(),
|
||||
);
|
||||
|
||||
let count = props
|
||||
.iter()
|
||||
.filter(
|
||||
|Prop {
|
||||
prop_opts: PropOpt { attrs, .. },
|
||||
..
|
||||
}| *attrs,
|
||||
)
|
||||
.count();
|
||||
|
||||
let dyn_attrs_props = props
|
||||
.iter()
|
||||
.filter(
|
||||
|Prop {
|
||||
prop_opts: PropOpt { attrs, .. },
|
||||
..
|
||||
}| *attrs,
|
||||
)
|
||||
.enumerate()
|
||||
.map(|(idx, Prop { name, .. })| {
|
||||
let ident = &name;
|
||||
if idx < count - 1 {
|
||||
quote! {
|
||||
self.#ident = v.clone().into();
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
self.#ident = v.into();
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect::<TokenStream>();
|
||||
|
||||
let output = quote! {
|
||||
#[doc = #builder_name_doc]
|
||||
#[doc = ""]
|
||||
@@ -125,20 +90,6 @@ impl ToTokens for Model {
|
||||
vec![value]
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics ::leptos::Props for #name #generics #where_clause {
|
||||
type Builder = #builder_name #generics;
|
||||
fn builder() -> Self::Builder {
|
||||
#name::builder()
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics ::leptos::DynAttrs for #name #generics #where_clause {
|
||||
fn dyn_attrs(mut self, v: Vec<(&'static str, ::leptos::Attribute)>) -> Self {
|
||||
#dyn_attrs_props
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tokens.append_all(output)
|
||||
@@ -179,7 +130,7 @@ impl Prop {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromAttr)]
|
||||
#[derive(Clone, Debug, AttributeDerive)]
|
||||
#[attribute(ident = prop)]
|
||||
struct PropOpt {
|
||||
#[attribute(conflicts = [optional_no_strip, strip_option])]
|
||||
@@ -191,7 +142,6 @@ struct PropOpt {
|
||||
#[attribute(example = "5 * 10")]
|
||||
pub default: Option<syn::Expr>,
|
||||
pub into: bool,
|
||||
pub attrs: bool,
|
||||
}
|
||||
|
||||
struct TypedBuilderOpts {
|
||||
@@ -204,7 +154,7 @@ struct TypedBuilderOpts {
|
||||
impl TypedBuilderOpts {
|
||||
pub fn from_opts(opts: &PropOpt, is_ty_option: bool) -> Self {
|
||||
Self {
|
||||
default: opts.optional || opts.optional_no_strip || opts.attrs,
|
||||
default: opts.optional || opts.optional_no_strip,
|
||||
default_with_value: opts.default.clone(),
|
||||
strip_option: opts.strip_option || opts.optional && is_ty_option,
|
||||
into: opts.into,
|
||||
|
||||
@@ -429,21 +429,6 @@ fn attribute_to_tokens_ssr<'a>(
|
||||
{ _ = #value; }
|
||||
});
|
||||
}
|
||||
} else if let Some(directive_name) = name.strip_prefix("use:") {
|
||||
let handler = syn::Ident::new(directive_name, attr.key.span());
|
||||
let value = attr.value();
|
||||
let value = value.map(|value| {
|
||||
quote! {
|
||||
_ = #value;
|
||||
}
|
||||
});
|
||||
exprs_for_compiler.push(quote! {
|
||||
#[allow(unused_braces)]
|
||||
{
|
||||
_ = #handler;
|
||||
#value
|
||||
}
|
||||
});
|
||||
} else if name == "inner_html" {
|
||||
return attr.value();
|
||||
} else {
|
||||
|
||||
@@ -50,7 +50,6 @@ pub(crate) fn slot_to_tokens(
|
||||
.filter(|attr| {
|
||||
!attr.key.to_string().starts_with("let:")
|
||||
&& !attr.key.to_string().starts_with("clone:")
|
||||
&& !attr.key.to_string().starts_with("attr:")
|
||||
})
|
||||
.map(|attr| {
|
||||
let name = &attr.key;
|
||||
@@ -87,24 +86,6 @@ pub(crate) fn slot_to_tokens(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let dyn_attrs = attrs
|
||||
.filter(|attr| attr.key.to_string().starts_with("attr:"))
|
||||
.filter_map(|attr| {
|
||||
let name = &attr.key.to_string();
|
||||
let name = name.strip_prefix("attr:");
|
||||
let value = attr.value().map(|v| {
|
||||
quote! { #v }
|
||||
})?;
|
||||
Some(quote! { (#name, ::leptos::IntoAttribute::into_attribute(#value)) })
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let dyn_attrs = if dyn_attrs.is_empty() {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! { .dyn_attrs(vec![#(#dyn_attrs),*]) }
|
||||
};
|
||||
|
||||
let mut slots = HashMap::new();
|
||||
let children = if node.children.is_empty() {
|
||||
quote! {}
|
||||
@@ -178,7 +159,6 @@ pub(crate) fn slot_to_tokens(
|
||||
#(#slots)*
|
||||
#children
|
||||
.build()
|
||||
#dyn_attrs
|
||||
.into(),
|
||||
};
|
||||
|
||||
|
||||
@@ -38,22 +38,16 @@ error: `optional_no_strip` conflicts with mutually exclusive `strip_option`
|
||||
30 | #[prop(optional_no_strip, strip_option)] conflicting: bool,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unexpected end of input, expected `=` or `(`
|
||||
|
||||
= help: try `#[prop(default = 5 * 10)]`
|
||||
--> tests/ui/component.rs:35:1
|
||||
error: unexpected end of input, expected assignment `=`
|
||||
--> tests/ui/component.rs:36:40
|
||||
|
|
||||
35 | #[component]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the attribute macro `component` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
36 | fn default_without_value(#[prop(default)] default: bool) -> impl IntoView {
|
||||
| ^
|
||||
|
||||
error: unexpected end of input, expected one of: identifier, `::`, `<`, `_`, literal, `const`, `ref`, `mut`, `&`, parentheses, square brackets, `..`, `const`
|
||||
|
||||
= help: try `#[prop(default = 5 * 10)]`
|
||||
--> tests/ui/component.rs:40:1
|
||||
= help: try `#[prop(default=5 * 10)]`
|
||||
--> tests/ui/component.rs:42:22
|
||||
|
|
||||
40 | #[component]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the attribute macro `component` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
42 | #[prop(default= |)] default: bool,
|
||||
| ^
|
||||
|
||||
@@ -30,22 +30,16 @@ error: `optional_no_strip` conflicts with mutually exclusive `strip_option`
|
||||
25 | #[prop(optional_no_strip, strip_option)] conflicting: bool,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unexpected end of input, expected `=` or `(`
|
||||
|
||||
= help: try `#[prop(default = 5 * 10)]`
|
||||
--> tests/ui/component_absolute.rs:30:1
|
||||
error: unexpected end of input, expected assignment `=`
|
||||
--> tests/ui/component_absolute.rs:32:19
|
||||
|
|
||||
30 | #[::leptos::component]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the attribute macro `::leptos::component` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
32 | #[prop(default)] default: bool,
|
||||
| ^
|
||||
|
||||
error: unexpected end of input, expected one of: identifier, `::`, `<`, `_`, literal, `const`, `ref`, `mut`, `&`, parentheses, square brackets, `..`, `const`
|
||||
|
||||
= help: try `#[prop(default = 5 * 10)]`
|
||||
--> tests/ui/component_absolute.rs:37:1
|
||||
= help: try `#[prop(default=5 * 10)]`
|
||||
--> tests/ui/component_absolute.rs:39:22
|
||||
|
|
||||
37 | #[::leptos::component]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the attribute macro `::leptos::component` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
39 | #[prop(default= |)] default: bool,
|
||||
| ^
|
||||
|
||||
@@ -28,7 +28,7 @@ rustc-hash = "1"
|
||||
serde-wasm-bindgen = "0.6"
|
||||
serde_json = "1"
|
||||
spin-sdk = { version = "2", optional = true }
|
||||
base64 = "0.22"
|
||||
base64 = "0.21"
|
||||
thiserror = "1"
|
||||
tokio = { version = "1", features = [
|
||||
"rt",
|
||||
@@ -72,7 +72,7 @@ hydrate = [
|
||||
"dep:web-sys",
|
||||
]
|
||||
ssr = ["dep:tokio"]
|
||||
nightly = [] #["rkyv?/copy"] # not working on more recent nightlys
|
||||
nightly = ["rkyv?/copy"]
|
||||
serde = []
|
||||
serde-lite = ["dep:serde-lite"]
|
||||
miniserde = ["dep:miniserde"]
|
||||
@@ -81,7 +81,7 @@ experimental-islands = []
|
||||
spin = ["ssr", "dep:spin-sdk"]
|
||||
|
||||
[package.metadata.cargo-all-features]
|
||||
denylist = ["nightly", "rkyv"]
|
||||
denylist = ["nightly"]
|
||||
skip_feature_sets = [
|
||||
[
|
||||
"csr",
|
||||
|
||||
@@ -238,7 +238,7 @@ mod tests {
|
||||
fn clone_callback() {
|
||||
let rt = create_runtime();
|
||||
let callback = Callback::new(move |_no_clone: NoClone| NoClone {});
|
||||
let _cloned = callback;
|
||||
let _cloned = callback.clone();
|
||||
rt.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ pub fn create_owning_memo<T>(
|
||||
f: impl Fn(Option<T>) -> (T, bool) + 'static,
|
||||
) -> Memo<T>
|
||||
where
|
||||
T: 'static,
|
||||
T: PartialEq + 'static,
|
||||
{
|
||||
Runtime::current().create_owning_memo(f)
|
||||
}
|
||||
@@ -352,7 +352,7 @@ impl<T> Memo<T> {
|
||||
#[track_caller]
|
||||
pub fn new_owning(f: impl Fn(Option<T>) -> (T, bool) + 'static) -> Memo<T>
|
||||
where
|
||||
T: 'static,
|
||||
T: PartialEq + 'static,
|
||||
{
|
||||
create_owning_memo(f)
|
||||
}
|
||||
|
||||
@@ -1389,7 +1389,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let current_span = tracing::Span::current();
|
||||
// run the Future
|
||||
let serializable = self.serializable;
|
||||
spawn_local({
|
||||
@@ -1398,8 +1397,6 @@ where
|
||||
let set_loading = self.set_loading;
|
||||
let last_version = self.version.clone();
|
||||
async move {
|
||||
// continue trace context within resource fetcher
|
||||
let _guard = current_span.enter();
|
||||
let res = fut.await;
|
||||
|
||||
if version == last_version.get() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user