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 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}