@paroicms/server
Version:
The ParoiCMS server
160 lines • 6.04 kB
JavaScript
import { getDocumentTypeByName } from "@paroicms/internal-anywhere-lib";
import { parseSqliteDateTime } from "@paroicms/internal-server-lib";
import { type } from "arktype";
import { getTypeNameOf } from "../admin-backend/node/node.queries.js";
import { applyRegularChildrenSortingOnQuery } from "../common/child-ordering-query.js";
import { makeCacheDependencyKey } from "../common/text-cache.js";
import { mainDbSchemaName } from "../connector/db-init/db-constants.js";
export async function getDocItem(siteContext, tracker, documentId, options = {}) {
const query = siteContext.cn("PaDocument as d");
querySelectDocValues(query, { omitId: true });
query
.innerJoin("PaLNode as s", {
"s.nodeId": "d.nodeId",
"s.language": "d.language",
})
.innerJoin("PaNode as l", "l.id", "d.nodeId")
.where({
"d.nodeId": documentId.nodeId,
"d.language": documentId.language,
"s.ready": 1,
})
.whereRaw("l.publishDate <= current_timestamp");
const row = await query.first();
tracker.trackAccess(mainDbSchemaName, "PaDocument", "read");
if (!row) {
if (options.allowUndef)
return;
throw new Error(`unknown document '${documentId.language}:${documentId.nodeId}'`);
}
return formatDocValues(row, documentId);
}
export async function getPaginatedListOfDocValues(renderingContext, options) {
const { siteContext } = renderingContext;
const { pageIndex, pageSize, ...otherOptions } = options;
const items = await getListOfDocValues(renderingContext, {
offset: options.pageIndex > 0 ? options.pageIndex * options.pageSize : undefined,
limit: options.pageSize,
...otherOptions,
});
const total = options.pageSize === items.length
? await countDocItems(siteContext, renderingContext.tracker, { parentId: options.parentId })
: items.length;
return {
items,
total,
pageIndex,
pageCount: Math.ceil(total / pageSize),
pageSize,
};
}
export async function getListOfDocValues(renderingContext, options) {
const { siteContext } = renderingContext;
const { parentId, documentKind } = options;
const parentTypeName = await getTypeNameOf(siteContext, parentId.nodeId);
const parentDocumentType = getDocumentTypeByName(siteContext.siteSchema, parentTypeName);
const typeNames = documentKind === "regular"
? parentDocumentType.regularChildren
: parentDocumentType.routingChildren;
if (!typeNames?.length)
return [];
renderingContext.addDependencyKey(makeCacheDependencyKey({
relation: "children",
documentId: parentId,
}));
const query = createBaseDocItemsQueryBuilder(siteContext, { parentId });
query.whereIn("l.typeName", typeNames);
querySelectDocValues(query);
applyRegularChildrenSortingOnQuery(siteContext, {
query,
parentDocumentType,
regularChildrenSorting: options.orderBy,
});
if (options.labeledBy) {
const { fieldName, termNodeId } = options.labeledBy;
query
.innerJoin("PaFieldLabeling as f", "f.nodeId", "l.id")
.where("f.termId", termNodeId)
.where("f.field", fieldName);
renderingContext.addDependencyKey(makeCacheDependencyKey({
relation: "labeled",
termNodeId: termNodeId,
fieldName,
}));
}
if (options.offset !== undefined) {
query.offset(options.offset);
}
if (options.limit !== undefined) {
query.limit(options.limit);
}
const rows = await query;
renderingContext.tracker.trackAccess(mainDbSchemaName, "PaDocument", "read");
return rows.map((row) => formatDocValues(row, { language: parentId.language }));
}
const CountDocItemsRowAT = type({
cnt: "number",
"+": "reject",
});
async function countDocItems(siteContext, tracker, { parentId }) {
const query = createBaseDocItemsQueryBuilder(siteContext, { parentId });
const row = await query.count("* as cnt").first();
tracker.trackAccess(mainDbSchemaName, "PaDocument", "read");
if (!row)
return 0;
return CountDocItemsRowAT.assert(row).cnt;
}
export function querySelectDocValues(query, { omitId } = {}) {
if (!omitId) {
query.select("l.id as nodeId");
}
query.select("l.typeName", "l.relativeId", "d.title", "d.slug", "l.publishDate", "d.metaDescription", "d.metaKeywords");
}
function createBaseDocItemsQueryBuilder(siteContext, { parentId }) {
const { cn } = siteContext;
return cn("PaNode as l")
.innerJoin("PaLNode as s", {
"s.nodeId": "l.id",
"s.language": cn.raw("?", [parentId.language]),
})
.innerJoin("PaDocument as d", {
"d.nodeId": "s.nodeId",
"d.language": "s.language",
})
.where("l.parentId", parentId.nodeId)
.where("s.ready", 1)
.whereRaw("l.publishDate <= current_timestamp");
}
const DocValuesRowAT = type({
typeName: "string",
nodeId: "number|string",
language: "string",
relativeId: "string",
publishDate: "Date|string|number",
title: "string|null",
slug: "string|null",
metaDescription: "string|null",
metaKeywords: "string|null",
"+": "reject",
}).pipe((r) => ({
type: r.typeName,
nodeId: String(r.nodeId),
language: r.language,
relativeId: r.relativeId,
publishDate: parseSqliteDateTime(r.publishDate).toISOString(),
title: r.title ?? undefined,
slug: r.slug ?? undefined,
metaDescription: r.metaDescription ?? undefined,
metaKeywords: r.metaKeywords ?? undefined,
}));
export function formatDocValues(row, { language, nodeId, typeName } = {}) {
const completed = { ...row };
if (language)
completed.language = language;
if (nodeId)
completed.nodeId = nodeId;
if (typeName)
completed.typeName = typeName;
return DocValuesRowAT.assert(completed);
}
//# sourceMappingURL=doc-values.queries.js.map