@@ -5,6 +5,7 @@ import path from 'node:path';
55import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest' ;
66
77import { PackageManager } from '../../types/index.js' ;
8+ import { createMigrationReport } from '../report.js' ;
89
910// Mock VITE_PLUS_VERSION to a stable value for snapshot tests.
1011// When tests run via `vp test`, the env var is injected with the actual version,
@@ -21,6 +22,9 @@ const {
2122 parseNvmrcVersion,
2223 detectNodeVersionManagerFile,
2324 migrateNodeVersionManagerFile,
25+ detectFramework,
26+ hasFrameworkShim,
27+ addFrameworkShim,
2428} = await import ( '../migrator.js' ) ;
2529
2630describe ( 'rewritePackageJson' , ( ) => {
@@ -304,6 +308,7 @@ describe('migrateNodeVersionManagerFile', () => {
304308 prettierMigrated : false ,
305309 nodeVersionFileMigrated : false ,
306310 gitHooksConfigured : false ,
311+ frameworkShimAdded : false ,
307312 warnings : [ ] ,
308313 manualSteps : [ ] ,
309314 } ;
@@ -334,6 +339,7 @@ describe('migrateNodeVersionManagerFile', () => {
334339 prettierMigrated : false ,
335340 nodeVersionFileMigrated : false ,
336341 gitHooksConfigured : false ,
342+ frameworkShimAdded : false ,
337343 warnings : [ ] ,
338344 manualSteps : [ ] ,
339345 } ;
@@ -366,6 +372,7 @@ describe('migrateNodeVersionManagerFile', () => {
366372 prettierMigrated : false ,
367373 nodeVersionFileMigrated : false ,
368374 gitHooksConfigured : false ,
375+ frameworkShimAdded : false ,
369376 warnings : [ ] ,
370377 manualSteps : [ ] ,
371378 } ;
@@ -401,6 +408,7 @@ describe('migrateNodeVersionManagerFile', () => {
401408 prettierMigrated : false ,
402409 nodeVersionFileMigrated : false ,
403410 gitHooksConfigured : false ,
411+ frameworkShimAdded : false ,
404412 warnings : [ ] ,
405413 manualSteps : [ ] ,
406414 } ;
@@ -638,3 +646,110 @@ describe('rewriteMonorepo bun catalog', () => {
638646 expect ( workspaces . packages ) . toEqual ( [ 'packages/*' ] ) ;
639647 } ) ;
640648} ) ;
649+
650+ describe ( 'framework shim' , ( ) => {
651+ let tmpDir : string ;
652+
653+ beforeEach ( ( ) => {
654+ tmpDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'vp-test-' ) ) ;
655+ } ) ;
656+
657+ afterEach ( ( ) => {
658+ fs . rmSync ( tmpDir , { recursive : true , force : true } ) ;
659+ } ) ;
660+
661+ describe ( 'detectFramework' , ( ) => {
662+ it ( 'returns vue when vue is in devDependencies' , ( ) => {
663+ fs . writeFileSync (
664+ path . join ( tmpDir , 'package.json' ) ,
665+ JSON . stringify ( { devDependencies : { vue : '^3.0.0' } } ) ,
666+ ) ;
667+ expect ( detectFramework ( tmpDir ) ) . toBe ( 'vue' ) ;
668+ } ) ;
669+
670+ it ( 'returns astro when astro is in devDependencies' , ( ) => {
671+ fs . writeFileSync (
672+ path . join ( tmpDir , 'package.json' ) ,
673+ JSON . stringify ( { devDependencies : { astro : '^4.0.0' } } ) ,
674+ ) ;
675+ expect ( detectFramework ( tmpDir ) ) . toBe ( 'astro' ) ;
676+ } ) ;
677+
678+ it ( 'returns null when no framework dependency is present' , ( ) => {
679+ fs . writeFileSync (
680+ path . join ( tmpDir , 'package.json' ) ,
681+ JSON . stringify ( { devDependencies : { vite : '^7.0.0' } } ) ,
682+ ) ;
683+ expect ( detectFramework ( tmpDir ) ) . toBeNull ( ) ;
684+ } ) ;
685+
686+ it ( 'returns null when package.json does not exist' , ( ) => {
687+ expect ( detectFramework ( tmpDir ) ) . toBeNull ( ) ;
688+ } ) ;
689+ } ) ;
690+
691+ describe ( 'hasFrameworkShim' , ( ) => {
692+ it ( 'returns true when src/env.d.ts contains vue shim' , ( ) => {
693+ const srcDir = path . join ( tmpDir , 'src' ) ;
694+ fs . mkdirSync ( srcDir ) ;
695+ fs . writeFileSync (
696+ path . join ( srcDir , 'env.d.ts' ) ,
697+ "declare module '*.vue' { export default {} }\n" ,
698+ ) ;
699+ expect ( hasFrameworkShim ( tmpDir , 'vue' ) ) . toBe ( true ) ;
700+ } ) ;
701+
702+ it ( 'returns false when src/env.d.ts does not contain vue shim' , ( ) => {
703+ const srcDir = path . join ( tmpDir , 'src' ) ;
704+ fs . mkdirSync ( srcDir ) ;
705+ fs . writeFileSync ( path . join ( srcDir , 'env.d.ts' ) , '/// <reference types="vite-plus/client" />\n' ) ;
706+ expect ( hasFrameworkShim ( tmpDir , 'vue' ) ) . toBe ( false ) ;
707+ } ) ;
708+
709+ it ( 'returns false when env.d.ts does not exist' , ( ) => {
710+ expect ( hasFrameworkShim ( tmpDir , 'vue' ) ) . toBe ( false ) ;
711+ } ) ;
712+
713+ it ( 'returns true when root env.d.ts contains astro/client reference' , ( ) => {
714+ fs . writeFileSync (
715+ path . join ( tmpDir , 'env.d.ts' ) ,
716+ '/// <reference types="astro/client" />\n' ,
717+ ) ;
718+ expect ( hasFrameworkShim ( tmpDir , 'astro' ) ) . toBe ( true ) ;
719+ } ) ;
720+ } ) ;
721+
722+ describe ( 'addFrameworkShim' , ( ) => {
723+ it ( 'creates src/env.d.ts with vue shim when src/ exists and no env.d.ts' , ( ) => {
724+ fs . mkdirSync ( path . join ( tmpDir , 'src' ) ) ;
725+ addFrameworkShim ( tmpDir , 'vue' ) ;
726+ const content = fs . readFileSync ( path . join ( tmpDir , 'src' , 'env.d.ts' ) , 'utf-8' ) ;
727+ expect ( content ) . toContain ( "declare module '*.vue'" ) ;
728+ expect ( content ) . toContain ( 'DefineComponent' ) ;
729+ } ) ;
730+
731+ it ( 'creates root env.d.ts with vue shim when no src/ dir' , ( ) => {
732+ addFrameworkShim ( tmpDir , 'vue' ) ;
733+ const content = fs . readFileSync ( path . join ( tmpDir , 'env.d.ts' ) , 'utf-8' ) ;
734+ expect ( content ) . toContain ( "declare module '*.vue'" ) ;
735+ } ) ;
736+
737+ it ( 'appends vue shim to existing src/env.d.ts' , ( ) => {
738+ const srcDir = path . join ( tmpDir , 'src' ) ;
739+ fs . mkdirSync ( srcDir ) ;
740+ const existing = '/// <reference types="vite-plus/client" />\n' ;
741+ fs . writeFileSync ( path . join ( srcDir , 'env.d.ts' ) , existing ) ;
742+ addFrameworkShim ( tmpDir , 'vue' ) ;
743+ const content = fs . readFileSync ( path . join ( srcDir , 'env.d.ts' ) , 'utf-8' ) ;
744+ expect ( content ) . toContain ( '/// <reference types="vite-plus/client" />' ) ;
745+ expect ( content ) . toContain ( "declare module '*.vue'" ) ;
746+ } ) ;
747+
748+ it ( 'sets frameworkShimAdded on report' , ( ) => {
749+ fs . mkdirSync ( path . join ( tmpDir , 'src' ) ) ;
750+ const report = createMigrationReport ( ) ;
751+ addFrameworkShim ( tmpDir , 'vue' , report ) ;
752+ expect ( report . frameworkShimAdded ) . toBe ( true ) ;
753+ } ) ;
754+ } ) ;
755+ } ) ;
0 commit comments