@@ -259,12 +259,20 @@ export async function listSnapshots(
259259 trace ?: TraceHttpContext ,
260260) : Promise < SnapshotIndex [ ] > {
261261 const result = await serverGet ( settings , "snapshots?limit=50" , trace ) ;
262- // Handle both shapes: old servers return { snapshots }, new servers
263- // also return { snapshots } by default. Array response is not expected
264- // but handle it defensively for any edge case.
265- if ( Array . isArray ( result ) ) return result as SnapshotIndex [ ] ;
266- const obj = result as { snapshots ?: SnapshotIndex [ ] } ;
267- return obj . snapshots ?? [ ] ;
262+ return normalizeSnapshotListResponse ( result ) ;
263+ }
264+
265+ /**
266+ * Normalize a raw snapshot list response into a SnapshotIndex array.
267+ * Handles: bare array, { snapshots: [...] }, or { snapshots: [...], ...metadata }.
268+ */
269+ export function normalizeSnapshotListResponse ( raw : unknown ) : SnapshotIndex [ ] {
270+ if ( Array . isArray ( raw ) ) return raw as SnapshotIndex [ ] ;
271+ if ( raw && typeof raw === "object" && "snapshots" in raw ) {
272+ const arr = ( raw as { snapshots ?: unknown } ) . snapshots ;
273+ if ( Array . isArray ( arr ) ) return arr as SnapshotIndex [ ] ;
274+ }
275+ return [ ] ;
268276}
269277
270278/**
@@ -296,27 +304,56 @@ export async function getSnapshotStatus(
296304 settings : VaultSyncSettings ,
297305 trace ?: TraceHttpContext ,
298306) : Promise < SnapshotStatus > {
299- const raw = await serverGet ( settings , "snapshots/status" , trace ) as Record < string , unknown > ;
307+ const raw = await serverGet ( settings , "snapshots/status" , trace ) ;
308+ return normalizeSnapshotStatusResponse ( raw ) ;
309+ }
300310
301- // Parse with fallbacks for old server field names
311+ /**
312+ * Normalize a raw status response into SnapshotStatus.
313+ * Falls back to old field names (snapshotCount, estimatedStorageBytes, pinnedCount)
314+ * when new LowerBound-suffixed fields are absent.
315+ */
316+ export function normalizeSnapshotStatusResponse ( raw : unknown ) : SnapshotStatus {
317+ if ( ! raw || typeof raw !== "object" ) {
318+ return {
319+ snapshotCountLowerBound : 0 ,
320+ listedSnapshotCount : 0 ,
321+ listingLimited : false ,
322+ estimatedStorageBytesLowerBound : 0 ,
323+ latestSnapshotId : null ,
324+ latestCreatedAt : null ,
325+ pinnedCountLowerBound : 0 ,
326+ } ;
327+ }
328+ const r = raw as Record < string , unknown > ;
302329 return {
303330 snapshotCountLowerBound :
304- ( raw . snapshotCountLowerBound as number ) ?? ( raw . snapshotCount as number ) ?? 0 ,
331+ ( r . snapshotCountLowerBound as number ) ?? ( r . snapshotCount as number ) ?? 0 ,
305332 listedSnapshotCount :
306- ( raw . listedSnapshotCount as number ) ?? ( raw . snapshotCount as number ) ?? 0 ,
333+ ( r . listedSnapshotCount as number ) ?? ( r . snapshotCount as number ) ?? 0 ,
307334 listingLimited :
308- ( raw . listingLimited as boolean ) ?? false ,
335+ ( r . listingLimited as boolean ) ?? false ,
309336 estimatedStorageBytesLowerBound :
310- ( raw . estimatedStorageBytesLowerBound as number ) ?? ( raw . estimatedStorageBytes as number ) ?? 0 ,
337+ ( r . estimatedStorageBytesLowerBound as number ) ?? ( r . estimatedStorageBytes as number ) ?? 0 ,
311338 latestSnapshotId :
312- ( raw . latestSnapshotId as string | null ) ?? null ,
339+ ( r . latestSnapshotId as string | null ) ?? null ,
313340 latestCreatedAt :
314- ( raw . latestCreatedAt as string | null ) ?? null ,
341+ ( r . latestCreatedAt as string | null ) ?? null ,
315342 pinnedCountLowerBound :
316- ( raw . pinnedCountLowerBound as number ) ?? ( raw . pinnedCount as number ) ?? 0 ,
343+ ( r . pinnedCountLowerBound as number ) ?? ( r . pinnedCount as number ) ?? 0 ,
317344 } ;
318345}
319346
347+ /**
348+ * Normalize the "identical to latest" field from a manual snapshot response.
349+ * Handles both new (snapshotIdenticalToLatest) and old (semanticUnchanged) field names.
350+ */
351+ export function normalizeSnapshotUnchanged ( raw : unknown ) : boolean {
352+ if ( ! raw || typeof raw !== "object" ) return false ;
353+ const r = raw as Record < string , unknown > ;
354+ return ! ! ( r . snapshotIdenticalToLatest ?? r . semanticUnchanged ) ;
355+ }
356+
320357// -------------------------------------------------------------------
321358// Snapshot download + decode
322359// -------------------------------------------------------------------
0 commit comments