turbopack_core/reference/
source_map.rs1use anyhow::Result;
2use turbo_tasks::{ResolvedVc, ValueToString, Vc};
3use turbo_tasks_fs::{File, FileContent, FileSystemEntryType, FileSystemPath};
4
5use super::ModuleReference;
6use crate::{
7 file_source::FileSource,
8 raw_module::RawModule,
9 resolve::ModuleResolveResult,
10 source_map::{GenerateSourceMap, utils::resolve_source_map_sources},
11};
12
13#[turbo_tasks::value]
14#[derive(ValueToString)]
15#[value_to_string("source map file is referenced by {from}")]
16pub struct SourceMapReference {
17 from: FileSystemPath,
18 file: FileSystemPath,
19}
20
21#[turbo_tasks::value_impl]
22impl SourceMapReference {
23 #[turbo_tasks::function]
24 pub fn new(from: FileSystemPath, file: FileSystemPath) -> Vc<Self> {
25 Self::cell(SourceMapReference { from, file })
26 }
27}
28
29impl SourceMapReference {
30 async fn get_file(&self) -> Option<FileSystemPath> {
31 let file_type = self.file.get_type().await;
32 if let Ok(file_type_result) = file_type.as_ref()
33 && let FileSystemEntryType::File = &**file_type_result
34 {
35 return Some(self.file.clone());
36 }
37 None
38 }
39}
40
41#[turbo_tasks::value_impl]
42impl ModuleReference for SourceMapReference {
43 #[turbo_tasks::function]
44 async fn resolve_reference(&self) -> Result<Vc<ModuleResolveResult>> {
45 if let Some(file) = self.get_file().await {
46 return Ok(*ModuleResolveResult::module(ResolvedVc::upcast(
47 RawModule::new(Vc::upcast(FileSource::new(file)))
48 .to_resolved()
49 .await?,
50 )));
51 }
52 Ok(*ModuleResolveResult::unresolvable())
53 }
54}
55
56#[turbo_tasks::value_impl]
57impl GenerateSourceMap for SourceMapReference {
58 #[turbo_tasks::function]
59 async fn generate_source_map(&self) -> Result<Vc<FileContent>> {
60 let Some(file) = self.get_file().await else {
61 return Ok(FileContent::NotFound.cell());
62 };
63
64 let content = file.read().await?;
65 let content = content.as_content().map(|file| file.content());
66 if let Some(source_map) = resolve_source_map_sources(content, &self.from).await? {
67 Ok(FileContent::Content(File::from(source_map)).cell())
68 } else {
69 Ok(FileContent::NotFound.cell())
70 }
71 }
72}