UNPKG

@npio/internals

Version:

A free visual website editor, powered with your own SolidJS components.

169 lines (148 loc) 4.43 kB
import { NitroProject } from "@prisma/client"; import { redirect } from "@solidjs/router"; import { useContext } from "solid-js"; import { getRequestEvent } from "solid-js/web"; import { PageVisit } from "../../../types"; import { ConfigContext } from "../../context/page"; import { normalizeState } from "../../normalization"; import { getClientConfig, getEventProject } from "../../request"; import { baseFilename } from "../../string"; import { getPublishedRevision } from "../revision"; import { useDatabase } from "./../prisma"; import { getSettings, notFoundPage } from "./../settings"; export const blueprintPaths: Record<string, string> = (( globalThis as any ).npBlueprintPaths ??= {}); const passiveBlueprints: Record<string, boolean> = (( globalThis as any ).npPassiveBlueprints ??= {}); let firstLoad = true; const getPageState = async function ({ urlPath, project, }: { urlPath: string; project: NitroProject; }) { let pageRevision = await getPublishedRevision({ urlPath, projectId: project.id, }); if (!pageRevision) { const notFoundPage_ = await notFoundPage({ projectId: project?.id, }); if (notFoundPage_.value) { pageRevision = await getPublishedRevision({ projectId: project?.id, pageId: notFoundPage_.value, }); } } if (!pageRevision) { return; } const settings = await getSettings({ projectId: project?.id, pageId: pageRevision.pageId, }); settings.blueprintDefaults.value = {}; const prisma = useDatabase(); const fonts = await prisma.nitroFont.findMany({ where: { projectId: project.id, }, omit: { createdAt: true, updatedAt: true, }, include: { faces: { omit: { createdAt: true, updatedAt: true, }, }, }, }); return normalizeState({ pageRevision, fonts, presets: [], settings, passiveBlueprints, }); }; export const getPageVisit = async (args: { urlPath: string; }): Promise<PageVisit | undefined> => { const configCtx = useContext(ConfigContext)!; // Removing trailing slash from urls *PT2* // Trailing slashes are handled in two places: middleware & getPageVisit // Here we handle client-side navigation (navigating from one page to the next) if (args.urlPath !== "/" && args.urlPath.slice(-1) === "/") { throw redirect(args.urlPath.slice(0, -1), { status: 301, }); } const project = getEventProject(); const nitropageConfig = getClientConfig(); if (!project || !nitropageConfig) { return; } const updateBlueprintFiles = firstLoad || !import.meta.env.PROD; if (updateBlueprintFiles) { try { for (const [filePath, loader] of Object.entries( nitropageConfig.blueprints(), )) { const module = await loader(); const id = module.id || baseFilename(filePath).toLowerCase(); blueprintPaths[id] = filePath; if (module.passive) { passiveBlueprints[id] = true; } } firstLoad = false; } catch (err) { console.error(err); } } const state = await getPageState({ urlPath: args.urlPath, project }); if (!state) { return; } const isSSR = !!configCtx; const event = getRequestEvent()!; event.locals.npElements = {}; const dynamicBlueprintIds: Record<string, boolean> = {}; const blueprintIds: Record<string, boolean> = {}; const layoutIds: Record<string, boolean> = {}; for (const element of Object.values(state.elements)) { if (element.blueprintId && blueprintPaths[element.blueprintId]) { blueprintIds[element.blueprintId] = true; if (element.dynamic) { dynamicBlueprintIds[element.blueprintId] = true; } } if (element.layoutId) { layoutIds[element.layoutId] = true; event.locals.npElements[element.id] = element; continue; } if (import.meta.env.PROD && isSSR) { event.locals.npElements[element.id] = { ...element }; if (!element.dynamic) { // Data for non-dynamic elements doesn't have to be available for client hydration // During ssr we access the data via event.locals.npElements delete (element as any).data; } } } return { state, dynamicBlueprintIds: Object.keys(dynamicBlueprintIds), blueprintIds: Object.keys(blueprintIds), layoutIds: Object.keys(layoutIds), }; };