// How the CLI's read commands obtain current data. // // `collections`, `files --collection`, `get`, and `get-thumb` must answer for // the account's state at the moment the command runs, not for whatever the // local cache last happened to hold (owner amendment, issue #36). Each helper // therefore forces a server round-trip through `Library.fresh()` and only then // reads — so a collection, file, or metadata change made elsewhere is visible. // // `collections` and `files` also list in the library's own enumeration order — // `listCollections()`/`listFiles()`, the order the pre-library CLI printed — // rather than the `albums`/`photos` projection's newest-first order, which // re-sorts the rows. The field values still come from each record's raw // metadata via `cli-output.ts`. import type { Collection, EnteFile } from "./model/types.js"; import type { Photo, PhotosAPI } from "./library/index.js"; // The slice of `Library` these helpers read. `Library` satisfies it // structurally; a test can drive them with a stand-in that records the // `fresh()` call and serves records in a known enumeration order. export interface FreshReadLibrary { fresh(): Promise; listCollections(): Collection[]; getCollection(id: number): Collection | undefined; listFiles(collectionID: number): EnteFile[]; getFileByID(fileID: number): EnteFile | undefined; photos: Pick; } // Every live collection, current as of a forced refresh, in enumeration order. export const freshCollections = async ( lib: FreshReadLibrary, ): Promise => { await lib.fresh(); return lib.listCollections(); }; // The files of one collection, current as of a forced refresh, in enumeration // order. `undefined` (not an empty list) when the collection does not exist, so // the caller can tell "no such collection" from "an empty collection". export const freshFiles = async ( lib: FreshReadLibrary, collectionID: number, ): Promise => { await lib.fresh(); if (!lib.getCollection(collectionID)) return undefined; return lib.listFiles(collectionID); }; // One file, current as of a forced refresh, resolved to both its content // handle (`Photo`, for fetching bytes) and its raw record (`EnteFile`, for the // default output name and field values). `undefined` when the file is unknown. export const freshFile = async ( lib: FreshReadLibrary, fileID: number, ): Promise<{ photo: Photo; file: EnteFile } | undefined> => { await lib.fresh(); const photo = lib.photos.byID({ fileID }); const file = lib.getFileByID(fileID); if (!photo || !file) return undefined; return { photo, file }; };