turbopack_ecmascript/references/
util.rs1use anyhow::Result;
2use swc_core::{ecma::ast::Expr, quote};
3use turbo_rcstr::{RcStr, rcstr};
4use turbo_tasks::Vc;
5use turbo_tasks_fs::{FileSystemPath, rope::Rope};
6use turbopack_core::{
7 resolve::parse::Request,
8 source_map::{
9 GenerateSourceMap, OptionStringifiedSourceMap, utils::resolve_source_map_sources,
10 },
11};
12
13pub fn throw_module_not_found_expr(request: &str) -> Expr {
16 let message = format!("Cannot find module '{request}'");
17 quote!(
18 "(() => { const e = new Error($message); e.code = 'MODULE_NOT_FOUND'; throw e; })()"
19 as Expr,
20 message: Expr = message.into()
21 )
22}
23
24pub fn throw_module_not_found_error_expr(request: &str, message: &str) -> Expr {
27 let message = format!("Cannot find module '{request}': {message}");
28 quote!(
29 "(() => { const e = new Error($message); e.code = 'MODULE_NOT_FOUND'; throw e; })()"
30 as Expr,
31 message: Expr = message.into()
32 )
33}
34
35#[turbo_tasks::function]
36pub async fn request_to_string(request: Vc<Request>) -> Result<Vc<RcStr>> {
37 Ok(Vc::cell(
38 request
39 .await?
40 .request()
41 .unwrap_or(rcstr!("unknown")),
43 ))
44}
45
46#[turbo_tasks::value(shared)]
47#[derive(Debug, Clone)]
48pub struct InlineSourceMap {
49 pub origin_path: FileSystemPath,
51 pub source_map: RcStr,
53}
54
55#[turbo_tasks::value_impl]
56impl GenerateSourceMap for InlineSourceMap {
57 #[turbo_tasks::function]
58 pub async fn generate_source_map(&self) -> Result<Vc<OptionStringifiedSourceMap>> {
59 let source_map = maybe_decode_data_url(&self.source_map);
60 let source_map =
61 resolve_source_map_sources(source_map.as_ref(), self.origin_path.clone()).await?;
62 Ok(Vc::cell(source_map))
63 }
64}
65
66fn maybe_decode_data_url(url: &str) -> Option<Rope> {
67 const DATA_PREAMBLE: &str = "data:application/json;base64,";
68
69 if !url.starts_with(DATA_PREAMBLE) {
70 return None;
71 }
72 let data_b64 = &url[DATA_PREAMBLE.len()..];
73 data_encoding::BASE64
74 .decode(data_b64.as_bytes())
75 .ok()
76 .map(Rope::from)
77}