Fixing a CORS bug

pmeunier
Mar 4, 2026, 5:54 PM
LE34RHBBMJT2BWLU5BHZJSHNMHQWX66QQNM2MAEDWEARCWOCSYLAC

Dependencies

Change contents

  • replacement in ui/src/routes/logout/+page.server.ts at line 7
    [2.53256][2.53256:53284]()
    throw redirect(302, `/`);
    [2.53256]
    [2.53284]
    redirect(302, `/`);
  • replacement in ui/src/routes/helpers.ts at line 13
    [2.53557][2.53557:53654]()
    export const server = browser ? import.meta.env.VITE_SERVER : import.meta.env.VITE_LOCAL_SERVER;
    [2.53557]
    [2.53654]
    export const server = import.meta.env.VITE_SERVER
  • edit in ui/src/routes/[user]/[repo]/tree/[[pos]]/+page.ts at line 11
    [3.749][2.55296:55317](),[2.55296][2.55296:55317]()
    console.log(resp);
  • replacement in ui/src/routes/[user]/[repo]/admin/+page.ts at line 5
    [2.104787][3.2521:2602]()
    const resp = await fetch(`${server}/api/admin/${params.user}/${params.repo}`);
    [2.104787]
    [3.2602]
    const url = `${server}/api/admin/${params.user}/${params.repo}`
    console.log("URL", url)
    const resp = await fetch(url);
  • replacement in ui/src/routes/[user]/[repo]/admin/+page.server.ts at line 50
    [2.108009][2.108009:108074]()
    throw redirect(302, `/${params.user}/${params.repo}/admin`);
    [2.108009]
    [2.108074]
    redirect(302, `/${params.user}/${params.repo}/admin`);
  • replacement in ui/src/routes/[user]/[repo]/+page.ts at line 6
    [2.112966][2.112966:113040]()
    throw redirect(302, `${ui_server}/${params.user}/${params.repo}/tree`);
    [2.112966]
    [2.113040]
    redirect(302, `${ui_server}/${params.user}/${params.repo}/tree`);
  • replacement in ui/src/routes/[user]/+page.ts at line 3
    [2.113369][2.113369:113427]()
    import { errorMsg, server, ui_server } from '../helpers';
    [2.113369]
    [2.113427]
    import { errorMsg, server } from '../helpers';
  • replacement in ui/src/routes/[user]/+page.ts at line 16
    [2.113731][2.113731:113835]()
    console.log('redirect', `${ui_server}/settings`);
    throw redirect(302, `${ui_server}/settings`);
    [2.113731]
    [2.113835]
    console.log('redirect', `/settings`);
    redirect(302, `/settings`);
  • replacement in ui/src/routes/+page.ts at line 5
    [2.115419][2.115419:115472]()
    export const load: PageLoad = async ({ fetch }) => {
    [2.115419]
    [3.3294]
    export const load: PageLoad = async ({ request, fetch }) => {
  • replacement in ui/src/routes/+page.ts at line 10
    [2.115614][2.115614:115666]()
    throw redirect(302, `${ui_server}/${y.login}`);
    [2.115614]
    [2.115666]
    redirect(302, `${ui_server}/settings`);
  • file addition: hooks.server.ts (----------)
    [2.2255]
    import type { HandleFetch } from '@sveltejs/kit';
    export const handleFetch: HandleFetch = async ({ event, request, fetch }) => {
    if (request.url.startsWith(import.meta.env.VITE_SERVER)) {
    // clone the original request, but change the URL
    request = new Request(
    request.url.replace(import.meta.env.VITE_SERVER, import.meta.env.VITE_LOCAL_SERVER),
    request
    );
    }
    console.log("request", request.url)
    const cookie = event.request.headers.get('cookie');
    console.log(cookie, request.headers.get('cookie'));
    if (cookie) {
    request.headers.set('cookie', cookie);
    }
    return fetch(request);
    };
  • replacement in api/src/proxy.rs at line 1
    [2.441558][2.441559:441593]()
    use axum::{extract::State, http};
    [2.441558]
    [2.441593]
    use crate::Config;
    use axum::extract::State;
    use axum::response::IntoResponse;
  • replacement in api/src/proxy.rs at line 10
    [2.441724][2.441724:441808]()
    pub struct BodyBuilder {
    pub http: http::response::Builder,
    pub html: bool,
    [2.441724]
    [2.441808]
    fn cached(
    cache: &std::sync::RwLock<std::collections::HashMap<String, crate::config::Cached>>,
    t: Option<&str>,
    path: &str,
    ) -> Option<axum::response::Response> {
    if let Ok(c) = cache.read() {
    if let Some(cached) = c.get(path) {
    debug!("cached {:?}", path);
    let mut resp = hyper::Response::new(cached.body.clone().into());
    let h = resp.headers_mut();
    h.insert(
    hyper::header::STRICT_TRANSPORT_SECURITY,
    HSTS.try_into().unwrap(),
    );
    if let Some(ref c) = cached.content_type {
    h.insert(CONTENT_TYPE, c.clone());
    }
    h.insert(
    hyper::header::CONTENT_LENGTH,
    cached.body.len().to_string().parse().unwrap(),
    );
    return Some(resp);
    }
    }
    None
  • edit in api/src/proxy.rs at line 36
    [2.441810][2.441810:442186]()
    type Body = http_body_util::Full<bytes::Bytes>;
    impl BodyBuilder {
    fn body(self, body: bytes::Bytes) -> Result<hyper::Response<Body>, http::Error> {
    let html =
    self.html
    || (self.http.headers_ref().map(|m| {
    m.get(CONTENT_TYPE).and_then(|x| x.to_str().ok()) == Some("text/html")
    }) == Some(true));
  • replacement in api/src/proxy.rs at line 37
    [2.442187][2.442187:442384]()
    let data = if html {
    minify_html::minify(&body, &minify_html::Cfg::default()).into()
    } else {
    body
    };
    Ok(self.http.body(data.into())?)
    }
    [2.442187]
    [2.442384]
    #[axum::debug_handler]
    pub async fn node_proxy_cached(
    State(config): State<Config>,
    req: axum::extract::Request,
    ) -> axum::response::Response {
    node_proxy(config, true, false, req).await.unwrap()
  • replacement in api/src/proxy.rs at line 46
    [2.442410][2.442410:442481]()
    pub async fn node_proxy_resp(
    State(config): State<crate::Config>,
    [2.442410]
    [2.442481]
    pub async fn node_proxy_strong_cached(
    State(config): State<Config>,
  • replacement in api/src/proxy.rs at line 49
    [2.442514][2.442514:442587]()
    ) -> hyper::Response<Body> {
    node_proxy(&config, req).await.unwrap()
    [2.442514]
    [2.442587]
    ) -> axum::response::Response {
    node_proxy(config, true, true, req).await.unwrap()
  • replacement in api/src/proxy.rs at line 53
    [2.442590][2.442590:442651]()
    pub async fn node_proxy(
    config: &crate::config::Config,
    [2.442590]
    [2.442651]
    #[axum::debug_handler]
    pub async fn node_proxy_not_cached(
    State(config): State<Config>,
  • replacement in api/src/proxy.rs at line 57
    [2.442684][2.442684:442783]()
    ) -> Result<hyper::Response<Body>, axum::http::Error> {
    match node_proxy_(config, req).await {
    [2.442684]
    [2.442783]
    ) -> axum::response::Response {
    node_proxy(config, false, false, req).await.unwrap()
    }
    async fn node_proxy(
    config: Config,
    cache: bool,
    forever: bool,
    mut req: axum::extract::Request,
    ) -> Result<axum::response::Response, hyper::http::Error> {
    let ref last_server_modif: chrono::DateTime<chrono::Utc> = config.version_time.into();
    if let Some(modif) = req.headers().get(http::header::IF_MODIFIED_SINCE) {
    debug!("req last_modif: {:?}", modif);
    if let Ok(parsed) = chrono::NaiveDateTime::parse_from_str(
    std::str::from_utf8(modif.as_bytes()).unwrap_or(""),
    crate::config::RFC1123,
    ) {
    let parsed = parsed.and_local_timezone(chrono::Utc).unwrap();
    debug!("parsed: {:?} {:?}", parsed, last_server_modif);
    if &parsed >= last_server_modif {
    return Ok(http::StatusCode::NOT_MODIFIED.into_response());
    }
    }
    }
    let mut path = if cache {
    let path = req.uri().path();
    if let Some(mut r) = cached(&config.cache, None, &path) {
    let ref l = config.version_time_str;
    debug!("cached {:?}", l);
    let h = r.headers_mut();
    h.insert(hyper::header::LAST_MODIFIED, l.parse().unwrap());
    h.insert(
    hyper::header::CACHE_CONTROL,
    if forever {
    "public, max-age=31536000".parse().unwrap()
    } else {
    "public".parse().unwrap()
    },
    );
    h.remove(hyper::header::VARY);
    return Ok(r);
    }
    Some(path.to_string())
    } else {
    None
    };
    req.headers_mut().remove(ACCEPT_ENCODING);
    debug!("node_proxy {:?}", path);
    for h in req.headers() {
    debug!("{:?}", h);
    }
    match node_proxy_(&config, req).await {
  • replacement in api/src/proxy.rs at line 111
    [2.442805][2.442805:442860]()
    let (mut parts, body) = resp.into_parts();
    [2.442805]
    [2.442860]
    let (parts, body) = resp.into_parts();
  • replacement in api/src/proxy.rs at line 113
    [2.442925][2.442925:442959]()
    parts.headers.insert(
    [2.442925]
    [2.442959]
    debug!("body {:?}", body.len());
    if !parts.status.is_success() {
    // Ne pas mettre en cache dans ce cas.
    path = None;
    }
    /*parts.headers.insert(
  • replacement in api/src/proxy.rs at line 121
    [2.443059][2.443059:443074]()
    );
    [2.443059]
    [2.443074]
    );*/
  • edit in api/src/proxy.rs at line 132
    [2.443404]
    [2.443404]
    };
    if let Some(path) = path {
    config.cache.write().unwrap().insert(
    path,
    crate::config::Cached {
    content_type: parts.headers.get(CONTENT_TYPE).cloned(),
    body: data.clone(),
    },
    );
  • edit in api/src/proxy.rs at line 145
    [2.443454]
    [2.443454]
    debug!("response len {:?}", len);
  • replacement in api/src/proxy.rs at line 150
    [2.443645][3.9263:9397]()
    trace!("{:?} {:?}", k, v);
    if let Some(k) = k {
    h.insert(k, v);
    }
    [2.443645]
    [2.443686]
    h.insert(k.unwrap(), v);
  • edit in api/src/proxy.rs at line 156
    [2.443834]
    [2.443834]
    if cache {
    let ref l = config.version_time_str;
    debug!("cache, last_modified {:?}", l);
    h.insert(hyper::header::LAST_MODIFIED, l.parse().unwrap());
    if forever {
    h.insert(
    hyper::header::CACHE_CONTROL,
    "public, max-age=31536000".parse().unwrap(),
    );
    } else {
    h.insert(hyper::header::CACHE_CONTROL, "public".parse().unwrap());
    }
    h.remove(hyper::header::VARY);
    } else {
    debug!("not cache")
    }
  • replacement in api/src/proxy.rs at line 175
    [2.443885][2.443885:444255]()
    error!("proxy error {:?}", e);
    let resp = http::response::Response::builder()
    .status(http::StatusCode::INTERNAL_SERVER_ERROR)
    .header(http::header::STRICT_TRANSPORT_SECURITY, HSTS);
    Ok(BodyBuilder {
    http: resp,
    html: false,
    }
    .body("".into())?)
    [2.443885]
    [2.444255]
    error!("grain error {:?}", e);
    Ok(hyper::Response::builder()
    .status(hyper::StatusCode::INTERNAL_SERVER_ERROR)
    .header(hyper::header::STRICT_TRANSPORT_SECURITY, HSTS)
    .body("".into())?)
  • replacement in api/src/proxy.rs at line 185
    [2.444300][2.444300:444437]()
    config: &crate::config::Config,
    req: axum::extract::Request,
    ) -> Result<hyper::Response<hyper::body::Incoming>, crate::Error> {
    [2.444300]
    [2.444437]
    config: &Config,
    req: hyper::Request<axum::body::Body>,
    ) -> Result<hyper::Response<axum::body::Body>, crate::Error> {
  • edit in api/src/proxy.rs at line 201
    [2.444962]
    [2.444962]
    debug!("node_proxy_ localhost:5173");
  • replacement in api/src/proxy.rs at line 220
    [2.445638][2.445638:445860]()
    for (k, v) in req.headers() {
    req_ = req_.header(k, v)
    }
    if cfg!(debug_assertions) {
    req_ = req_.header(HOST, "localhost:5173");
    } else {
    req_ = req_.header(HOST, "nest.pijul.org");
    [2.445638]
    [2.445860]
    for (h, v) in req.headers() {
    if h == HOST {
    req_ = req_.header(HOST, config.host.clone());
    } else {
    req_ = req_.header(h, v.clone());
    }
  • replacement in api/src/proxy.rs at line 228
    [2.445898][2.445898:445972]()
    let req_ = req_.body(body)?;
    Ok(sender.send_request(req_).await?)
    [2.445898]
    [2.445972]
    let bytes = axum::body::to_bytes(body, usize::MAX).await.unwrap();
    let req_: http::Request<axum::body::Body> = req_.body(bytes.into())?;
    debug!("node_proxy_ {:?}", req_);
    let mut resp = sender.send_request(req_).await?;
    let body = resp.body_mut().collect().await.unwrap().to_bytes();
    Ok(resp.map(|_| body.into()))
  • replacement in api/src/main.rs at line 64
    [2.453625][2.453625:453911]()
    tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
    format!(
    "{}=debug,tower_http=debug,axum::rejection=trace",
    env!("CARGO_CRATE_NAME")
    )
    .into()
    }),
    [2.453625]
    [2.453911]
    tracing_subscriber::EnvFilter::try_from_default_env()
    .unwrap_or_else(|_| "nest=debug,tower_http=debug,axum::rejection=trace".into()),
  • replacement in api/src/main.rs at line 74
    [3.9430][3.9430:9572]()
    .allow_origin(
    "http://localhost:5173"
    .parse::<http::HeaderValue>()
    .unwrap(),
    )
    [3.9430]
    [3.9572]
    .allow_origin([
    config_file.origin.parse::<http::HeaderValue>().unwrap(),
    ])
  • replacement in api/src/main.rs at line 78
    [3.9606][2.454257:454258](),[2.454257][2.454257:454258]()
    [3.9606]
    [2.454258]
    /*
    let cors = CorsLayer::new()
    .allow_origin(tower_http::cors::AllowOrigin::any());
    */
  • replacement in api/src/main.rs at line 93
    [2.454664][2.454664:454806]()
    .route("/static/{*wildcard}", any(proxy::node_proxy_resp))
    .route("/_app/immutable/{*wildcard}", any(proxy::node_proxy_resp))
    [2.454664]
    [2.454806]
    .route("/static/{*wildcard}", any(proxy::node_proxy_cached))
    .route("/_app/immutable/{*wildcard}", any(proxy::node_proxy_cached))
  • edit in api/src/main.rs at line 109
    [2.455407]
    [2.455407]
    .route("/logout", any(logout))
  • replacement in api/src/main.rs at line 118
    [2.455586][2.455586:455628]()
    .fallback(proxy::node_proxy_resp)
    [2.455586]
    [2.455628]
    .fallback(proxy::node_proxy_not_cached)
  • replacement in api/src/main.rs at line 129
    [2.456037][2.456037:456118]()
    tracing::debug_span!("request", %method, %uri, matched_path)
    [2.456037]
    [2.456118]
    let headers = req.headers();
    let h = format!("{:?}", headers);
    tracing::debug_span!("request", %method, %uri, matched_path, %h)
  • replacement in api/src/main.rs at line 166
    [2.457137][2.457137:457402]()
    tracing::debug!("listening on {}", https_addr);
    let https_worker = tokio::spawn(
    axum_server::bind_rustls(https_addr, tls_config).serve(
    app.clone()
    .into_make_service_with_connect_info::<SocketAddr>(),
    ),
    );
    [2.457137]
    [2.457402]
    let app_ = app.clone();
    let (https_worker, http_worker) = if let Some(tls_config) = tls_config {
    (
    tokio::spawn(
    axum_server::bind_rustls(https_addr, tls_config)
    .serve(app.into_make_service_with_connect_info::<SocketAddr>()),
    ),
    tokio::spawn(async move {
    redirect_http_to_https(
    config_file.http.http_port,
    config_file.http.https_port,
    app_,
    )
    .await;
    Ok::<_, Error>(())
    }),
    )
    } else {
    let listener = tokio::net::TcpListener::bind(http_addr).await.unwrap();
    let listener2 = tokio::net::TcpListener::bind(https_addr).await.unwrap();
    tracing::debug!("listening on {}", listener.local_addr().unwrap());
    use axum::handler::HandlerWithoutStateExt;
    (
    tokio::spawn(async move {
    axum::serve(
    listener,
    app.into_make_service_with_connect_info::<SocketAddr>(),
    )
    .await
    }),
    tokio::spawn(async move {
    axum::serve(
    listener2,
    app_.into_make_service_with_connect_info::<SocketAddr>(),
    )
    .await?;
    Ok::<_, Error>(())
    }),
    )
    };
  • edit in api/src/main.rs at line 208
    [2.457453][2.457453:457606]()
    let http_worker = tokio::spawn(redirect_http_to_https(
    config_file.http.http_port,
    config_file.http.https_port,
    app,
    ));
  • edit in api/src/main.rs at line 228
    [2.458194]
    [2.458194]
    )
    }
    #[debug_handler]
    async fn logout(State(config): State<Config>, jar: SignedCookieJar) -> (SignedCookieJar, Redirect) {
    (
    jar.remove(axum_extra::extract::cookie::Cookie::from("session_id")),
    Redirect::to("/"),
  • replacement in api/src/main.rs at line 249
    [2.458563][3.9848:9911]()
    Ok(proxy::node_proxy(&config, req).await?.into_response())
    [2.458563]
    [2.458644]
    Ok(proxy::node_proxy_(&config, req).await?.into_response())
  • edit in api/src/main.rs at line 462
    [3.10848]
    [2.464723]
    debug!("get_user_login: id {:?}", id);
  • edit in api/src/main.rs at line 472
    [2.464982]
    [2.464982]
    } else {
    debug!("get_user_login: no id");
  • replacement in api/src/email.rs at line 39
    [3.11717][3.11717:11813]()
    rusoto_ses::SesClient::new_with(client, config_email, rusoto_core::Region::EuWest1)
    [3.11717]
    [3.11813]
    rusoto_ses::SesClient::new_with(client, config_email, config.aws_ses_zone.clone())
  • edit in api/src/config_file.rs at line 6
    [2.529936]
    [2.529936]
    pub region: String,
  • edit in api/src/config_file.rs at line 36
    [2.530617]
    [2.530617]
    pub hostname: String,
  • edit in api/src/config.rs at line 14
    [2.533085]
    [2.533085]
    pub const RFC1123: &str = "%a, %d %b %Y %H:%M:%S GMT";
  • edit in api/src/config.rs at line 42
    [2.533950]
    [2.533950]
    pub aws_ses_zone: rusoto_core::Region,
  • replacement in api/src/config.rs at line 131
    [2.536525][2.536525:536838]()
    pub async fn make_tls() -> Result<axum_server::tls_rustls::RustlsConfig, TlsError> {
    let key = std::env::var("tls_key").unwrap().into_bytes();
    let certs = std::env::var("tls_cert").unwrap().into_bytes();
    Ok(axum_server::tls_rustls::RustlsConfig::from_pem(certs, key)
    .await
    .unwrap())
    [2.536525]
    [2.536838]
    pub async fn make_tls() -> Result<Option<axum_server::tls_rustls::RustlsConfig>, TlsError> {
    if let (Ok(key), Ok(cert)) = (std::env::var("tls_key"), std::env::var("tls_cert")) {
    Ok(Some(
    axum_server::tls_rustls::RustlsConfig::from_pem(cert.into_bytes(), key.into_bytes())
    .await
    .unwrap(),
    ))
    } else {
    Ok(None)
    }
  • replacement in api/src/config.rs at line 212
    [2.539519][2.539519:539794]()
    hostname: config_file.host.clone(),
    host: {
    let mut h = config_file.host.clone();
    if config_file.http.https_port != 443 {
    h.push_str(&format!(":{}", config_file.http.https_port));
    }
    h
    },
    [2.539519]
    [2.539794]
    aws_ses_zone: config_file.email.region.parse().unwrap(),
    hostname: config_file.hostname.clone(),
    host: config_file.host.clone(),
  • replacement in api/src/auth.rs at line 26
    [2.590356][2.590356:590397]()
    #[derive(Debug, Serialize, Deserialize)]
    [2.590356]
    [2.590397]
    #[derive(Serialize, Deserialize)]
  • edit in api/src/auth.rs at line 68
    [2.591354][2.591354:591383]()
    debug!("{:?}", payload);
  • replacement in api/src/auth.rs at line 215
    [2.595923][2.595923:596061]()
    .set(u::password.eq(make_password!(recover.pass)))
    .filter(u::email_is_invalid.is_null())
    [2.595923]
    [2.596061]
    .set((
    u::password.eq(make_password!(recover.pass)),
    u::email_is_invalid.eq(None::<bool>),
    ))
  • replacement in api/src/auth.rs at line 383
    [2.601201][2.601201:601240]()
    config.host, token
    [2.601201]
    [2.601240]
    config.hostname, token
  • replacement in api/src/auth.rs at line 409
    [2.601993][2.601993:602017]()
    ", config.host, token),
    [2.601993]
    [2.602017]
    ", config.hostname, token),
  • replacement in Cargo.lock at line 853
    [2.627108][3.20387:20405]()
    "bincode 2.0.1",
    [2.627108]
    [2.627120]
    "bincode 1.3.3",
  • edit in Cargo.lock at line 1931
    [2.650756]
    [2.650756]
    name = "getrandom"
    version = "0.4.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
    dependencies = [
    "cfg-if",
    "libc",
    "r-efi",
    "wasip2",
    "wasip3",
    ]
    [[package]]
  • edit in Cargo.lock at line 2448
    [2.663881]
    [2.663881]
    name = "id-arena"
    version = "2.3.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
    [[package]]
  • edit in Cargo.lock at line 2633
    [2.667706]
    [2.667898]
    [[package]]
    name = "leb128fmt"
    version = "0.1.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
  • edit in Cargo.lock at line 4119
    [2.694009]
    [2.694009]
    name = "prettyplease"
    version = "0.2.37"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
    dependencies = [
    "proc-macro2",
    "syn 2.0.111",
    ]
    [[package]]
  • edit in Cargo.lock at line 5814
    [2.733252]
    [2.733252]
    name = "unicode-xid"
    version = "0.2.6"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
    [[package]]
  • replacement in Cargo.lock at line 5873
    [2.734740][3.59783:59802]()
    version = "1.18.1"
    [2.734740]
    [2.734759]
    version = "1.21.0"
  • replacement in Cargo.lock at line 5875
    [2.734824][3.59803:59881]()
    checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
    [2.734824]
    [2.734902]
    checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb"
  • replacement in Cargo.lock at line 5877
    [2.734919][3.59882:59902]()
    "getrandom 0.3.4",
    [2.734919]
    [3.59902]
    "getrandom 0.4.1",
  • replacement in Cargo.lock at line 5879
    [3.59913][2.734939:734949](),[2.734939][2.734939:734949]()
    "serde",
    [3.59913]
    [3.59914]
    "serde_core",
  • replacement in Cargo.lock at line 5962
    [2.737014][3.60561:60577]()
    "wit-bindgen",
    [2.737014]
    [2.737033]
    "wit-bindgen 0.46.0",
    ]
    [[package]]
    name = "wasip3"
    version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
    dependencies = [
    "wit-bindgen 0.51.0",
  • edit in Cargo.lock at line 6036
    [2.738930]
    [2.738930]
    ]
    [[package]]
    name = "wasm-encoder"
    version = "0.244.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
    dependencies = [
    "leb128fmt",
    "wasmparser",
    ]
    [[package]]
    name = "wasm-metadata"
    version = "0.244.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
    dependencies = [
    "anyhow",
    "indexmap",
    "wasm-encoder",
    "wasmparser",
    ]
    [[package]]
    name = "wasmparser"
    version = "0.244.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
    dependencies = [
    "bitflags 2.10.0",
    "hashbrown 0.15.5",
    "indexmap",
    "semver",
  • edit in Cargo.lock at line 6461
    [3.66372]
    [2.746652]
    [[package]]
    name = "wit-bindgen"
    version = "0.51.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
    dependencies = [
    "wit-bindgen-rust-macro",
    ]
    [[package]]
    name = "wit-bindgen-core"
    version = "0.51.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
    dependencies = [
    "anyhow",
    "heck 0.5.0",
    "wit-parser",
    ]
    [[package]]
    name = "wit-bindgen-rust"
    version = "0.51.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
    dependencies = [
    "anyhow",
    "heck 0.5.0",
    "indexmap",
    "prettyplease",
    "syn 2.0.111",
    "wasm-metadata",
    "wit-bindgen-core",
    "wit-component",
    ]
    [[package]]
    name = "wit-bindgen-rust-macro"
    version = "0.51.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
    dependencies = [
    "anyhow",
    "prettyplease",
    "proc-macro2",
    "quote",
    "syn 2.0.111",
    "wit-bindgen-core",
    "wit-bindgen-rust",
    ]
    [[package]]
    name = "wit-component"
    version = "0.244.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
    dependencies = [
    "anyhow",
    "bitflags 2.10.0",
    "indexmap",
    "log",
    "serde",
    "serde_derive",
    "serde_json",
    "wasm-encoder",
    "wasm-metadata",
    "wasmparser",
    "wit-parser",
    ]
  • edit in Cargo.lock at line 6533
    [2.746665]
    [2.746665]
    name = "wit-parser"
    version = "0.244.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
    dependencies = [
    "anyhow",
    "id-arena",
    "indexmap",
    "log",
    "semver",
    "serde",
    "serde_derive",
    "serde_json",
    "unicode-xid",
    "wasmparser",
    ]
    [[package]]