turbopack_ecmascript/
bytes_source_transform.rs1use std::io::Read;
2
3use anyhow::{Result, bail};
4use turbo_tasks::Vc;
5use turbo_tasks_fs::{File, FileContent};
6use turbopack_core::{
7 asset::{Asset, AssetContent},
8 context::AssetContext,
9 source::Source,
10 source_transform::SourceTransform,
11 virtual_source::VirtualSource,
12};
13
14use crate::utils::{StringifyJs, inline_source_map_comment};
15
16#[turbo_tasks::value]
21pub struct BytesSourceTransform;
22
23#[turbo_tasks::value_impl]
24impl BytesSourceTransform {
25 #[turbo_tasks::function]
26 pub fn new() -> Vc<Self> {
27 BytesSourceTransform.cell()
28 }
29}
30
31#[turbo_tasks::value_impl]
32impl SourceTransform for BytesSourceTransform {
33 #[turbo_tasks::function]
34 async fn transform(
35 self: Vc<Self>,
36 source: Vc<Box<dyn Source>>,
37 _asset_context: Vc<Box<dyn AssetContext>>,
38 ) -> Result<Vc<Box<dyn Source>>> {
39 let ident = source.ident().owned().await?;
40 let content = source.content().file_content().await?;
41 let bytes = match &*content {
42 FileContent::Content(data) => {
43 data.read().bytes().collect::<std::io::Result<Vec<u8>>>()?
44 }
45 FileContent::NotFound => {
46 bail!("File not found: {:?}", ident.path);
47 }
48 };
49
50 let encoded = data_encoding::BASE64_NOPAD.encode(&bytes);
51
52 let code = format!(
54 r#""use turbopack no side effects";
55import {{ base64Decode }} from '@turbopack/base64';
56export default base64Decode({});
57{}"#,
58 StringifyJs(&encoded),
59 inline_source_map_comment(&ident.path.path, "")
62 );
63
64 let new_ident = ident.rename_as("*.[bytes].mjs").into_vc();
68
69 Ok(Vc::upcast(VirtualSource::new_with_ident(
70 new_ident,
71 AssetContent::file(FileContent::Content(File::from(code)).cell()),
72 )))
73 }
74}