1use anyhow::Result;
2use turbo_rcstr::{RcStr, rcstr};
3use turbo_tasks::{ResolvedVc, Vc};
4use turbopack_core::{
5 asset::{Asset, AssetContent},
6 chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext},
7 ident::AssetIdent,
8 module::Module,
9 module_graph::ModuleGraph,
10 output::{OutputAsset, OutputAssets},
11 source::Source,
12};
13use turbopack_ecmascript::{
14 chunk::{
15 EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable,
16 EcmascriptChunkType, EcmascriptExports,
17 },
18 runtime_functions::TURBOPACK_EXPORT_VALUE,
19 utils::StringifyJs,
20};
21
22use crate::output_asset::StaticOutputAsset;
23
24#[turbo_tasks::value]
25#[derive(Clone)]
26pub struct StaticUrlJsModule {
27 pub source: ResolvedVc<Box<dyn Source>>,
28 pub tag: Option<RcStr>,
29}
30
31#[turbo_tasks::value_impl]
32impl StaticUrlJsModule {
33 #[turbo_tasks::function]
34 pub fn new(source: ResolvedVc<Box<dyn Source>>, tag: Option<RcStr>) -> Vc<Self> {
35 Self::cell(StaticUrlJsModule { source, tag })
36 }
37
38 #[turbo_tasks::function]
39 fn static_output_asset(
40 &self,
41 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
42 ) -> Vc<StaticOutputAsset> {
43 StaticOutputAsset::new(*chunking_context, *self.source, self.tag.clone())
44 }
45}
46
47#[turbo_tasks::value_impl]
48impl Module for StaticUrlJsModule {
49 #[turbo_tasks::function]
50 fn ident(&self) -> Vc<AssetIdent> {
51 let mut ident = self
52 .source
53 .ident()
54 .with_modifier(rcstr!("static in ecmascript"));
55 if let Some(tag) = &self.tag {
56 ident = ident.with_modifier(format!("tag {}", tag).into());
57 }
58 ident
59 }
60}
61
62#[turbo_tasks::value_impl]
63impl Asset for StaticUrlJsModule {
64 #[turbo_tasks::function]
65 fn content(&self) -> Vc<AssetContent> {
66 self.source.content()
67 }
68}
69
70#[turbo_tasks::value_impl]
71impl ChunkableModule for StaticUrlJsModule {
72 #[turbo_tasks::function]
73 async fn as_chunk_item(
74 self: ResolvedVc<Self>,
75 _module_graph: Vc<ModuleGraph>,
76 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
77 ) -> Result<Vc<Box<dyn turbopack_core::chunk::ChunkItem>>> {
78 Ok(Vc::upcast(StaticUrlJsChunkItem::cell(
79 StaticUrlJsChunkItem {
80 module: self,
81 chunking_context,
82 static_asset: self
83 .static_output_asset(*chunking_context)
84 .to_resolved()
85 .await?,
86 tag: self.await?.tag.clone(),
87 },
88 )))
89 }
90}
91
92#[turbo_tasks::value_impl]
93impl EcmascriptChunkPlaceable for StaticUrlJsModule {
94 #[turbo_tasks::function]
95 fn get_exports(&self) -> Vc<EcmascriptExports> {
96 EcmascriptExports::Value.into()
97 }
98}
99
100#[turbo_tasks::value]
101struct StaticUrlJsChunkItem {
102 module: ResolvedVc<StaticUrlJsModule>,
103 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
104 static_asset: ResolvedVc<StaticOutputAsset>,
105 tag: Option<RcStr>,
106}
107
108#[turbo_tasks::value_impl]
109impl ChunkItem for StaticUrlJsChunkItem {
110 #[turbo_tasks::function]
111 fn asset_ident(&self) -> Vc<AssetIdent> {
112 self.module.ident()
113 }
114
115 #[turbo_tasks::function]
116 fn references(&self) -> Vc<OutputAssets> {
117 Vc::cell(vec![ResolvedVc::upcast(self.static_asset)])
118 }
119
120 #[turbo_tasks::function]
121 fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
122 *self.chunking_context
123 }
124
125 #[turbo_tasks::function]
126 async fn ty(&self) -> Result<Vc<Box<dyn ChunkType>>> {
127 Ok(Vc::upcast(
128 Vc::<EcmascriptChunkType>::default().resolve().await?,
129 ))
130 }
131
132 #[turbo_tasks::function]
133 fn module(&self) -> Vc<Box<dyn Module>> {
134 *ResolvedVc::upcast(self.module)
135 }
136}
137
138#[turbo_tasks::value_impl]
139impl EcmascriptChunkItem for StaticUrlJsChunkItem {
140 #[turbo_tasks::function]
141 async fn content(&self) -> Result<Vc<EcmascriptChunkItemContent>> {
142 Ok(EcmascriptChunkItemContent {
143 inner_code: format!(
144 "{TURBOPACK_EXPORT_VALUE}({path});",
145 path = StringifyJs(
146 &self
147 .chunking_context
148 .asset_url(self.static_asset.path().owned().await?, self.tag.clone())
149 .await?
150 )
151 )
152 .into(),
153 ..Default::default()
154 }
155 .into())
156 }
157}