studiocms
Version:
Astro Native CMS for AstroDB. Built from the ground up by the Astro community.
201 lines (200 loc) • 6.44 kB
JavaScript
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
};