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: ResolvedVc<FileSystemPath>,
20
21 env: ResolvedVc<Box<dyn ProcessEnv>>,
23}
24
25#[turbo_tasks::value_impl]
26impl ProcessEnvAsset {
27 #[turbo_tasks::function]
28 pub async fn new(
29 root: ResolvedVc<FileSystemPath>,
30 env: ResolvedVc<Box<dyn ProcessEnv>>,
31 ) -> Result<Vc<Self>> {
32 Ok(ProcessEnvAsset { root, env }.cell())
33 }
34}
35
36#[turbo_tasks::value_impl]
37impl Source for ProcessEnvAsset {
38 #[turbo_tasks::function]
39 fn ident(&self) -> Vc<AssetIdent> {
40 AssetIdent::from_path(self.root.join(".env.js".into()))
41 }
42}
43
44#[turbo_tasks::value_impl]
45impl Asset for ProcessEnvAsset {
46 #[turbo_tasks::function]
47 async fn content(&self) -> Result<Vc<AssetContent>> {
48 let env = self.env.read_all().await?;
49
50 let mut code = RopeBuilder::default();
54 code += "const env = process.env = {...process.env};\n\n";
55
56 for (name, val) in &*env {
57 writeln!(code, "env[{}] = {};", StringifyJs(name), val)?;
63 }
64
65 Ok(AssetContent::file(File::from(code.build()).into()))
66 }
67}