@@ -55,3 +55,71 @@ test("register-loader errors when entry file does not exist", () => {
5555 rmSync ( cwd , { recursive : true , force : true } ) ;
5656 }
5757} ) ;
58+
59+ test ( "register-loader resolves typebox exports from the project dependency tree" , ( ) => {
60+ const cwd = mkdtempSync ( resolve ( tmpdir ( ) , "pi-agenticoding-loader-typebox-" ) ) ;
61+ try {
62+ const result = spawnSync (
63+ process . execPath ,
64+ [
65+ "--import" ,
66+ REGISTER_LOADER ,
67+ "--input-type=module" ,
68+ "-e" ,
69+ [
70+ 'const specifiers = ["typebox", "typebox/compile", "typebox/value"];' ,
71+ "const mods = await Promise.all(specifiers.map((specifier) => import(specifier)));" ,
72+ 'if (typeof mods[0].Type.String !== "function") process.exit(1);' ,
73+ "console.log(JSON.stringify(Object.fromEntries(specifiers.map((specifier) => [specifier, import.meta.resolve(specifier)]))));" ,
74+ ] . join ( "\n" ) ,
75+ ] ,
76+ {
77+ cwd,
78+ encoding : "utf8" ,
79+ env : { ...process . env , NODE_OPTIONS : "" } ,
80+ } ,
81+ ) ;
82+
83+ assert . equal ( result . status , 0 , result . stderr || result . stdout ) ;
84+ const resolved = JSON . parse ( result . stdout . trim ( ) ) as Record < string , string > ;
85+ const [ rootSpecifier , ...subpathSpecifiers ] = Object . keys ( resolved ) ;
86+ const typeboxRoot = resolved [ rootSpecifier ] . replace ( / (?: b u i l d \/ ) ? i n d e x \. m ? j s $ / , "" ) ;
87+ assert . match ( typeboxRoot , / ^ f i l e : / ) ;
88+ for ( const specifier of Object . keys ( resolved ) ) {
89+ assert . match ( resolved [ specifier ] , / ^ f i l e : / ) ;
90+ assert . ok (
91+ resolved [ specifier ] . startsWith ( typeboxRoot ) ,
92+ `${ specifier } should resolve from the same typebox package root` ,
93+ ) ;
94+ }
95+ assert . ok ( subpathSpecifiers . length > 0 ) ;
96+ } finally {
97+ rmSync ( cwd , { recursive : true , force : true } ) ;
98+ }
99+ } ) ;
100+
101+ test ( "register-loader surfaces a clear error for missing typebox exports" , ( ) => {
102+ const cwd = mkdtempSync ( resolve ( tmpdir ( ) , "pi-agenticoding-loader-typebox-missing-" ) ) ;
103+ try {
104+ const result = spawnSync (
105+ process . execPath ,
106+ [
107+ "--import" ,
108+ REGISTER_LOADER ,
109+ "--input-type=module" ,
110+ "-e" ,
111+ 'await import("typebox/not-real");' ,
112+ ] ,
113+ {
114+ cwd,
115+ encoding : "utf8" ,
116+ env : { ...process . env , NODE_OPTIONS : "" } ,
117+ } ,
118+ ) ;
119+
120+ assert . notEqual ( result . status , 0 , "should exit non-zero for missing typebox export" ) ;
121+ assert . match ( result . stderr , / C a n n o t f i n d t y p e b o x \/ n o t - r e a l e x p o r t / ) ;
122+ } finally {
123+ rmSync ( cwd , { recursive : true , force : true } ) ;
124+ }
125+ } ) ;
0 commit comments