Photo: save path, is-local, content bytes, metadata and EXIF getters (closes #141)
check / check (push) Successful in 1m34s

A Photo now has savePath and isLocal, which look only at the disk;
content() and exif(), which may download the original; and modifiedAt,
hash, fileSize and year. PhotoRecord gains modifiedAt, hash and fileSize.
The JPEG EXIF scan moves from metadata-backup.ts to the new src/exif.ts,
so the read surface does not import the backup command.

Model: opus-5-5
This commit is contained in:
2026-10-01 15:09:17 +00:00
parent e6825abcdb
commit e7f75685e5
12 changed files with 533 additions and 86 deletions
+25
View File
@@ -209,6 +209,31 @@ describe("lib.photos", () => {
expect("key" in photo.record()).toBe(false);
});
it("byID exposes modifiedAt, hash, fileSize and the year taken", () => {
// Mid-July, so the year is 2021 in every time zone.
const takenAt = Date.UTC(2021, 6, 15, 12);
const records = deriveRecords(
[collection(1)],
[
file(1001, 1, {
metadata: {
title: "IMG.jpg",
fileType: "image",
creationTime: micros(takenAt),
modificationTime: micros(1_700_000_123_456),
hash: "aGFzaA==",
},
file: { decryptionHeader: "aGVhZGVy", size: 2_048_000 },
}),
],
);
const photo = apis(records).photos.byID({ fileID: 1001 })!;
expect(photo.modifiedAt).toBe(ms(1_700_000_123_456));
expect(photo.hash).toBe("aGFzaA==");
expect(photo.fileSize).toBe(2_048_000);
expect(photo.year).toBe(2021);
});
it("byID returns undefined for an unknown file id", () => {
const records = deriveRecords([collection(1)], [file(1, 1)]);
expect(apis(records).photos.byID({ fileID: 999 })).toBeUndefined();