66
77use oxc_allocator:: Allocator ;
88use oxc_ast:: ast:: {
9- BindingPattern , Expression , ImportDeclarationSpecifier , ImportOrExportKind , ModuleExportName ,
10- ObjectPropertyKind , Program , Statement , VariableDeclarationKind ,
9+ BindingPattern , Expression , ImportDeclarationSpecifier , ImportOrExportKind , ObjectPropertyKind ,
10+ Program , Statement , VariableDeclarationKind ,
1111} ;
1212use oxc_parser:: Parser ;
1313use oxc_span:: SourceType ;
1414use rustc_hash:: FxHashMap ;
1515use vite_path:: AbsolutePath ;
1616
17+ /// The package that exports the `defineConfig` helper static extraction trusts.
18+ const VITE_PLUS_PACKAGE : & str = "vite-plus" ;
19+ /// The name of the config helper static extraction trusts.
20+ const DEFINE_CONFIG : & str = "defineConfig" ;
21+
1722/// The result of statically analyzing a single config field's value.
1823#[ derive( Debug , Clone , PartialEq , Eq ) ]
1924pub enum FieldValue {
@@ -147,13 +152,11 @@ fn parse_js_ts_config(source: &str, extension: &str) -> FieldMap {
147152/// 3. `module.exports = defineConfig({ ... })` with `defineConfig` trusted from `vite-plus`
148153/// 4. `module.exports = { ... }`
149154fn extract_config_fields ( program : & Program < ' _ > ) -> FieldMap {
150- let mut has_trusted_define_config_binding = has_trusted_define_config_import ( program) ;
155+ let has_trusted_define_config_binding = program. body . iter ( ) . any ( |stmt| {
156+ is_trusted_define_config_import ( stmt) || has_trusted_define_config_cjs_binding ( stmt)
157+ } ) ;
151158
152159 for stmt in & program. body {
153- if has_trusted_define_config_cjs_binding ( stmt) {
154- has_trusted_define_config_binding = true ;
155- }
156-
157160 // ESM: export default ...
158161 if let Statement :: ExportDefaultDeclaration ( decl) = stmt {
159162 if let Some ( expr) = decl. declaration . as_expression ( ) {
@@ -261,45 +264,35 @@ fn extract_config_from_function_body(body: &oxc_ast::ast::FunctionBody<'_>) -> F
261264 FieldMap :: unanalyzable ( )
262265}
263266
264- fn has_trusted_define_config_import ( program : & Program < ' _ > ) -> bool {
265- program. body . iter ( ) . any ( |stmt| {
266- let Statement :: ImportDeclaration ( import_decl) = stmt else {
267- return false ;
268- } ;
269- if import_decl. import_kind != ImportOrExportKind :: Value
270- || import_decl. source . value != "vite-plus"
271- {
272- return false ;
273- }
274- import_decl. specifiers . as_ref ( ) . is_some_and ( |specifiers| {
275- specifiers. iter ( ) . any ( |specifier| {
276- let ImportDeclarationSpecifier :: ImportSpecifier ( specifier) = specifier else {
277- return false ;
278- } ;
279- specifier. import_kind == ImportOrExportKind :: Value
280- && specifier. local . name == "defineConfig"
281- && module_export_name_is_define_config ( & specifier. imported )
282- } )
267+ fn is_trusted_define_config_import ( stmt : & Statement < ' _ > ) -> bool {
268+ let Statement :: ImportDeclaration ( import_decl) = stmt else {
269+ return false ;
270+ } ;
271+ if import_decl. import_kind != ImportOrExportKind :: Value
272+ || import_decl. source . value != VITE_PLUS_PACKAGE
273+ {
274+ return false ;
275+ }
276+ import_decl. specifiers . as_ref ( ) . is_some_and ( |specifiers| {
277+ specifiers. iter ( ) . any ( |specifier| {
278+ let ImportDeclarationSpecifier :: ImportSpecifier ( specifier) = specifier else {
279+ return false ;
280+ } ;
281+ specifier. import_kind == ImportOrExportKind :: Value
282+ && specifier. local . name == DEFINE_CONFIG
283+ && specifier. imported . name ( ) == DEFINE_CONFIG
283284 } )
284285 } )
285286}
286287
287- fn module_export_name_is_define_config ( name : & ModuleExportName < ' _ > ) -> bool {
288- match name {
289- ModuleExportName :: IdentifierName ( id) => id. name == "defineConfig" ,
290- ModuleExportName :: IdentifierReference ( id) => id. name == "defineConfig" ,
291- ModuleExportName :: StringLiteral ( lit) => lit. value == "defineConfig" ,
292- }
293- }
294-
295288fn has_trusted_define_config_cjs_binding ( stmt : & Statement < ' _ > ) -> bool {
296289 match stmt {
297290 Statement :: VariableDeclaration ( decl) => {
298291 decl. kind == VariableDeclarationKind :: Const
299292 && decl. declarations . iter ( ) . any ( |declarator| {
300293 declarator. init . as_ref ( ) . is_some_and ( |init| match & declarator. id {
301294 BindingPattern :: BindingIdentifier ( id) => {
302- id. name == "defineConfig" && is_require_vite_plus_define_config ( init)
295+ id. name == DEFINE_CONFIG && is_require_vite_plus_define_config ( init)
303296 }
304297 BindingPattern :: ObjectPattern ( pattern) => {
305298 is_require_vite_plus ( init)
@@ -308,11 +301,11 @@ fn has_trusted_define_config_cjs_binding(stmt: &Statement<'_>) -> bool {
308301 && prop
309302 . key
310303 . static_name ( )
311- . is_some_and ( |key| key == "defineConfig" )
304+ . is_some_and ( |key| key == DEFINE_CONFIG )
312305 && matches ! (
313306 & prop. value,
314307 BindingPattern :: BindingIdentifier ( id)
315- if id. name == "defineConfig"
308+ if id. name == DEFINE_CONFIG
316309 )
317310 } )
318311 }
@@ -326,7 +319,7 @@ fn has_trusted_define_config_cjs_binding(stmt: &Statement<'_>) -> bool {
326319
327320fn is_require_vite_plus_define_config ( expr : & Expression < ' _ > ) -> bool {
328321 expr. without_parentheses ( ) . as_member_expression ( ) . is_some_and ( |member| {
329- member. static_property_name ( ) == Some ( "defineConfig" )
322+ member. static_property_name ( ) == Some ( DEFINE_CONFIG )
330323 && is_require_vite_plus ( member. object ( ) )
331324 } )
332325}
@@ -335,7 +328,7 @@ fn is_require_vite_plus(expr: &Expression<'_>) -> bool {
335328 matches ! (
336329 expr. without_parentheses( ) ,
337330 Expression :: CallExpression ( call)
338- if call. common_js_require( ) . is_some_and( |source| source. value == "vite-plus" )
331+ if call. common_js_require( ) . is_some_and( |source| source. value == VITE_PLUS_PACKAGE )
339332 )
340333}
341334
0 commit comments