Skip to main content

react_auditor/
presets.rs

1use std::collections::HashMap;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub enum Preset {
5    Recommended,
6    Strict,
7    Nextjs,
8    All,
9}
10
11impl std::str::FromStr for Preset {
12    type Err = String;
13
14    fn from_str(s: &str) -> Result<Self, Self::Err> {
15        match s.to_lowercase().as_str() {
16            "recommended" => Ok(Preset::Recommended),
17            "strict" => Ok(Preset::Strict),
18            "nextjs" => Ok(Preset::Nextjs),
19            "all" => Ok(Preset::All),
20            _ => Err(format!(
21                "Unknown preset: {s}. Available: recommended, strict, nextjs, all"
22            )),
23        }
24    }
25}
26
27impl Preset {
28    pub fn severity_overrides(&self) -> HashMap<String, String> {
29        match self {
30            Preset::Recommended => HashMap::new(),
31            Preset::Strict => {
32                let mut map = HashMap::new();
33                map.insert("no-console".to_string(), "error".to_string());
34                map.insert("no-any".to_string(), "error".to_string());
35                map.insert("no-eval".to_string(), "error".to_string());
36                map.insert("no-non-null-assertion".to_string(), "error".to_string());
37                map.insert("no-type-assertion".to_string(), "error".to_string());
38                map.insert("no-unused-vars".to_string(), "error".to_string());
39                map.insert("no-shadow".to_string(), "error".to_string());
40                map.insert(
41                    "prefer-function-components".to_string(),
42                    "error".to_string(),
43                );
44                map.insert("explicit-return-type".to_string(), "error".to_string());
45                map.insert(
46                    "no-dangerously-set-innerhtml".to_string(),
47                    "error".to_string(),
48                );
49                map.insert("no-hardcoded-secrets".to_string(), "error".to_string());
50                map.insert("no-unsanitized-input".to_string(), "error".to_string());
51                map
52            }
53            Preset::Nextjs => {
54                let mut map = HashMap::new();
55                map.insert("no-console".to_string(), "warn".to_string());
56                map.insert("no-img-element".to_string(), "error".to_string());
57                map.insert("no-script-tag-in-head".to_string(), "error".to_string());
58                map.insert("no-page-link".to_string(), "error".to_string());
59                map.insert("no-head-element".to_string(), "error".to_string());
60                map.insert("no-sync-script".to_string(), "error".to_string());
61                map.insert("no-missing-key".to_string(), "error".to_string());
62                map.insert("no-inline-styles".to_string(), "warn".to_string());
63                map
64            }
65            Preset::All => {
66                let mut map = HashMap::new();
67                map.insert("complexity".to_string(), "error".to_string());
68                map.insert("max-params".to_string(), "error".to_string());
69                map.insert("no-long-functions".to_string(), "error".to_string());
70                map.insert("no-deep-nesting".to_string(), "error".to_string());
71                map.insert("no-magic-numbers".to_string(), "warn".to_string());
72                map
73            }
74        }
75    }
76
77    pub fn category_filter(&self) -> Option<Vec<String>> {
78        match self {
79            Preset::Nextjs => Some(vec![
80                "react".to_string(),
81                "nextjs".to_string(),
82                "performance".to_string(),
83                "accessibility".to_string(),
84                "quality".to_string(),
85            ]),
86            _ => None,
87        }
88    }
89}