@@ -3,7 +3,10 @@ use ast_grep_language::SupportLang;
33use serde_json:: { Map , Value } ;
44use vite_error:: Error ;
55
6- use crate :: { ast_grep, eslint:: rewrite_eslint_script, prettier:: rewrite_prettier_script} ;
6+ use crate :: {
7+ ast_grep, eslint:: rewrite_eslint_script, prettier:: rewrite_prettier_script,
8+ script_rewrite:: rewrite_bunx_commands,
9+ } ;
710
811// Marker to replace "cross-env " before ast-grep processing
912// Using a fake env var assignment that won't match our rules
@@ -22,8 +25,11 @@ fn rewrite_script(script: &str, rules: &[RuleConfig<SupportLang>]) -> String {
2225 script. to_string ( )
2326 } ;
2427
25- // Step 2: Process with ast-grep
26- let result = ast_grep:: apply_loaded_rules ( & preprocessed, rules) ;
28+ // Step 2: Rewrite commands behind bunx only when their inner command
29+ // matches an active rule, then process ordinary commands.
30+ let rewritten_bunx =
31+ rewrite_bunx_commands ( & preprocessed, |inner| ast_grep:: apply_loaded_rules ( inner, rules) ) ;
32+ let result = ast_grep:: apply_loaded_rules ( & rewritten_bunx, rules) ;
2733
2834 // Step 3: Replace cross-env marker back with "cross-env " (only if we replaced it)
2935
@@ -172,6 +178,15 @@ rule:
172178 regex: '^vitest$'
173179fix: vp test
174180
181+ # lint-staged => vp staged
182+ ---
183+ id: replace-lint-staged
184+ language: bash
185+ rule:
186+ kind: command_name
187+ regex: '^lint-staged$'
188+ fix: vp staged
189+
175190# tsdown => vp pack
176191---
177192id: replace-tsdown
@@ -276,6 +291,43 @@ fix: vp pack
276291 rewrite_script( "NODE_ENV=test oxlint --type-aware" , & rules) ,
277292 "NODE_ENV=test vp lint --type-aware"
278293 ) ;
294+ // bunx and its flags are preserved while managed commands are rewritten
295+ assert_eq ! ( rewrite_script( "bunx --bun vite build" , & rules) , "bunx --bun vp build" ) ;
296+ assert_eq ! ( rewrite_script( "bunx --bun vite preview" , & rules) , "bunx --bun vp preview" ) ;
297+ assert_eq ! ( rewrite_script( "bunx --bun vitest run" , & rules) , "bunx --bun vp test run" ) ;
298+ assert_eq ! (
299+ rewrite_script( "bunx --bun oxlint --type-aware" , & rules) ,
300+ "bunx --bun vp lint --type-aware"
301+ ) ;
302+ assert_eq ! (
303+ rewrite_script( "bunx --bun oxfmt --check ." , & rules) ,
304+ "bunx --bun vp fmt --check ."
305+ ) ;
306+ assert_eq ! (
307+ rewrite_script( "bunx --bun tsdown --watch" , & rules) ,
308+ "bunx --bun vp pack --watch"
309+ ) ;
310+ assert_eq ! ( rewrite_script( "bunx --bun lint-staged" , & rules) , "bunx --bun vp staged" ) ;
311+ assert_eq ! (
312+ rewrite_script( "NODE_ENV=development portless --tailscale run bunx --bun vite" , & rules, ) ,
313+ "NODE_ENV=development portless --tailscale run bunx --bun vp dev"
314+ ) ;
315+ assert_eq ! (
316+ rewrite_script( "dotenv -e .env.test -- bunx --bun vitest run" , & rules) ,
317+ "dotenv -e .env.test -- bunx --bun vp test run"
318+ ) ;
319+ // unrelated executor calls and non-launcher arguments stay unchanged
320+ assert_eq ! (
321+ rewrite_script( "bunx --bun playwright test" , & rules) ,
322+ "bunx --bun playwright test"
323+ ) ;
324+ assert_eq ! ( rewrite_script( "bunx --bun vp build" , & rules) , "bunx --bun vp build" ) ;
325+ assert_eq ! (
326+ rewrite_script( "echo bunx --bun vite build" , & rules) ,
327+ "echo bunx --bun vite build"
328+ ) ;
329+ assert_eq ! ( rewrite_script( "npx vite build" , & rules) , "npx vite build" ) ;
330+ assert_eq ! ( rewrite_script( "bun x vite build" , & rules) , "bun x vite build" ) ;
279331 // oxlint commands
280332 assert_eq ! ( rewrite_script( "oxlint" , & rules) , "vp lint" ) ;
281333 assert_eq ! ( rewrite_script( "oxlint --type-aware" , & rules) , "vp lint --type-aware" ) ;
0 commit comments