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