1use indexmap::IndexMap;
2use rustc_hash::FxHashMap;
3use serde::Deserialize;
4
5use stylex_constants::constants::common::DEFAULT_INJECT_PATH;
6use stylex_enums::property_validation_mode::PropertyValidationMode;
7use stylex_enums::style_resolution::StyleResolution;
8use stylex_enums::sx_prop_name_param::SxPropNameParam;
9
10use crate::{
11 named_import_source::{ImportSources, RuntimeInjection},
12 stylex_env::{EnvEntry, JSFunction},
13};
14
15#[derive(Deserialize, Clone, Debug)]
16#[serde(rename_all = "camelCase")]
17pub struct StyleXOptionsParams {
18 pub style_resolution: Option<StyleResolution>,
19 pub property_validation_mode: Option<PropertyValidationMode>,
20 pub enable_font_size_px_to_rem: Option<bool>,
21 pub runtime_injection: Option<RuntimeInjection>,
22 pub class_name_prefix: Option<String>,
23 pub defined_stylex_css_variables: Option<FxHashMap<String, String>>,
24 pub import_sources: Option<Vec<ImportSources>>,
25 pub treeshake_compensation: Option<bool>,
26 pub enable_inlined_conditional_merge: Option<bool>,
27 pub enable_media_query_order: Option<bool>,
28 pub enable_logical_styles_polyfill: Option<bool>,
29 pub enable_legacy_value_flipping: Option<bool>,
30 pub enable_ltr_rtl_comments: Option<bool>,
31 pub use_real_file_for_source: Option<bool>,
32 pub dev: Option<bool>,
33 pub test: Option<bool>,
34 pub debug: Option<bool>,
35 pub enable_debug_class_names: Option<bool>,
36 pub enable_debug_data_prop: Option<bool>,
37 pub enable_dev_class_names: Option<bool>,
38 pub enable_minified_keys: Option<bool>,
39 pub inject_stylex_side_effects: Option<bool>,
40 pub aliases: Option<FxHashMap<String, Vec<String>>>,
41 #[serde(rename = "unstable_moduleResolution")]
42 pub unstable_module_resolution: Option<ModuleResolution>,
43 pub sx_prop_name: Option<SxPropNameParam>,
44 #[serde(skip)]
45 pub env: Option<IndexMap<String, EnvEntry>>,
46 #[serde(skip)]
47 pub debug_file_path: Option<JSFunction>,
48}
49
50impl Default for StyleXOptionsParams {
51 fn default() -> Self {
52 StyleXOptionsParams {
53 style_resolution: Some(StyleResolution::PropertySpecificity),
54 property_validation_mode: Some(PropertyValidationMode::Silent),
55 enable_font_size_px_to_rem: Some(false),
56 runtime_injection: Some(RuntimeInjection::Boolean(false)),
57 class_name_prefix: Some("x".to_string()),
58 defined_stylex_css_variables: Some(FxHashMap::default()),
59 import_sources: None,
60 treeshake_compensation: Some(true),
61 enable_inlined_conditional_merge: Some(true),
62 enable_media_query_order: Some(true),
63 enable_logical_styles_polyfill: Some(false),
64 enable_ltr_rtl_comments: Some(false),
65 enable_legacy_value_flipping: Some(false),
66 dev: Some(false),
67 test: Some(false),
68 debug: None,
69 enable_debug_class_names: Some(false),
70 enable_debug_data_prop: Some(true),
71 enable_dev_class_names: Some(false),
72 enable_minified_keys: Some(true),
73 inject_stylex_side_effects: Some(false),
74 use_real_file_for_source: Some(true),
75 aliases: None,
76 unstable_module_resolution: None,
77 sx_prop_name: None,
78 env: None,
79 debug_file_path: None,
80 }
81 }
82}
83
84#[derive(Deserialize, Debug, Clone)]
85#[serde(rename_all(deserialize = "camelCase", serialize = "PascalCase"))]
86pub struct ModuleResolution {
87 pub r#type: String,
88 pub root_dir: Option<String>,
89 pub theme_file_extension: Option<String>,
90}
91
92#[derive(Deserialize, Debug, Clone)]
93
94pub enum CheckModuleResolution {
95 CommonJS(ModuleResolution),
96 Haste(ModuleResolution),
97 CrossFileParsing(ModuleResolution),
98}
99
100#[derive(Clone, Debug)]
101pub struct StyleXOptions {
102 pub dev: bool,
103 pub test: bool,
104 pub debug: bool,
105 pub property_validation_mode: PropertyValidationMode,
106 pub enable_debug_class_names: bool,
107 pub enable_debug_data_prop: bool,
108 pub enable_dev_class_names: bool,
109 pub enable_inlined_conditional_merge: bool,
110 pub enable_media_query_order: bool,
111 pub enable_logical_styles_polyfill: bool,
112 pub enable_legacy_value_flipping: bool,
113 pub enable_ltr_rtl_comments: bool,
114 pub enable_minified_keys: bool,
115 pub enable_font_size_px_to_rem: bool,
116 pub use_real_file_for_source: bool,
117 pub class_name_prefix: String,
118 pub style_resolution: StyleResolution,
120 pub runtime_injection: RuntimeInjection,
121 pub import_sources: Vec<ImportSources>,
122 pub treeshake_compensation: bool,
123 pub inject_stylex_side_effects: bool,
124 pub aliases: Option<FxHashMap<String, Vec<String>>>,
125 pub unstable_module_resolution: CheckModuleResolution,
126 pub sx_prop_name: Option<String>,
127 pub env: IndexMap<String, EnvEntry>,
128 pub debug_file_path: Option<JSFunction>,
129}
130
131impl StyleXOptions {
132 pub fn get_haste_module_resolution(root_dir: Option<String>) -> ModuleResolution {
133 ModuleResolution {
134 r#type: "haste".to_string(),
135 root_dir,
136 theme_file_extension: None,
137 }
138 }
139
140 pub fn get_common_js_module_resolution(root_dir: Option<String>) -> ModuleResolution {
141 ModuleResolution {
142 r#type: "commonjs".to_string(),
143 root_dir,
144 theme_file_extension: None,
145 }
146 }
147}
148
149impl Default for StyleXOptions {
150 fn default() -> Self {
151 StyleXOptions {
152 style_resolution: StyleResolution::PropertySpecificity,
153 property_validation_mode: PropertyValidationMode::Silent,
154 enable_font_size_px_to_rem: false,
155 runtime_injection: RuntimeInjection::Boolean(false),
156 class_name_prefix: "x".to_string(),
157 import_sources: vec![],
159 dev: false,
160 test: false,
161 debug: false,
162 enable_debug_class_names: false,
163 enable_debug_data_prop: true,
164 enable_dev_class_names: false,
165 enable_inlined_conditional_merge: true,
166 enable_media_query_order: true,
167 enable_logical_styles_polyfill: false,
168 enable_legacy_value_flipping: false,
169 enable_ltr_rtl_comments: false,
170 enable_minified_keys: true,
171 inject_stylex_side_effects: false,
172 use_real_file_for_source: true,
173 treeshake_compensation: false,
174 aliases: None,
175 unstable_module_resolution: CheckModuleResolution::CommonJS(
176 StyleXOptions::get_common_js_module_resolution(None),
177 ),
178 sx_prop_name: Some("sx".to_string()),
179 env: IndexMap::new(),
180 debug_file_path: None,
181 }
182 }
183}
184
185impl From<StyleXOptionsParams> for StyleXOptions {
186 fn from(options: StyleXOptionsParams) -> Self {
187 let module_resolution = options
188 .unstable_module_resolution
189 .unwrap_or_else(|| StyleXOptions::get_common_js_module_resolution(None));
190
191 let unstable_module_resolution = match module_resolution.r#type.to_lowercase().as_str() {
192 "haste" => CheckModuleResolution::Haste(module_resolution),
193 "cross-file-parsing" => CheckModuleResolution::CrossFileParsing(module_resolution),
194 _ => CheckModuleResolution::CommonJS(module_resolution),
195 };
196
197 let runtime_injection = match options.runtime_injection {
198 Some(value) => match value {
199 RuntimeInjection::Boolean(true) => {
200 RuntimeInjection::Regular(DEFAULT_INJECT_PATH.to_string())
201 },
202 RuntimeInjection::Boolean(false) => RuntimeInjection::Boolean(false),
203 RuntimeInjection::Regular(path) => RuntimeInjection::Regular(path),
204 RuntimeInjection::Named(named) => RuntimeInjection::Named(named),
205 },
206 None => RuntimeInjection::Boolean(false),
207 };
208
209 StyleXOptions {
210 style_resolution: options
211 .style_resolution
212 .unwrap_or(StyleResolution::PropertySpecificity),
213 property_validation_mode: options
214 .property_validation_mode
215 .unwrap_or(PropertyValidationMode::Silent),
216 enable_font_size_px_to_rem: options.enable_font_size_px_to_rem.unwrap_or(false),
217 runtime_injection,
218 class_name_prefix: options.class_name_prefix.unwrap_or("x".to_string()),
219 import_sources: options.import_sources.unwrap_or_else(|| {
221 vec![
222 ImportSources::Regular("stylex".to_string()),
223 ImportSources::Regular("@stylexjs/stylex".to_string()),
224 ]
225 }),
226 dev: options.dev.unwrap_or(false),
227 test: options.test.unwrap_or(false),
228 debug: options.debug.or(options.dev).unwrap_or(false),
229 enable_debug_class_names: options.enable_debug_class_names.unwrap_or(false),
230 enable_debug_data_prop: options.enable_debug_data_prop.unwrap_or(true),
231 enable_dev_class_names: options.enable_dev_class_names.unwrap_or(false),
232 enable_minified_keys: options.enable_minified_keys.unwrap_or(true),
233 inject_stylex_side_effects: options.inject_stylex_side_effects.unwrap_or(false),
234 treeshake_compensation: options.treeshake_compensation.unwrap_or(false),
235 enable_inlined_conditional_merge: options.enable_inlined_conditional_merge.unwrap_or(true),
236 enable_media_query_order: options.enable_media_query_order.unwrap_or(true),
237 enable_logical_styles_polyfill: options.enable_logical_styles_polyfill.unwrap_or(false),
238 enable_legacy_value_flipping: options.enable_legacy_value_flipping.unwrap_or(false),
239 enable_ltr_rtl_comments: options.enable_ltr_rtl_comments.unwrap_or(false),
240 use_real_file_for_source: options.use_real_file_for_source.unwrap_or(true),
241 aliases: options.aliases,
242 unstable_module_resolution,
243 sx_prop_name: match options.sx_prop_name {
244 None => Some("sx".to_string()),
245 Some(SxPropNameParam::Disabled) => None,
246 Some(SxPropNameParam::Enabled(name)) => Some(name),
247 },
248 env: options.env.unwrap_or_default(),
249 debug_file_path: options.debug_file_path,
250 }
251 }
252}