react_remove_properties/
lib.rs

1use serde::Deserialize;
2use swc_cached::regex::CachedRegex;
3use swc_ecma_ast::*;
4use swc_ecma_visit::{fold_pass, noop_fold_type, Fold, FoldWith};
5
6#[derive(Clone, Debug, Deserialize)]
7#[serde(untagged)]
8pub enum Config {
9    All(bool),
10    WithOptions(Options),
11}
12
13impl Config {
14    pub fn truthy(&self) -> bool {
15        match self {
16            Config::All(b) => *b,
17            Config::WithOptions(_) => true,
18        }
19    }
20}
21
22#[derive(Clone, Debug, Deserialize)]
23pub struct Options {
24    #[serde(default)]
25    pub properties: Vec<String>,
26}
27
28pub fn react_remove_properties(config: Config) -> impl Pass {
29    let mut properties: Vec<CachedRegex> = match config {
30        Config::WithOptions(x) => x
31            .properties
32            .iter()
33            .map(|pattern| {
34                CachedRegex::new(pattern).unwrap_or_else(|e| {
35                    panic!("error compiling property regex `{pattern}`: {e}");
36                })
37            })
38            .collect(),
39        _ => vec![],
40    };
41    if properties.is_empty() {
42        // Keep the default regex identical to `babel-plugin-react-remove-properties`.
43        properties.push(CachedRegex::new(r"^data-test").unwrap());
44    }
45    fold_pass(RemoveProperties { properties })
46}
47
48struct RemoveProperties {
49    properties: Vec<CachedRegex>,
50}
51
52impl RemoveProperties {
53    fn should_remove_property(&self, name: &str) -> bool {
54        self.properties.iter().any(|p| p.is_match(name))
55    }
56}
57
58impl Fold for RemoveProperties {
59    noop_fold_type!();
60
61    fn fold_jsx_opening_element(&mut self, mut el: JSXOpeningElement) -> JSXOpeningElement {
62        el.attrs.retain(|attr| {
63            !matches!(attr, JSXAttrOrSpread::JSXAttr(JSXAttr {
64              name: JSXAttrName::Ident(ident),
65              ..
66            }) if self.should_remove_property(ident.sym.as_ref()))
67        });
68        el.fold_children_with(self)
69    }
70}