turbopack_core/reference/
source_map.rs

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