next_core/
middleware.rs

1use anyhow::Result;
2use turbo_rcstr::{RcStr, rcstr};
3use turbo_tasks::{ResolvedVc, Vc, fxindexmap};
4use turbo_tasks_fs::FileSystemPath;
5use turbopack_core::{context::AssetContext, module::Module, reference_type::ReferenceType};
6
7use crate::util::load_next_js_template;
8
9#[turbo_tasks::function]
10pub async fn middleware_files(page_extensions: Vc<Vec<RcStr>>) -> Result<Vc<Vec<RcStr>>> {
11    let extensions = page_extensions.await?;
12    let files = ["middleware.", "src/middleware."]
13        .into_iter()
14        .flat_map(|f| {
15            extensions
16                .iter()
17                .map(move |ext| String::from(f) + ext.as_str())
18                .map(RcStr::from)
19        })
20        .collect();
21    Ok(Vc::cell(files))
22}
23
24#[turbo_tasks::function]
25pub async fn get_middleware_module(
26    asset_context: Vc<Box<dyn AssetContext>>,
27    project_root: FileSystemPath,
28    userland_module: ResolvedVc<Box<dyn Module>>,
29) -> Result<Vc<Box<dyn Module>>> {
30    const INNER: &str = "INNER_MIDDLEWARE_MODULE";
31
32    // Load the file from the next.js codebase.
33    let source = load_next_js_template(
34        "middleware.js",
35        project_root,
36        &[
37            ("VAR_USERLAND", INNER),
38            ("VAR_DEFINITION_PAGE", "/middleware"),
39        ],
40        &[],
41        &[],
42    )
43    .await?;
44
45    let inner_assets = fxindexmap! {
46        rcstr!(INNER) => userland_module
47    };
48
49    let module = asset_context
50        .process(
51            source,
52            ReferenceType::Internal(ResolvedVc::cell(inner_assets)),
53        )
54        .module();
55
56    Ok(module)
57}