1use std::io::Write;
2
3use anyhow::Result;
4use turbo_tasks::{ResolvedVc, Vc};
5use turbo_tasks_env::ProcessEnv;
6use turbo_tasks_fs::{File, FileSystemPath, rope::RopeBuilder};
7use turbopack_core::{
8 asset::{Asset, AssetContent},
9 ident::AssetIdent,
10 source::Source,
11};
12use turbopack_ecmascript::utils::StringifyJs;
13
14#[turbo_tasks::value]
17pub struct ProcessEnvAsset {
18 root: FileSystemPath,
20
21 env: ResolvedVc<Box<dyn ProcessEnv>>,
23}
24
25#[turbo_tasks::value_impl]
26impl ProcessEnvAsset {
27 #[turbo_tasks::function]
28 pub fn new(root: FileSystemPath, env: ResolvedVc<Box<dyn ProcessEnv>>) -> Result<Vc<Self>> {
29 Ok(ProcessEnvAsset { root, env }.cell())
30 }
31}
32
33#[turbo_tasks::value_impl]
34impl Source for ProcessEnvAsset {
35 #[turbo_tasks::function]
36 fn ident(&self) -> Result<Vc<AssetIdent>> {
37 Ok(AssetIdent::from_path(self.root.join(".env.js")?))
38 }
39}
40
41#[turbo_tasks::value_impl]
42impl Asset for ProcessEnvAsset {
43 #[turbo_tasks::function]
44 async fn content(&self) -> Result<Vc<AssetContent>> {
45 let env = self.env.read_all().await?;
46
47 let mut code = RopeBuilder::default();
51 code += "const env = process.env = {...process.env};\n\n";
52
53 for (name, val) in &*env {
54 writeln!(code, "env[{}] = {};", StringifyJs(name), val)?;
60 }
61
62 Ok(AssetContent::file(File::from(code.build()).into()))
63 }
64}