/** * Image Attachment Manifest * * Per-work-item record of attachment files synced between local disk and ADO. * Stored at `{syncFolder}/{workItemId}/.attachments.json`. * * The manifest is the source of truth for "is this image already on ADO?": * - On pull: each downloaded ADO attachment is recorded with `source: "ado-pull"`. * - On push: when a local image src matches a manifest entry, the original * ADO URL is reused (no re-upload). When it doesn't match, the file is * uploaded as a new attachment and added with `source: "local-uploaded"`. */ export type AttachmentSource = 'ado-pull' | 'local-uploaded'; export interface AttachmentManifestEntry { /** ADO attachment GUID */ guid: string; /** Original filename as stored in ADO */ fileName: string; /** Path relative to the work item folder (e.g. "attachments/{guid}-image.png") */ localPath: string; /** Original ADO attachment URL (used to re-reference on push) */ originalUrl: string; /** Where the entry came from */ source: AttachmentSource; /** ADO field reference name where the image was first seen (informational) */ field?: string; /** ISO timestamp of upload (for local-uploaded entries) */ uploadedAt?: string; } export interface AttachmentManifest { workItemId: number; lastSyncedAt: string; attachments: AttachmentManifestEntry[]; } /** Folder for a work item's attachments + manifest. */ export declare function getWorkItemAttachmentDir(syncFolder: string, workItemId: number): string; /** Folder where the binary attachment files live. */ export declare function getAttachmentsBinDir(syncFolder: string, workItemId: number): string; /** Path to the manifest JSON file. */ export declare function getManifestPath(syncFolder: string, workItemId: number): string; /** * Build the local relative path for a downloaded attachment. * Example: `attachments/5e5c125f-...-image.png`. * * The GUID prefix keeps filenames unique even when ADO returns generic names * like "image.png" for many different attachments. */ export declare function buildLocalAttachmentPath(guid: string, fileName: string): string; /** Read manifest from disk. Returns an empty manifest if the file is missing. */ export declare function readManifest(syncFolder: string, workItemId: number): Promise; /** Write manifest to disk, creating the parent directory if needed. */ export declare function writeManifest(syncFolder: string, manifest: AttachmentManifest): Promise; /** * Add (or replace) an entry in the manifest. Lookup is by `guid` — the same * attachment is never recorded twice. Returns the manifest unchanged when an * existing entry has the same guid AND localPath, otherwise replaces it. */ export declare function upsertEntry(manifest: AttachmentManifest, entry: AttachmentManifestEntry): AttachmentManifest; /** * Look up a manifest entry by its local path (relative to the work item folder). * Used on push to recognise images that came from ADO and avoid re-uploading. */ export declare function findEntryByLocalPath(manifest: AttachmentManifest, localPath: string): AttachmentManifestEntry | undefined; /** Look up an entry by its original ADO URL. */ export declare function findEntryByAdoUrl(manifest: AttachmentManifest, url: string): AttachmentManifestEntry | undefined; //# sourceMappingURL=image-manifest.d.ts.map