@paroicms/connector
Version:
An API to help build management tools for ParoiCMS instances
97 lines • 3.66 kB
JavaScript
import { getNodeTypeByName } from "@paroicms/internal-anywhere-lib";
import { makeDefaultRelativeId, parseSqliteDateTime } from "@paroicms/internal-server-lib";
import { type } from "arktype";
const CreateNodeParentNodeAT = type({
typeName: "string",
depth: "number",
"+": "reject",
});
const CreateNodeInsertedAT = type({
id: "number",
publishDate: "string|number|Date",
"+": "reject",
}).pipe((r) => ({
id: String(r.id),
publishDate: parseSqliteDateTime(r.publishDate),
}));
export async function createNode(siteSchema, cn, { parentId, depth, typeName, }) {
const nodeType = getNodeTypeByName(siteSchema, typeName); // the node can be a part too
const documentType = nodeType.kind === "document" ? nodeType : undefined;
let nodeDepth = depth;
if (nodeDepth === undefined) {
if (!parentId)
throw new Error("parentId not provided");
const row = await cn("PaNode").select("typeName", "depth").where("id", parentId).first();
if (!row)
throw new Error(`cannot find parent node '${parentId}'`);
const parentNode = CreateNodeParentNodeAT.assert(row);
nodeDepth = parentNode.depth + 1;
if (!isTypeNameChildOf(siteSchema, { typeName, parentTypeName: parentNode.typeName })) {
throw new Error(`invalid parentTypeName '${parentNode.typeName}'`);
}
}
const makeRelativeId = provideRelativeIdGenerator(documentType && documentType.documentKind === "regular"
? documentType.relativeIdGenerator
: undefined);
let attempt = 0;
while (true) {
const newRelativeId = makeRelativeId();
try {
const [inserted] = await cn("PaNode")
.insert({
parentId,
relativeId: newRelativeId,
depth: nodeDepth,
typeName,
publishDate: cn.fn.now(),
})
.returning(["id", "publishDate"]);
const { id: newId, publishDate } = CreateNodeInsertedAT.assert(inserted);
return {
id: newId,
relativeId: newRelativeId,
depth: nodeDepth,
typeName,
publishDate,
parentId,
};
}
catch (err) {
if (++attempt === 20)
throw err;
// ignore error and retry
}
}
}
export function isTypeNameChildOf(siteSchema, { parentTypeName, typeName }) {
const parentType = getNodeTypeByName(siteSchema, parentTypeName);
if (parentType.kind === "site") {
return typeName === "home";
}
if (parentType.kind === "document") {
const childType = getNodeTypeByName(siteSchema, typeName);
if (childType.kind === "document") {
return ((parentType.regularChildren?.includes(childType.typeName) ||
parentType.routingChildren?.includes(childType.typeName)) ??
false);
}
for (const listType of parentType.lists ?? []) {
if (listType.parts.includes(typeName))
return true;
}
}
if (parentType.kind === "part") {
if (parentType.list?.parts.includes(typeName))
return true;
}
return false;
}
function provideRelativeIdGenerator(rim) {
const makerName = rim?.[0] ?? "default";
if (makerName === "default") {
const size = rim ? Number(rim[1]) : undefined;
return () => makeDefaultRelativeId({ size });
}
throw new Error(`Invalid relativeId maker name '${makerName}'`);
}
//# sourceMappingURL=init-node-queries.js.map