diff --git a/crates/turbopack-ecmascript-plugins/src/transform/directives/client_disallowed.rs b/crates/turbopack-ecmascript-plugins/src/transform/directives/client_disallowed.rs new file mode 100644 index 0000000000000..4b3f04667ce7d --- /dev/null +++ b/crates/turbopack-ecmascript-plugins/src/transform/directives/client_disallowed.rs @@ -0,0 +1,33 @@ +use anyhow::Result; +use async_trait::async_trait; +use swc_core::ecma::{ast::Program, transforms::base::resolver, visit::VisitMutWith}; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +use super::{is_client_module, server_to_client_proxy::create_error_proxy_module}; + +#[derive(Debug)] +pub struct ClientDisallowedDirectiveTransformer { + error_proxy_module: String, +} + +impl ClientDisallowedDirectiveTransformer { + pub fn new(error_proxy_module: String) -> Self { + Self { error_proxy_module } + } +} + +#[async_trait] +impl CustomTransformer for ClientDisallowedDirectiveTransformer { + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + if is_client_module(program) { + *program = create_error_proxy_module(&self.error_proxy_module); + program.visit_mut_with(&mut resolver( + ctx.unresolved_mark, + ctx.top_level_mark, + false, + )); + } + + Ok(()) + } +} diff --git a/crates/turbopack-ecmascript-plugins/src/transform/directives/mod.rs b/crates/turbopack-ecmascript-plugins/src/transform/directives/mod.rs index 09e96f2b3fb75..2b5e745c9eb2f 100644 --- a/crates/turbopack-ecmascript-plugins/src/transform/directives/mod.rs +++ b/crates/turbopack-ecmascript-plugins/src/transform/directives/mod.rs @@ -1,6 +1,7 @@ use swc_core::ecma::ast::{Lit, Program}; pub mod client; +pub mod client_disallowed; pub mod server; mod server_to_client_proxy; diff --git a/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs b/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs index e9b55df950940..b031e3dc65c90 100644 --- a/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs +++ b/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs @@ -2,8 +2,8 @@ use swc_core::{ common::DUMMY_SP, ecma::{ ast::{ - ImportDecl, ImportSpecifier, ImportStarAsSpecifier, Module, ModuleDecl, ModuleItem, - Program, + ImportDecl, ImportDefaultSpecifier, ImportSpecifier, ImportStarAsSpecifier, Module, + ModuleDecl, ModuleItem, Program, }, utils::private_ident, }, @@ -41,3 +41,28 @@ pub fn create_proxy_module(transition_name: &str, target_import: &str) -> Progra span: DUMMY_SP, }) } + +pub fn create_error_proxy_module(error_proxy_module: &str) -> Program { + let ident = private_ident!("errorProxy"); + Program::Module(Module { + body: vec![ + ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + specifiers: vec![ImportSpecifier::Default(ImportDefaultSpecifier { + local: ident.clone(), + span: DUMMY_SP, + })], + src: Box::new(error_proxy_module.into()), + type_only: false, + with: Some(with_clause(&[(TURBOPACK_HELPER.as_str(), "true")])), + span: DUMMY_SP, + phase: Default::default(), + })), + ModuleItem::Stmt(quote!( + "__turbopack_export_namespace__($proxy);" as Stmt, + proxy = ident, + )), + ], + shebang: None, + span: DUMMY_SP, + }) +}