47 lines
1.1 KiB
TypeScript
47 lines
1.1 KiB
TypeScript
import type { ValidatedImage } from "@/lib/share/validation";
|
|
|
|
export type ShareAuthor = {
|
|
userId: string;
|
|
discordId: string;
|
|
displayName: string;
|
|
avatarUrl: string | null;
|
|
};
|
|
|
|
export type CreateShareInput = {
|
|
content: string;
|
|
description: string | null;
|
|
image: ValidatedImage | null;
|
|
source: "web" | "bot";
|
|
author: ShareAuthor;
|
|
};
|
|
|
|
export type CreatedShare = {
|
|
id: string;
|
|
imageCdnId: string | null;
|
|
createdAt: Date;
|
|
};
|
|
|
|
export type CreateShareTransaction = {
|
|
insertImage(image: ValidatedImage, ownerDiscordId: string): Promise<string>;
|
|
insertShare(
|
|
input: CreateShareInput,
|
|
imageCdnId: string | null,
|
|
): Promise<CreatedShare>;
|
|
};
|
|
|
|
export type CreateShareStore = {
|
|
transaction<T>(callback: (tx: CreateShareTransaction) => Promise<T>): Promise<T>;
|
|
};
|
|
|
|
export function createShareAtomically(
|
|
input: CreateShareInput,
|
|
store: CreateShareStore,
|
|
) {
|
|
return store.transaction(async (tx) => {
|
|
const imageCdnId = input.image
|
|
? await tx.insertImage(input.image, input.author.discordId)
|
|
: null;
|
|
return tx.insertShare(input, imageCdnId);
|
|
});
|
|
}
|