import "reflect-metadata"; import { injectable } from "inversify"; import { getPayload } from "payload"; import type { SanitizedConfig } from "payload"; import type { IArticlesRepository } from "../../application/repositories/articles-repository.interface"; import type { Article } from "../../entities/article"; type PayloadArticleDoc = { id: string | number; title?: string | null; slug?: string | null; content?: unknown; status?: string | null; author?: string | number | { id: string | number } | null; createdAt?: string | null; updatedAt?: string | null; }; function mapDoc(doc: PayloadArticleDoc): Article { const authorId = typeof doc.author === "object" && doc.author !== null ? String(doc.author.id) : doc.author != null ? String(doc.author) : ""; return { id: String(doc.id), title: doc.title ?? "", slug: doc.slug ?? "", content: doc.content ?? null, status: doc.status === "published" ? "published" : "draft", authorId, createdAt: doc.createdAt ? new Date(doc.createdAt) : new Date(0), updatedAt: doc.updatedAt ? new Date(doc.updatedAt) : new Date(0), }; } @injectable() export class PayloadArticlesRepository implements IArticlesRepository { private config: SanitizedConfig; constructor(config: SanitizedConfig) { this.config = config; } async getArticle(id: string): Promise
{ const payload = await getPayload({ config: this.config }); try { const doc = await payload.findByID({ collection: "articles", id, overrideAccess: false, }); return mapDoc(doc as PayloadArticleDoc); } catch { return undefined; } } async getArticleBySlug(slug: string): Promise
{ const payload = await getPayload({ config: this.config }); const result = await payload.find({ collection: "articles", where: { slug: { equals: slug } }, limit: 1, overrideAccess: false, }); const doc = result.docs[0] as PayloadArticleDoc | undefined; return doc ? mapDoc(doc) : undefined; } async getArticles(options?: { status?: string; authorId?: string; limit?: number; offset?: number; }): Promise { const payload = await getPayload({ config: this.config }); const where: Record = {}; if (options?.status) where.status = { equals: options.status }; if (options?.authorId) where.author = { equals: options.authorId }; const result = await payload.find({ collection: "articles", where: where as never, limit: options?.limit ?? 50, page: options?.offset ? Math.floor(options.offset / (options.limit ?? 50)) + 1 : 1, overrideAccess: false, }); return result.docs.map((d) => mapDoc(d as PayloadArticleDoc)); } async createArticle(input: Article): Promise
{ const payload = await getPayload({ config: this.config }); const created = await payload.create({ collection: "articles", data: { title: input.title, slug: input.slug, content: input.content, status: input.status, author: input.authorId, } as never, overrideAccess: false, }); return mapDoc(created as PayloadArticleDoc); } async updateArticle( id: string, input: Partial
, ): Promise
{ const payload = await getPayload({ config: this.config }); try { const updated = await payload.update({ collection: "articles", id, data: { ...(input.title !== undefined && { title: input.title }), ...(input.slug !== undefined && { slug: input.slug }), ...(input.content !== undefined && { content: input.content }), ...(input.status !== undefined && { status: input.status }), ...(input.authorId !== undefined && { author: input.authorId }), } as never, overrideAccess: false, }); return mapDoc(updated as PayloadArticleDoc); } catch { return undefined; } } }