UNPKG

@paroicms/connector

Version:

An API to help build management tools for ParoiCMS instances

97 lines 3.66 kB
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