// 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). `files`, // `get` and `get-thumb` therefore force a server round-trip through // `Library.fresh()` and only then read — so a collection, file, or metadata // change made elsewhere is visible. `collections` asks the library for the // collection list alone through `Library.freshCollections()` (issue #210): a // refresh would also fetch the files of every collection, which on a large // account takes long and which `collections` does not print. // // `collections` lists in the server's order and `files` in the library's own // enumeration order (`listFiles()`), the orders 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()` and `freshCollections()` calls and serves records in a known // enumeration order. export interface FreshReadLibrary { fresh(): Promise; freshCollections(): Promise; getCollection(id: number): Collection | undefined; listFiles(collectionID: number): EnteFile[]; getFileByID(fileID: number): EnteFile | undefined; photos: Pick; } // Every live collection, current as of one collections request, in the // server's order. export const freshCollections = ( lib: FreshReadLibrary, ): Promise => lib.freshCollections(); // 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 }; };