@@ -7,6 +7,7 @@ import mm from 'mm';
77import { describe , it , beforeEach , afterEach } from 'vitest' ;
88
99import { ManifestStore } from '../../src/loader/manifest.ts' ;
10+ import type { StartupManifest } from '../../src/loader/manifest.ts' ;
1011import { createTmpDir , setupBaseDir , generateAndWrite } from './manifest_helper.ts' ;
1112
1213let tmpDir : string ;
@@ -377,6 +378,95 @@ describe('ManifestStore', () => {
377378 } ) ;
378379 } ) ;
379380
381+ describe ( 'fromBundle()' , ( ) => {
382+ it ( 'should create store from bundled manifest data' , ( ) => {
383+ const baseDir = setupBaseDir ( ) ;
384+ try {
385+ const manifest = ManifestStore . createCollector ( baseDir ) . generateManifest ( {
386+ serverEnv : 'prod' ,
387+ serverScope : '' ,
388+ typescriptEnabled : true ,
389+ } ) ;
390+ manifest . resolveCache [ 'config/plugin' ] = 'config/plugin.ts' ;
391+
392+ const store = ManifestStore . fromBundle ( manifest , baseDir ) ;
393+ const result = store . resolveModule ( path . join ( baseDir , 'config/plugin' ) , ( ) => {
394+ throw new Error ( 'should not be called' ) ;
395+ } ) ;
396+
397+ assert . equal ( store . baseDir , baseDir ) ;
398+ assert . equal ( store . data , manifest ) ;
399+ assert . equal ( result , path . join ( baseDir , 'config/plugin.ts' ) ) ;
400+ } finally {
401+ fs . rmSync ( baseDir , { recursive : true , force : true } ) ;
402+ }
403+ } ) ;
404+
405+ it ( 'should throw when bundled manifest version mismatches' , ( ) => {
406+ const baseDir = setupBaseDir ( ) ;
407+ try {
408+ const manifest = ManifestStore . createCollector ( baseDir ) . generateManifest ( {
409+ serverEnv : 'prod' ,
410+ serverScope : '' ,
411+ typescriptEnabled : true ,
412+ } ) ;
413+ manifest . version = 999 ;
414+
415+ assert . throws (
416+ ( ) => ManifestStore . fromBundle ( manifest , baseDir ) ,
417+ / b u n d l e d m a n i f e s t v e r s i o n m i s m a t c h : e x p e c t e d 1 , g o t 9 9 9 / ,
418+ ) ;
419+ } finally {
420+ fs . rmSync ( baseDir , { recursive : true , force : true } ) ;
421+ }
422+ } ) ;
423+
424+ it ( 'should throw when bundled manifest is missing invalidation data' , ( ) => {
425+ const baseDir = setupBaseDir ( ) ;
426+ try {
427+ const manifest = ManifestStore . createCollector ( baseDir ) . generateManifest ( {
428+ serverEnv : 'prod' ,
429+ serverScope : '' ,
430+ typescriptEnabled : true ,
431+ } ) ;
432+ delete ( manifest as Partial < StartupManifest > ) . invalidation ;
433+
434+ assert . throws ( ( ) => ManifestStore . fromBundle ( manifest , baseDir ) , / b u n d l e d m a n i f e s t m i s s i n g i n v a l i d a t i o n d a t a / ) ;
435+ } finally {
436+ fs . rmSync ( baseDir , { recursive : true , force : true } ) ;
437+ }
438+ } ) ;
439+
440+ it ( 'should throw a clear error when bundled manifest data is null' , ( ) => {
441+ assert . throws (
442+ ( ) => ManifestStore . fromBundle ( null as unknown as StartupManifest , tmpDir ) ,
443+ / b u n d l e d m a n i f e s t v e r s i o n m i s m a t c h : e x p e c t e d 1 , g o t u n d e f i n e d / ,
444+ ) ;
445+ } ) ;
446+
447+ it ( 'should bypass normal invalidation checks for bundled manifest data' , async ( ) => {
448+ const baseDir = setupBaseDir ( { lockfile : 'pnpm' } ) ;
449+ try {
450+ const manifest = ManifestStore . createCollector ( baseDir ) . generateManifest ( {
451+ serverEnv : 'prod' ,
452+ serverScope : '' ,
453+ typescriptEnabled : true ,
454+ } ) ;
455+ manifest . invalidation . serverEnv = 'stale-env' ;
456+ manifest . invalidation . serverScope = 'stale-scope' ;
457+ manifest . invalidation . typescriptEnabled = ! manifest . invalidation . typescriptEnabled ;
458+ manifest . invalidation . lockfileFingerprint = 'stale-lockfile' ;
459+ manifest . invalidation . configFingerprint = 'stale-config' ;
460+ await ManifestStore . write ( baseDir , manifest ) ;
461+
462+ assert . equal ( ManifestStore . load ( baseDir , 'prod' , '' ) , null ) ;
463+ assert . doesNotThrow ( ( ) => ManifestStore . fromBundle ( manifest , baseDir ) ) ;
464+ } finally {
465+ fs . rmSync ( baseDir , { recursive : true , force : true } ) ;
466+ }
467+ } ) ;
468+ } ) ;
469+
380470 describe ( 'resolveModule()' , ( ) => {
381471 it ( 'should return cached result from loaded manifest' , async ( ) => {
382472 const baseDir = setupBaseDir ( ) ;
0 commit comments