next_core/
middleware.rs

1use anyhow::Result;
2use turbo_rcstr::RcStr;
3use turbo_tasks::{FxIndexMap, ResolvedVc, Value, 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: Vc<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        fxindexmap! {
37            "VAR_USERLAND" => INNER.into(),
38            "VAR_DEFINITION_PAGE" => "/middleware".into(),
39        },
40        FxIndexMap::default(),
41        FxIndexMap::default(),
42    )
43    .await?;
44
45    let inner_assets = fxindexmap! {
46        INNER.into() => userland_module
47    };
48
49    let module = asset_context
50        .process(
51            source,
52            Value::new(ReferenceType::Internal(ResolvedVc::cell(inner_assets))),
53        )
54        .module();
55
56    Ok(module)
57}