@@ -5,6 +5,7 @@ import { dirname, join } from "node:path";
55import { afterEach , beforeEach , describe , expect , it , vi } from "vitest" ;
66import { getConfigDir , getProjectStorageKey } from "../lib/storage/paths.js" ;
77import { setStoragePathState } from "../lib/storage/path-state.js" ;
8+ import { getIntentionalResetMarkerPath } from "../lib/storage/backup-paths.js" ;
89import {
910 buildNamedBackupPath ,
1011 clearAccounts ,
@@ -1672,6 +1673,73 @@ describe("storage", () => {
16721673 }
16731674 } ) ;
16741675
1676+ it ( "does not export legacy accounts when an intentional reset marker appears during export fallback migration" , async ( ) => {
1677+ const currentStoragePath = join (
1678+ testWorkDir ,
1679+ "accounts-reset-during-fallback-current.json" ,
1680+ ) ;
1681+ const legacyStoragePath = join (
1682+ testWorkDir ,
1683+ "accounts-reset-during-fallback-legacy.json" ,
1684+ ) ;
1685+ const resetMarkerPath =
1686+ getIntentionalResetMarkerPath ( currentStoragePath ) ;
1687+ await fs . writeFile (
1688+ legacyStoragePath ,
1689+ JSON . stringify ( {
1690+ version : 3 ,
1691+ activeIndex : 0 ,
1692+ activeIndexByFamily : { } ,
1693+ accounts : [
1694+ {
1695+ accountId : "legacy" ,
1696+ refreshToken : "legacy-token" ,
1697+ addedAt : 1 ,
1698+ lastUsed : 1 ,
1699+ } ,
1700+ ] ,
1701+ } ) ,
1702+ ) ;
1703+
1704+ const actualStorageParser = await vi . importActual <
1705+ typeof import ( "../lib/storage/storage-parser.js" )
1706+ > ( "../lib/storage/storage-parser.js" ) ;
1707+ vi . resetModules ( ) ;
1708+ vi . doMock ( "../lib/storage/storage-parser.js" , ( ) => ( {
1709+ ...actualStorageParser ,
1710+ loadAccountsFromPath : vi . fn ( async ( path , deps ) => {
1711+ if ( path === legacyStoragePath && ! existsSync ( resetMarkerPath ) ) {
1712+ await fs . writeFile ( resetMarkerPath , "" ) ;
1713+ }
1714+ return actualStorageParser . loadAccountsFromPath ( path , deps ) ;
1715+ } ) ,
1716+ } ) ) ;
1717+
1718+ try {
1719+ const isolatedStorageModule = await import ( "../lib/storage.js" ) ;
1720+ const isolatedPathState = await import ( "../lib/storage/path-state.js" ) ;
1721+ isolatedPathState . setStoragePathState ( {
1722+ currentStoragePath,
1723+ currentLegacyProjectStoragePath : legacyStoragePath ,
1724+ currentLegacyWorktreeStoragePath : null ,
1725+ currentProjectRoot : null ,
1726+ } ) ;
1727+
1728+ await expect (
1729+ isolatedStorageModule . exportAccounts ( exportPath ) ,
1730+ ) . rejects . toThrow ( / N o a c c o u n t s t o e x p o r t / ) ;
1731+
1732+ expect ( existsSync ( currentStoragePath ) ) . toBe ( false ) ;
1733+ expect ( existsSync ( resetMarkerPath ) ) . toBe ( true ) ;
1734+ expect ( existsSync ( legacyStoragePath ) ) . toBe ( true ) ;
1735+ expect ( existsSync ( exportPath ) ) . toBe ( false ) ;
1736+ } finally {
1737+ vi . doUnmock ( "../lib/storage/storage-parser.js" ) ;
1738+ vi . resetModules ( ) ;
1739+ setStoragePathDirect ( testStoragePath ) ;
1740+ }
1741+ } ) ;
1742+
16751743 it ( "does not revive legacy accounts when the current storage reappears before export merges legacy storage" , async ( ) => {
16761744 const currentStoragePath = join (
16771745 testWorkDir ,
0 commit comments