metadata.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import { openMetadataStore } from '../lib/bucket.js';
  2. export interface ImageMetadataInput {
  3. width: number;
  4. height: number;
  5. format: string;
  6. bytes: number;
  7. }
  8. export interface ImageMetadataRecord extends ImageMetadataInput {
  9. id: string;
  10. key: string;
  11. recordedAt: number;
  12. }
  13. /**
  14. * Record the image metadata for a stored object. Writes go to the metadata
  15. * store keyed by object key; the returned record carries the id the queue
  16. * message references.
  17. */
  18. export async function recordImageMetadata(
  19. key: string,
  20. input: ImageMetadataInput,
  21. ): Promise<ImageMetadataRecord> {
  22. const store = openMetadataStore();
  23. const record: ImageMetadataRecord = {
  24. ...input,
  25. id: metadataIdFor(key, input),
  26. key,
  27. recordedAt: 0,
  28. };
  29. await store.put(record.id, JSON.stringify(record));
  30. return record;
  31. }
  32. /** Deterministic id so a retried upload records the same metadata row. */
  33. export function metadataIdFor(key: string, input: ImageMetadataInput): string {
  34. return `${key}:${input.format}:${input.width}x${input.height}`;
  35. }
  36. /** Read a metadata record back for the download and listing paths. */
  37. export async function loadImageMetadata(id: string): Promise<ImageMetadataRecord | null> {
  38. const store = openMetadataStore();
  39. const raw = await store.get(id);
  40. return raw ? (JSON.parse(raw) as ImageMetadataRecord) : null;
  41. }
  42. /** Normalize a client-declared format string to the canonical set. */
  43. export function normalizeFormat(format: string): string {
  44. const lowered = format.trim().toLowerCase();
  45. if (lowered === 'jpg') return 'jpeg';
  46. if (lowered === 'tif') return 'tiff';
  47. return lowered;
  48. }