UNPKG

@oberoncms/core

Version:

OberonCMS is a cloud deployable CMS written in typescript based on the Puck visual editor

280 lines (279 loc) 7.85 kB
import { unstable_cache, revalidateTag, revalidatePath } from "next/cache"; import { streamResponse } from "@tohuhono/utils"; import { version } from "../package.json.js"; import { AddPageSchema, INITIAL_DATA, DeletePageSchema, PublishPageSchema, AddImageSchema, AddUserSchema, DeleteUserSchema, ChangeRoleSchema, ResponseError } from "../lib/dtd.js"; import { getTransforms, getComponentTransformVersions, applyTransforms } from "./transforms.js"; import { exportTailwindClasses } from "./export-tailwind-clases.js"; function initAdapter({ config, versions, pluginAdapter: adapter }) { const can = async (action, permission = "read") => { if (adapter.hasPermission({ action, permission })) { return true; } const user = await adapter.getCurrentUser(); return adapter.hasPermission({ user, action, permission }); }; const will = async (action, permission) => { if (await can(action, permission)) { return; } throw new ResponseError("You do not have permission to perform this action"); }; const whoWill = async (action, permission) => { const user = await adapter.getCurrentUser(); if (user && adapter.hasPermission({ user, action, permission })) { return user; } throw new ResponseError("You do not have permission to perform this action"); }; const getAllPagesCached = unstable_cache( async () => { const sortPages = (a, b) => { if (a.key < b.key) { return -1; } if (a.key > b.key) { return 1; } return 0; }; const result = await adapter.getAllPages(); const data = result.sort(sortPages); return data; }, void 0, { tags: ["oberon-pages"] } ); const getAllPathsCached = unstable_cache( async () => { const result = await adapter.getAllPages(); const data = result.map((row) => ({ path: row["key"].split("/").slice(1) })); return data; }, void 0, { tags: ["oberon-pages"] } ); const getPageDataCached = async (key) => { const dataString = await adapter.getPageData(key); return dataString; }; const getAllUsersCached = unstable_cache( async () => { const allUsers = await adapter.getAllUsers(); return allUsers || []; }, void 0, { tags: ["oberon-users"] } ); const getAllImagesCached = unstable_cache( async () => { const allImages = await adapter.getAllImages(); return allImages || []; }, void 0, { tags: ["oberon-images"] } ); const updatePageData = async ({ key, data, updatedBy }) => { await adapter.updatePageData({ key, data, updatedAt: /* @__PURE__ */ new Date(), updatedBy }); revalidatePath(key); revalidateTag("oberon-pages"); }; const getConfigCached = unstable_cache( async () => { const site = await adapter.getSite(); const { components, transforms } = getTransforms(site == null ? void 0 : site.components, config); const siteConfig = { version, plugins: versions, components, pendingMigrations: transforms && Object.keys(transforms) }; if (!site) { await adapter.updateSite({ version: config.version, components: getComponentTransformVersions(config), updatedAt: /* @__PURE__ */ new Date(), updatedBy: "system" }); } return siteConfig; }, void 0, { tags: ["oberon-config"] } ); const migrate = streamResponse(async function* (user) { const summary = { type: "summary", error: [], success: [], total: 0 }; const site = await adapter.getSite(); const { transforms } = getTransforms(site == null ? void 0 : site.components, config); if (!transforms) { return summary; } const pages = await getAllPagesCached(); const results = applyTransforms({ transforms, pages, getPageData: getPageDataCached, updatePageData }); for await (const result of results) { summary[result.status].push(result.key); yield result; } await adapter.updateSite({ version: config.version, components: getComponentTransformVersions(config), updatedAt: /* @__PURE__ */ new Date(), updatedBy: user.email }); revalidateTag("oberon-config"); yield { ...summary, total: pages.length }; }); return { prebuild: async () => { await adapter.prebuild(); await exportTailwindClasses(adapter); }, /* * Auth */ can, signIn: adapter.signIn, signOut: adapter.signOut, /* * Site actions */ getConfig: async () => { await will("site", "read"); return await getConfigCached(); }, migrateData: async () => { const user = await whoWill("site", "write"); return migrate(user); }, /* * Page actions */ getAllPaths: async function() { await will("pages", "read"); return getAllPathsCached(); }, getAllPages: async function() { await will("pages", "read"); return getAllPagesCached(); }, getPageData: async function(key) { await will("pages", "read"); return getPageDataCached(key); }, // TODO return value addPage: async function(data) { const user = await whoWill("pages", "write"); const { key } = AddPageSchema.parse(data); await adapter.addPage({ key, data: INITIAL_DATA, updatedAt: /* @__PURE__ */ new Date(), updatedBy: user.email }); revalidatePath(key); revalidateTag("oberon-pages"); }, // TODO return value deletePage: async function(data) { await will("pages", "write"); const { key } = DeletePageSchema.parse(data); await adapter.deletePage(key); revalidatePath(key); revalidateTag("oberon-pages"); }, publishPageData: async function(data) { const user = await whoWill("pages", "write"); const { key, data: pageData } = PublishPageSchema.parse(data); await updatePageData({ key, data: pageData, updatedBy: user.email }); return { message: `Successfully published ${key}` }; }, /* * Image actions */ getAllImages: async function() { await will("images", "read"); return getAllImagesCached(); }, addImage: async function(data) { await will("images", "write"); const image = AddImageSchema.parse(data); await adapter.addImage(image); revalidateTag("oberon-images"); return adapter.getAllImages(); }, // TODO uploadthing deleteImage: async function(data) { await will("images", "write"); revalidateTag("oberon-images"); return adapter.deleteImage(data); }, /* * User actions */ getAllUsers: async function() { await will("users", "read"); return getAllUsersCached(); }, addUser: async function(data) { await will("users", "write"); const { email, role } = AddUserSchema.parse(data); const { id } = await adapter.addUser({ email, role }); revalidateTag("oberon-users"); return { id, email, role }; }, deleteUser: async function(data) { await will("users", "write"); const { id } = DeleteUserSchema.parse(data); await adapter.deleteUser(id); revalidateTag("oberon-users"); return { id }; }, changeRole: async function(data) { await will("users", "write"); const { role, id } = ChangeRoleSchema.parse(data); await adapter.changeRole({ role, id }); revalidateTag("oberon-users"); return { role, id }; } }; } export { initAdapter };