@paroicms/server
Version:
The ParoiCMS server
133 lines • 5.32 kB
JavaScript
import { getDocumentTypeByName } from "@paroicms/internal-anywhere-lib";
import { encodeLNodeId, } from "@paroicms/public-anywhere-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";
import { createDocPayloadDrop } from "./create-doc-drop.js";
import { getDocItem } from "./doc-values.queries.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,
});
return {
renderingCacheKey,
values: {
previous: previousDocumentId
? createDocPayloadDrop(renderingContext, () => {
renderingContext.addDependencyKey(makeCacheDependencyKey({ documentId: previousDocumentId }));
return getDocItem(siteContext, renderingContext.tracker, previousDocumentId);
})
: undefined,
next: nextDocumentId
? createDocPayloadDrop(renderingContext, () => {
renderingContext.addDependencyKey(makeCacheDependencyKey({ documentId: nextDocumentId }));
return getDocItem(siteContext, renderingContext.tracker, 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 l")
.select(["l2.typeName as parentTypeName", "l2.id as parentId"])
.where("l.id", nodeId)
.innerJoin("PaNode as l2", "l2.id", "l.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 l")
.innerJoin("PaLNode as s", {
"s.nodeId": "l.id",
"s.language": cn.raw("?", [language]),
})
.innerJoin("PaDocument as d", {
"d.nodeId": "s.nodeId",
"d.language": "s.language",
})
.where("l.parentId", parentNodeId)
.andWhere("s.ready", 1)
.andWhere("l.publishDate", "<=", cn.fn.now());
const { orderBy } = applyRegularChildrenSortingOnQuery(siteContext, {
query: subQuery,
parentDocumentType,
orderByAsString: true,
leftJoinDocument: false,
});
if (!orderBy)
return {};
subQuery.select([
"l.id as id",
cn.raw("lag(l.id) over (?) as prevId", [cn.raw("order by ?", [cn.raw(orderBy)])]),
cn.raw("lead(l.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