feat(marketing-pages): add Payload-backed pages + site-settings repos (constructor-injected config)
This commit is contained in:
@@ -0,0 +1,96 @@
|
|||||||
|
import "reflect-metadata";
|
||||||
|
import { injectable } from "inversify";
|
||||||
|
import { getPayload } from "payload";
|
||||||
|
import type { SanitizedConfig } from "payload";
|
||||||
|
|
||||||
|
import type { IPagesRepository } from "../../application/repositories/pages-repository.interface";
|
||||||
|
import type { Page } from "../../entities/page";
|
||||||
|
|
||||||
|
type PayloadPageDoc = {
|
||||||
|
id: string | number;
|
||||||
|
title?: string | null;
|
||||||
|
slug?: string | null;
|
||||||
|
hero?:
|
||||||
|
| {
|
||||||
|
heading?: string | null;
|
||||||
|
subheading?: string | null;
|
||||||
|
image?: string | number | { id: string | number } | null;
|
||||||
|
}
|
||||||
|
| null;
|
||||||
|
layout?: unknown[] | null;
|
||||||
|
status?: string | null;
|
||||||
|
publishedAt?: string | null;
|
||||||
|
seo?: { title?: string | null; description?: string | null } | null;
|
||||||
|
createdAt?: string | null;
|
||||||
|
updatedAt?: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
function mapDoc(doc: PayloadPageDoc): Page {
|
||||||
|
const imageId =
|
||||||
|
doc.hero && typeof doc.hero.image === "object" && doc.hero.image !== null
|
||||||
|
? String(doc.hero.image.id)
|
||||||
|
: doc.hero?.image != null
|
||||||
|
? String(doc.hero.image)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: String(doc.id),
|
||||||
|
title: doc.title ?? "",
|
||||||
|
slug: doc.slug ?? "",
|
||||||
|
hero: {
|
||||||
|
heading: doc.hero?.heading ?? "",
|
||||||
|
subheading: doc.hero?.subheading ?? undefined,
|
||||||
|
imageId,
|
||||||
|
},
|
||||||
|
layout: doc.layout ?? [],
|
||||||
|
status: doc.status === "published" ? "published" : "draft",
|
||||||
|
publishedAt: doc.publishedAt ? new Date(doc.publishedAt) : null,
|
||||||
|
seo: {
|
||||||
|
title: doc.seo?.title ?? "",
|
||||||
|
description: doc.seo?.description ?? undefined,
|
||||||
|
},
|
||||||
|
createdAt: doc.createdAt ? new Date(doc.createdAt) : new Date(0),
|
||||||
|
updatedAt: doc.updatedAt ? new Date(doc.updatedAt) : new Date(0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class PayloadPagesRepository implements IPagesRepository {
|
||||||
|
private config: SanitizedConfig;
|
||||||
|
|
||||||
|
constructor(config: SanitizedConfig) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPageBySlug(slug: string): Promise<Page | undefined> {
|
||||||
|
const payload = await getPayload({ config: this.config });
|
||||||
|
const result = await payload.find({
|
||||||
|
collection: "pages",
|
||||||
|
where: { slug: { equals: slug } },
|
||||||
|
limit: 1,
|
||||||
|
overrideAccess: false,
|
||||||
|
});
|
||||||
|
const doc = result.docs[0] as PayloadPageDoc | undefined;
|
||||||
|
return doc ? mapDoc(doc) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPages(options?: {
|
||||||
|
status?: string;
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
}): Promise<Page[]> {
|
||||||
|
const payload = await getPayload({ config: this.config });
|
||||||
|
const where: Record<string, { equals: string }> = {};
|
||||||
|
if (options?.status) where.status = { equals: options.status };
|
||||||
|
const result = await payload.find({
|
||||||
|
collection: "pages",
|
||||||
|
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 PayloadPageDoc));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import "reflect-metadata";
|
||||||
|
import { injectable } from "inversify";
|
||||||
|
import { getPayload } from "payload";
|
||||||
|
import type { SanitizedConfig } from "payload";
|
||||||
|
|
||||||
|
import type { ISiteSettingsRepository } from "../../application/repositories/site-settings-repository.interface";
|
||||||
|
import type { SiteSettings } from "../../entities/site-settings";
|
||||||
|
|
||||||
|
type PayloadSiteSettings = {
|
||||||
|
siteName?: string | null;
|
||||||
|
siteDescription?: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class PayloadSiteSettingsRepository implements ISiteSettingsRepository {
|
||||||
|
private config: SanitizedConfig;
|
||||||
|
|
||||||
|
constructor(config: SanitizedConfig) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSiteSettings(): Promise<SiteSettings> {
|
||||||
|
const payload = await getPayload({ config: this.config });
|
||||||
|
const doc = (await payload.findGlobal({
|
||||||
|
slug: "site-settings",
|
||||||
|
overrideAccess: false,
|
||||||
|
})) as PayloadSiteSettings;
|
||||||
|
return {
|
||||||
|
siteName: doc.siteName ?? "My App",
|
||||||
|
siteDescription: doc.siteDescription ?? undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user