Files
gerbeur/api/services/attachment-service.ts

43 lines
1.3 KiB
TypeScript

import { db } from "../model/db.ts";
import { APIErrorCode, APIException } from "../model/interfaces.ts";
export function createAttachment(id: string, mime: string): void {
db.prepare(
"INSERT INTO attachments (id, mime, created_at) VALUES (?, ?, ?)",
).run(id, mime, new Date().toISOString());
}
export function getAttachment(attachmentId: string): { mime: string } {
const row = db.prepare(
"SELECT mime FROM attachments WHERE id = ?",
).get(attachmentId) as { mime: string } | undefined;
if (!row) {
throw new APIException(
APIErrorCode.NOT_FOUND,
404,
"Attachment not found",
);
}
return { mime: row.mime };
}
// UUID pattern used to extract attachment IDs from markdown/text bodies.
const ATTACHMENT_RE =
/\/api\/attachments\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/g;
/**
* Parse `text` for attachment URLs and bind any unowned attachments to
* `resourceId`. Only updates rows where resource_id IS NULL so a user cannot
* claim attachments that already belong to another resource.
*/
export function linkAttachments(text: string, resourceId: string): void {
const ids = [...text.matchAll(ATTACHMENT_RE)].map((m) => m[1]);
for (const id of ids) {
db.prepare(
"UPDATE attachments SET resource_id = ? WHERE id = ? AND resource_id IS NULL",
).run(resourceId, id);
}
}