UNPKG

studiocms

Version:

Astro Native CMS for AstroDB. Built from the ground up by the Astro community.

201 lines (200 loc) 6.44 kB
import { Effect } from "../../../effect.js"; import { SDKCoreError, StudioCMS_SDK_Error } from "../errors.js"; import { tsPageFolderStructure } from "../tables.js"; import { AstroDB } from "./db.js"; class SDKCore_FolderTree extends Effect.Service()( "studiocms/sdk/SDKCore_FolderTree", { effect: Effect.gen(function* () { const dbService = yield* AstroDB; const generateFolderTree = (folders) => Effect.try({ try: () => { const folderMap = {}; for (const folder of folders) { folderMap[folder.id] = { id: folder.id, name: folder.name, pageData: null, page: false, children: [] }; } const rootFolders = []; for (const folder of folders) { const childFolder = folderMap[folder.id]; if (!childFolder) continue; if (folder.parent === null) { rootFolders.push(childFolder); } else { const parentFolder = folderMap[folder.parent]; if (parentFolder) { parentFolder.children.push(childFolder); } } } return rootFolders; }, catch: (error) => new SDKCoreError({ type: "UNKNOWN", cause: new StudioCMS_SDK_Error(`GenerateFolderTree Error: ${error}`) }) }); const getFullPath = (tree, path) => Effect.try({ try: () => { const result = []; function helper(nodes, pathParts) { if (pathParts.length === 0) return false; const [current, ...rest] = pathParts; for (const node of nodes) { if (node.name === current) { result.push(node.name); if (rest.length === 0 || helper(node.children, rest)) { return true; } result.pop(); } } return false; } helper(tree, path); return result; }, catch: (error) => new SDKCoreError({ type: "UNKNOWN", cause: new StudioCMS_SDK_Error(`getFullPath Error: ${error}`) }) }); const findNodeByPath = (tree, path) => Effect.try({ try: () => { function _findNodeByPath(tree2, path2) { if (path2.length === 0) return null; const [current, ...rest] = path2; for (const node of tree2) { if (node.name === current) { if (rest.length === 0) return node; return _findNodeByPath(node.children, rest); } } return null; } return _findNodeByPath(tree, path); }, catch: (error) => new SDKCoreError({ type: "UNKNOWN", cause: new StudioCMS_SDK_Error(`FindNodeByPath Error: ${error}`) }) }); const findNodesAlongPath = (tree, path) => Effect.try({ try: () => { const result = []; function helper(nodes, pathParts) { if (pathParts.length === 0) return false; const [current, ...rest] = pathParts; for (const node of nodes) { if (node.name === current) { result.push(node); if (rest.length === 0 || helper(node.children, rest)) { return true; } result.pop(); } } return false; } helper(tree, path); return result; }, catch: (error) => new SDKCoreError({ type: "UNKNOWN", cause: new StudioCMS_SDK_Error(`FindNodesAlongPath Error: ${error}`) }) }); const findNodesAlongPathToId = (tree, id) => Effect.try({ try: () => { const path = []; function helper(nodes, targetId) { for (const node of nodes) { path.push(node); if (node.id === targetId) { return true; } if (helper(node.children, targetId)) { return true; } path.pop(); } return false; } helper(tree, id); return path; }, catch: (error) => new SDKCoreError({ type: "UNKNOWN", cause: new StudioCMS_SDK_Error(`FindNodesAlongPathToId Error: ${error}`) }) }); const findNodeById = (tree, id) => Effect.try({ try: () => { function _findNodeById(tree2, id2) { for (const node of tree2) { if (node.id === id2) { return node; } const found = _findNodeById(node.children, id2); if (found) { return found; } } return null; } return _findNodeById(tree, id); }, catch: (error) => new SDKCoreError({ type: "UNKNOWN", cause: new StudioCMS_SDK_Error(`findNodeById Error: ${error}`) }) }); const addPageToFolderTree = (tree, folderId, newPage) => Effect.gen(function* () { const parentFolder = yield* findNodeById(tree, folderId); if (!parentFolder) { tree.push(newPage); return tree; } parentFolder.children.push(newPage); return tree; }); const buildFolderTree = Effect.gen(function* () { const currentFolders = yield* dbService.execute( (db) => db.select().from(tsPageFolderStructure) ); return yield* generateFolderTree(currentFolders); }); const getAvailableFolders = Effect.gen(function* () { const folders = []; const currentFolders = yield* dbService.execute( (db) => db.select().from(tsPageFolderStructure) ); for (const current of currentFolders) { folders.push(current); } return folders; }); return { generateFolderTree, getFullPath, findNodeByPath, findNodesAlongPath, findNodesAlongPathToId, findNodeById, addPageToFolderTree, buildFolderTree, getAvailableFolders }; }), dependencies: [AstroDB.Default] } ) { } export { SDKCore_FolderTree };