UNPKG

@paroicms/server

Version:
143 lines 5.42 kB
import { getDocumentTypeByName } from "@paroicms/internal-anywhere-lib"; import { encodeLNodeId, } from "@paroicms/public-anywhere-lib"; import { assignLoadDescriptor } from "@paroicms/public-server-lib"; import { type } from "arktype"; import { applyRegularChildrenSortingOnQuery } from "../common/child-ordering-query.js"; import { makeCacheDependencyKey } from "../common/text-cache.js"; import { mainDbSchemaName } from "../connector/db-init/db-constants.js"; import { createLiquidDrop } from "../liquidjs-tools/liquidjs-drop.js"; export function getSiblingDocuments(renderingContext, documentId) { const { siteContext } = renderingContext; const renderingCacheKey = `doc:${encodeLNodeId(documentId)}:siblings`; return createLiquidDrop(renderingContext, async () => { const parentNode = await getParentNode(siteContext, renderingContext.tracker, documentId.nodeId); if (!parentNode || parentNode.parentTypeName === "_site") { return { renderingCacheKey, values: { previous: undefined, next: undefined }, }; } const parentDocumentType = getDocumentTypeByName(siteContext.siteSchema, parentNode.parentTypeName); if (!parentDocumentType.regularChildrenSorting) { return { renderingCacheKey, values: { previous: undefined, next: undefined }, }; } const { previousDocumentId, nextDocumentId } = await getSiblingDocumentIds(siteContext, renderingContext.tracker, { parentDocumentType, parentNodeId: parentNode.parentNodeId, documentId, }); renderingContext.addDependencyKey(makeCacheDependencyKey({ documentId: { nodeId: parentNode.parentNodeId, language: documentId.language, }, relation: "children", })); return { renderingCacheKey, values: { previous: previousDocumentId ? assignLoadDescriptor({}, { load: "one", nodeKind: "document", descriptorName: "id", documentId: previousDocumentId, }) : undefined, next: nextDocumentId ? assignLoadDescriptor({}, { load: "one", nodeKind: "document", descriptorName: "id", documentId: nextDocumentId, }) : undefined, }, }; }); } const ParentNodeRowAT = type({ parentTypeName: "string", parentId: "number", "+": "reject", }).pipe((r) => ({ parentTypeName: r.parentTypeName, parentNodeId: String(r.parentId), })); async function getParentNode(siteContext, tracker, nodeId) { const row = await siteContext .cn("PaNode as n") .select(["n2.typeName as parentTypeName", "n2.id as parentId"]) .where("n.id", nodeId) .innerJoin("PaNode as n2", "n2.id", "n.parentId") .first(); tracker.trackAccess(mainDbSchemaName, "PaNode", "read"); if (!row) return; return ParentNodeRowAT.assert(row); } const SiblingIdsRowAT = type({ prevId: "number|null", nextId: "number|null", "+": "reject", }).pipe((data) => ({ prevNodeId: data.prevId === null ? undefined : String(data.prevId), nextNodeId: data.nextId === null ? undefined : String(data.nextId), })); async function getSiblingDocumentIds(siteContext, tracker, { documentId, parentNodeId, parentDocumentType, }) { const { language } = documentId; const { cn } = siteContext; const subQuery = cn("PaNode as n") .innerJoin("PaLNode as l", { "l.nodeId": "n.id", "l.language": cn.raw("?", [language]), }) .innerJoin("PaDocument as d", { "d.nodeId": "l.nodeId", "d.language": "l.language", }) .where("n.parentId", parentNodeId) .andWhere("l.ready", 1) .andWhere("n.publishDate", "<=", cn.fn.now()); const { orderBy } = applyRegularChildrenSortingOnQuery(siteContext, { query: subQuery, parentDocumentType, orderByAsString: true, leftJoinDocument: false, }); if (!orderBy) return {}; subQuery.select([ "n.id as id", cn.raw("lag(n.id) over (?) as prevId", [cn.raw("order by ?", [cn.raw(orderBy)])]), cn.raw("lead(n.id) over (?) as nextId", [cn.raw("order by ?", [cn.raw(orderBy)])]), ]); const query = cn .with("ordered_nodes", subQuery) .select(["prevId", "nextId"]) .from("ordered_nodes") .where("id", documentId.nodeId); const row = await query.first(); tracker.trackAccess(mainDbSchemaName, "PaNode", "read"); if (!row) return {}; const { prevNodeId, nextNodeId } = SiblingIdsRowAT.assert(row); return { previousDocumentId: prevNodeId === undefined ? undefined : { nodeId: prevNodeId, language, }, nextDocumentId: nextNodeId === undefined ? undefined : { nodeId: nextNodeId, language, }, }; } //# sourceMappingURL=get-siblings.queries.js.map