@@ -2065,7 +2065,7 @@ export * from '../dist/@vitest/browser/context.d.ts'
20652065}
20662066
20672067/**
2068- * Patch module augmentations in global.d.*.d.ts files to use relative paths .
2068+ * Patch module augmentations in global.d.*.d.ts files.
20692069 *
20702070 * The original vitest types use module augmentation like:
20712071 * declare module "@vitest/expect" { interface Assertion<T> { toMatchSnapshot: ... } }
@@ -2074,12 +2074,11 @@ export * from '../dist/@vitest/browser/context.d.ts'
20742074 * "@vitest/expect" doesn't exist as a package for consumers. This breaks the
20752075 * module augmentation - TypeScript can't find @vitest/expect to augment.
20762076 *
2077- * The fix: Change module augmentation to use relative paths that TypeScript CAN resolve:
2078- * declare module "../@vitest/expect/index.js" { ... }
2079- *
2080- * This makes TypeScript augment the same module that our index.d.ts imports from,
2081- * so the augmented properties (toMatchSnapshot, toMatchInlineSnapshot, etc.)
2082- * appear on the Assertion type that consumers import.
2077+ * The fix has two parts:
2078+ * 1. Change module augmentation to use relative paths that TypeScript CAN resolve:
2079+ * declare module "../@vitest/expect/index.js" { ... }
2080+ * 2. Merge augmented interface/type definitions into the target .d.ts files so that
2081+ * downstream DTS bundlers (rolldown) can resolve them without cross-file augmentation.
20832082 */
20842083async function patchModuleAugmentations ( ) {
20852084 console . log ( '\nPatching module augmentations in global.d.*.d.ts files...' ) ;
@@ -2097,31 +2096,79 @@ async function patchModuleAugmentations() {
20972096 return ;
20982097 }
20992098
2100- // Module augmentation mappings: bare specifier -> relative path from chunks/
2101- const augmentationMappings : Record < string , string > = {
2102- '@vitest/expect' : '../@vitest/expect/index.js' ,
2103- '@vitest/runner' : '../@vitest/runner/index.js' ,
2099+ // Module augmentation mappings: bare specifier -> [relative path, target .d.ts file]
2100+ const augmentationMappings : Record < string , { relativePath : string ; targetFile : string } > = {
2101+ '@vitest/expect' : {
2102+ relativePath : '../@vitest/expect/index.js' ,
2103+ targetFile : join ( distDir , '@vitest/expect/index.d.ts' ) ,
2104+ } ,
2105+ '@vitest/runner' : {
2106+ relativePath : '../@vitest/runner/index.js' ,
2107+ targetFile : join ( distDir , '@vitest/runner/utils.d.ts' ) ,
2108+ } ,
21042109 } ;
21052110
21062111 for ( const file of globalDtsFiles ) {
21072112 let content = await readFile ( file , 'utf-8' ) ;
21082113 let modified = false ;
21092114
2110- for ( const [ bareSpecifier , relativePath ] of Object . entries ( augmentationMappings ) ) {
2115+ for ( const [ bareSpecifier , { relativePath, targetFile } ] of Object . entries ( augmentationMappings ) ) {
21112116 const oldPattern = `declare module "${ bareSpecifier } "` ;
2112- const newPattern = `declare module "${ relativePath } "` ;
21132117
2114- if ( content . includes ( oldPattern ) ) {
2115- content = content . replaceAll ( oldPattern , newPattern ) ;
2116- modified = true ;
2117- console . log ( ` Patched: ${ bareSpecifier } -> ${ relativePath } in ${ basename ( file ) } ` ) ;
2118+ if ( ! content . includes ( oldPattern ) ) continue ;
2119+
2120+ // Extract the augmentation block content using brace matching
2121+ const startIdx = content . indexOf ( oldPattern ) ;
2122+ const braceStart = content . indexOf ( '{' , startIdx ) ;
2123+ if ( braceStart === - 1 ) continue ;
2124+
2125+ let depth = 0 ;
2126+ let braceEnd = - 1 ;
2127+ for ( let i = braceStart ; i < content . length ; i ++ ) {
2128+ if ( content [ i ] === '{' ) depth ++ ;
2129+ else if ( content [ i ] === '}' ) {
2130+ depth -- ;
2131+ if ( depth === 0 ) {
2132+ braceEnd = i ;
2133+ break ;
2134+ }
2135+ }
21182136 }
2137+ if ( braceEnd === - 1 ) continue ;
2138+
2139+ const innerContent = content . slice ( braceStart + 1 , braceEnd ) . trim ( ) ;
2140+
2141+ // Merge augmented types into the target .d.ts file
2142+ if ( innerContent && existsSync ( targetFile ) ) {
2143+ let targetContent = await readFile ( targetFile , 'utf-8' ) ;
2144+ const exportBlock = innerContent . replace ( / ^ ( \t * ) i n t e r f a c e / gm, '$1export interface ' ) ;
2145+ targetContent += `\n// Merged from module augmentation: declare module "${ bareSpecifier } "\n${ exportBlock } \n` ;
2146+ await writeFile ( targetFile , targetContent , 'utf-8' ) ;
2147+ console . log ( ` Merged augmentation "${ bareSpecifier } " into ${ basename ( targetFile ) } ` ) ;
2148+ }
2149+
2150+ // Rewrite declare module path to relative
2151+ const newPattern = `declare module "${ relativePath } "` ;
2152+ content = content . replaceAll ( oldPattern , newPattern ) ;
2153+ modified = true ;
2154+ console . log ( ` Patched: ${ bareSpecifier } -> ${ relativePath } in ${ basename ( file ) } ` ) ;
21192155 }
21202156
21212157 if ( modified ) {
21222158 await writeFile ( file , content , 'utf-8' ) ;
21232159 }
21242160 }
2161+
2162+ // Re-export BrowserCommands from context.d.ts (imported but not exported)
2163+ const contextDtsPath = join ( distDir , '@vitest/browser/context.d.ts' ) ;
2164+ if ( existsSync ( contextDtsPath ) ) {
2165+ let content = await readFile ( contextDtsPath , 'utf-8' ) ;
2166+ if ( content . includes ( 'BrowserCommands' ) && ! content . match ( / e x p o r t \s + ( t y p e \s + ) ? \{ [ ^ } ] * B r o w s e r C o m m a n d s / ) ) {
2167+ content += '\nexport type { BrowserCommands };\n' ;
2168+ await writeFile ( contextDtsPath , content , 'utf-8' ) ;
2169+ console . log ( ' Added BrowserCommands re-export to context.d.ts' ) ;
2170+ }
2171+ }
21252172}
21262173
21272174/**
0 commit comments