turbopack_ecmascript_plugins/transform/directives/
mod.rs

1use swc_core::ecma::ast::{Lit, Program};
2
3pub mod client;
4pub mod client_disallowed;
5pub mod server;
6mod server_to_client_proxy;
7
8macro_rules! has_directive {
9    ($stmts:expr, $name:literal) => {
10        $stmts
11            .map(|item| {
12                if let Lit::Str(str) = item?.as_expr()?.expr.as_lit()? {
13                    Some(str)
14                } else {
15                    None
16                }
17            })
18            .take_while(Option::is_some)
19            .map(Option::unwrap)
20            .any(|s| &*s.value == $name)
21    };
22}
23
24fn is_client_module(program: &Program) -> bool {
25    match program {
26        Program::Module(m) => {
27            has_directive!(m.body.iter().map(|item| item.as_stmt()), "use client")
28        }
29        Program::Script(s) => has_directive!(s.body.iter().map(Some), "use client"),
30    }
31}
32
33fn is_server_module(program: &Program) -> bool {
34    match program {
35        Program::Module(m) => {
36            has_directive!(m.body.iter().map(|item| item.as_stmt()), "use server")
37        }
38        Program::Script(s) => has_directive!(s.body.iter().map(Some), "use server"),
39    }
40}