@@ -467,6 +467,109 @@ describe("typegen unit tests", () => {
467467 expect ( content ) . toContain ( "suffixSchemaLayout" ) ;
468468 } ) ;
469469
470+ it ( "preserves client index exports across multiple configs targeting the same path" , async ( ) => {
471+ vi . stubGlobal (
472+ "fetch" ,
473+ createLayoutMetadataMock ( {
474+ LayoutA : mockLayoutMetadata [ "basic-layout" ] ,
475+ LayoutB : mockLayoutMetadata [ "layout-with-portal" ] ,
476+ } ) ,
477+ ) ;
478+
479+ const config : Extract < z . infer < typeof typegenConfigSingle > , { type : "fmdapi" } > [ ] = [
480+ {
481+ type : "fmdapi" ,
482+ layouts : [
483+ {
484+ layoutName : "LayoutA" ,
485+ schemaName : "schemaA" ,
486+ } ,
487+ ] ,
488+ path : "unit-typegen-output/multi-config" ,
489+ generateClient : true ,
490+ clientSuffix : "Layout" ,
491+ clearOldFiles : false ,
492+ } ,
493+ {
494+ type : "fmdapi" ,
495+ layouts : [
496+ {
497+ layoutName : "LayoutB" ,
498+ schemaName : "schemaB" ,
499+ } ,
500+ ] ,
501+ path : "unit-typegen-output/multi-config" ,
502+ generateClient : true ,
503+ clientSuffix : "Layout" ,
504+ clearOldFiles : false ,
505+ } ,
506+ ] ;
507+
508+ await generateTypedClients ( config , { cwd : import . meta. dirname } ) ;
509+
510+ const indexPath = path . join ( __dirname , "unit-typegen-output/multi-config/client/index.ts" ) ;
511+ const content = await fs . readFile ( indexPath , "utf-8" ) ;
512+
513+ expect ( content ) . toContain ( 'export { client as schemaALayout } from "./schemaA";' ) ;
514+ expect ( content ) . toContain ( 'export { client as schemaBLayout } from "./schemaB";' ) ;
515+ } ) ;
516+
517+ it ( "clears shared output path once when any config enables clearOldFiles" , async ( ) => {
518+ vi . stubGlobal (
519+ "fetch" ,
520+ createLayoutMetadataMock ( {
521+ LayoutA : mockLayoutMetadata [ "basic-layout" ] ,
522+ LayoutB : mockLayoutMetadata [ "layout-with-portal" ] ,
523+ } ) ,
524+ ) ;
525+
526+ const outputDir = path . join ( __dirname , "unit-typegen-output/multi-config-clear" ) ;
527+ await fs . mkdir ( path . join ( outputDir , "client" ) , { recursive : true } ) ;
528+ await fs . mkdir ( path . join ( outputDir , "generated" ) , { recursive : true } ) ;
529+ await fs . writeFile ( path . join ( outputDir , "client" , "stale.ts" ) , "stale client" ) ;
530+ await fs . writeFile ( path . join ( outputDir , "generated" , "stale.ts" ) , "stale generated" ) ;
531+
532+ const config : Extract < z . infer < typeof typegenConfigSingle > , { type : "fmdapi" } > [ ] = [
533+ {
534+ type : "fmdapi" ,
535+ layouts : [
536+ {
537+ layoutName : "LayoutA" ,
538+ schemaName : "schemaA" ,
539+ } ,
540+ ] ,
541+ path : "unit-typegen-output/multi-config-clear" ,
542+ generateClient : true ,
543+ clientSuffix : "Layout" ,
544+ clearOldFiles : true ,
545+ } ,
546+ {
547+ type : "fmdapi" ,
548+ layouts : [
549+ {
550+ layoutName : "LayoutB" ,
551+ schemaName : "schemaB" ,
552+ } ,
553+ ] ,
554+ path : "unit-typegen-output/multi-config-clear" ,
555+ generateClient : true ,
556+ clientSuffix : "Layout" ,
557+ clearOldFiles : false ,
558+ } ,
559+ ] ;
560+
561+ await generateTypedClients ( config , { cwd : import . meta. dirname } ) ;
562+
563+ const indexPath = path . join ( outputDir , "client/index.ts" ) ;
564+ const indexContent = await fs . readFile ( indexPath , "utf-8" ) ;
565+
566+ expect ( indexContent ) . toContain ( 'export { client as schemaALayout } from "./schemaA";' ) ;
567+ expect ( indexContent ) . toContain ( 'export { client as schemaBLayout } from "./schemaB";' ) ;
568+
569+ await expect ( fs . access ( path . join ( outputDir , "client" , "stale.ts" ) ) ) . rejects . toThrow ( ) ;
570+ await expect ( fs . access ( path . join ( outputDir , "generated" , "stale.ts" ) ) ) . rejects . toThrow ( ) ;
571+ } ) ;
572+
470573 it ( "generates client using WebViewerAdapter when fmMcp config is provided" , async ( ) => {
471574 process . env . FM_MCP_BASE_URL = "http://127.0.0.1:1365" ;
472575 process . env . FM_CONNECTED_FILE_NAME = "TestFile" ;
0 commit comments