UNPKG

nitropage

Version:

A free and open source, extensible visual page builder based on SolidStart.

264 lines (240 loc) 6.13 kB
import { State } from "#../types"; import { NitroPage, NitroPageRevision } from "@prisma/client"; import { isEqual } from "es-toolkit"; import { error } from "../../../response"; import { updateFonts } from "../../font"; import updateLayoutSlots from "../../layout/update"; import { logger } from "../../log"; import { useDatabase } from "../../prisma"; import { setDefaultFont, setFavicon, setMetaDescription, setMetaImage, setNotFoundPage, setPageBackgroundColor, Settings, } from "../../settings"; import { DEBUG_PAGE_UPDATE } from "../../util"; import { publishPage } from "../publish"; import updateBlueprintDefaults from "./blueprintDefaults"; import { updateColors, updateRteColors } from "./colors"; import updatePresets from "./presets"; import createPageRevision from "./revision"; const updateSettings = async ({ page, state, prevState, settings, prevSettings, }: { state: State; prevState?: State; page: NitroPage; settings: { pages: Partial<Settings>; projects: Partial<Settings>; }; prevSettings?: { pages: Partial<Settings>; projects: Partial<Settings>; }; }) => { const db = useDatabase(); if (state.defaultFont !== prevState?.defaultFont) { if (DEBUG_PAGE_UPDATE) logger.info("Update default font"); if (state.defaultFont) { const font = await db.nitroFont.findUnique({ where: { publicId: state.defaultFont, }, }); await setDefaultFont(font?.id, { projectId: page.projectId, }); } else { await setDefaultFont(undefined, { projectId: page.projectId, }); } } if (state.metaDescription !== prevState?.metaDescription) { if (DEBUG_PAGE_UPDATE) logger.info("Update meta description"); await setMetaDescription( state.metaDescription !== "" ? state.metaDescription : undefined, { pageId: page.id, }, ); } if ( !isEqual( settings.pages.metaImage?.value, prevSettings?.pages.metaImage?.value, ) ) { if (DEBUG_PAGE_UPDATE) logger.info("Update page meta image"); await setMetaImage(settings.pages.metaImage?.value, { pageId: page.id, }); } if ( !isEqual( settings.projects.metaImage?.value, prevSettings?.projects.metaImage?.value, ) ) { if (DEBUG_PAGE_UPDATE) logger.info("Update project meta image", { prev: prevSettings?.projects.metaImage?.value, next: settings.projects.metaImage?.value, }); await setMetaImage(settings.projects.metaImage?.value, { projectId: page.projectId, }); } if ( !isEqual( settings.projects.favicon?.value, prevSettings?.projects.favicon?.value, ) ) { if (DEBUG_PAGE_UPDATE) logger.info("Update project favicon"); await setFavicon(settings.projects.favicon?.value, { projectId: page.projectId, }); } if (!isEqual(state.backgroundColor, prevState?.backgroundColor)) { if (DEBUG_PAGE_UPDATE) logger.info("Update background color"); await setPageBackgroundColor(state.backgroundColor, { projectId: page.projectId, }); } await updateColors({ page, state, prevState }); await updateRteColors({ page, state, prevState }); await updateBlueprintDefaults({ page, state, prevState }); if (!isEqual(state.notFound, prevState?.notFound)) { if (DEBUG_PAGE_UPDATE) logger.info("Update not found"); await setNotFoundPage(state.notFound ? page.id : undefined, { projectId: page.projectId, }); } }; export const updatePage = async ({ publish, pageRevisionId, prevState, state, prevSettings, settings, pageId, }: { publish?: boolean; pageRevisionId?: string; prevState?: State; state: State; prevSettings?: { pages: Partial<Settings>; projects: Partial<Settings>; }; settings: { pages: Partial<Settings>; projects: Partial<Settings>; }; pageId: string; }) => { const startTime = performance.now(); const db = useDatabase(); const page = await db.nitroPage.findUnique({ include: { layoutSlots: true, }, where: { id: pageId, }, }); if (!page) { return error({ message: "Page not found", status: 410, }); } let pageRevision: NitroPageRevision | undefined | null = undefined; if (pageRevisionId) { pageRevision = await db.nitroPageRevision.findFirst({ where: { id: pageRevisionId, page: { id: pageId }, }, }); } if (!pageRevision) { pageRevision = await db.nitroPageRevision.findFirst({ where: { page: { id: pageId }, }, orderBy: { savedAt: "desc", }, }); } if (!pageRevision) { return error({ message: "No page revision found", status: 410, }); } const parallelWork: Promise<any>[] = []; parallelWork.push( updateSettings({ state, prevState, page, settings, prevSettings }), ); parallelWork.push( updateFonts({ fonts: state.fonts, prevFonts: prevState?.fonts, }), ); if (state.includeInFeed !== prevState?.includeInFeed) { await db.nitroPage.update({ select: { id: true, }, where: { id: pageId, }, data: { includeInFeed: state.includeInFeed, }, }); } await updateLayoutSlots({ page, state, prevState }); const { deletedIds: deletedPresets } = await updatePresets({ projectId: page.projectId, presets: state.presets, prevPresets: prevState?.presets, }); if (state.pendingDeletes) { await db.nitroPreset.deleteMany({ where: { id: { in: state.pendingDeletes.presets }, }, }); } pageRevision = (await createPageRevision({ page, state, prevState, deletedPresets, })) ?? pageRevision; await Promise.all(parallelWork); if (publish) { await publishPage(pageRevision.id); } const endTime = performance.now(); if (DEBUG_PAGE_UPDATE) logger.info("Update page took", (endTime - startTime).toFixed(3) + "ms"); return { revisionId: pageRevision.id, }; };