UNPKG

@finos/legend-application-studio

Version:
219 lines 8.6 kB
/** * Copyright (c) 2020-present, Goldman Sachs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { isNonNullable, returnUndefOnError, addUniqueEntry, } from '@finos/legend-shared'; import { DIRECTORY_PATH_DELIMITER, } from '@finos/legend-graph'; export const GENERATION_FILE_ROOT_NAME = 'GENERATION_FILE_ROOT'; class FileSystemElement { name; directory; parentId; constructor(name, fileGenerationParent) { this.name = name; this.parentId = fileGenerationParent; } get path() { if (!this.directory) { return this.name; } const parentDirectoryName = this.directory.getDirectoryPath(); return !parentDirectoryName ? this.name : `${parentDirectoryName}${DIRECTORY_PATH_DELIMITER}${this.name}`; } } export class FileSystem_Directory extends FileSystemElement { children = []; setDirectory(val) { this.directory = val; } addChild(val) { addUniqueEntry(this.children, val); } addElement(val) { this.addChild(val); val.directory = this; } static createDirectoryFromParent(name, parent, genParent) { const newDirectory = new FileSystem_Directory(name, genParent); newDirectory.setDirectory(parent); return newDirectory; } static getOrCreateDirectory(parent, directoryName, insert) { const index = directoryName.indexOf(DIRECTORY_PATH_DELIMITER); const str = index === -1 ? directoryName : directoryName.substring(0, index); let node; node = parent.children.find((child) => child instanceof FileSystem_Directory && child.name === str); if (!node) { if (!insert) { throw new Error(`Can't find file node '${str}' in directory '${directoryName}'`); } // create the node if it is not in parent directory node = FileSystem_Directory.createDirectoryFromParent(str, parent); parent.addChild(node); } if (index !== -1) { return FileSystem_Directory.getOrCreateDirectory(node, directoryName.substring(index + DIRECTORY_PATH_DELIMITER.length), insert); } return node; } getDirectoryPath() { if (!this.directory) { return ''; } const parentDirectoryName = this.directory.getDirectoryPath(); return !parentDirectoryName ? this.name : `${parentDirectoryName}${DIRECTORY_PATH_DELIMITER}${this.name}`; } } export class FileSystem_File extends FileSystemElement { content; format; constructor(name, content, format, parentId) { super(name, parentId); this.content = content; this.format = format; } } export const getFileSystemTreeNodeData = (fileNode) => ({ id: fileNode.path, label: fileNode.name, childrenIds: fileNode instanceof FileSystem_Directory ? fileNode.children.map((child) => child.path) : undefined, fileNode: fileNode, }); export const populateDirectoryTreeNodeChildren = (node, treeData) => { if (node.childrenIds && node.fileNode instanceof FileSystem_Directory) { node.childrenIds = node.fileNode.children.map((child) => child.path); node.fileNode.children .map((child) => getFileSystemTreeNodeData(child)) .forEach((childNode) => { const currentNode = treeData.nodes.get(childNode.id); if (currentNode) { currentNode.childrenIds = childNode.childrenIds; currentNode.label = childNode.label; } else { treeData.nodes.set(childNode.id, childNode); } }); } }; export const getFileSystemTreeData = (dir, rootWrapperName) => { const rootIds = []; const nodes = new Map(); if (rootWrapperName) { const rootNode = getFileSystemTreeNodeData(dir); rootNode.label = rootWrapperName; addUniqueEntry(rootIds, rootNode.id); nodes.set(rootNode.id, rootNode); } else { dir.children .toSorted((a, b) => a.name.localeCompare(b.name)) .sort((a, b) => (b instanceof FileSystem_Directory ? 1 : 0) - (a instanceof FileSystem_Directory ? 1 : 0)) .forEach((childDirectory) => { const childTreeNodeData = getFileSystemTreeNodeData(childDirectory); addUniqueEntry(rootIds, childTreeNodeData.id); nodes.set(childTreeNodeData.id, childTreeNodeData); }); } return { rootIds, nodes }; }; export const addNode = (element, treeData, showRoot) => { const newNode = getFileSystemTreeNodeData(element); treeData.nodes.set(newNode.id, newNode); if (!element.directory || (element.directory.path === GENERATION_FILE_ROOT_NAME && !showRoot)) { treeData.rootIds = Array.from(new Set(treeData.rootIds).add(newNode.id)); } else { const parentNode = treeData.nodes.get(element.directory.path); if (parentNode) { parentNode.childrenIds = parentNode.childrenIds ? Array.from(new Set(parentNode.childrenIds).add(newNode.id)) : [newNode.id]; } } return newNode; }; export const openNode = (element, treeData, showRoot) => { let currentElement = element; let openingNode; while (currentElement.directory) { const node = treeData.nodes.get(currentElement.path) ?? addNode(currentElement, treeData, showRoot); node.isOpen = currentElement instanceof FileSystem_Directory; openingNode = !openingNode ? node : openingNode; currentElement = currentElement.directory; } return openingNode; }; export const getFileSystemChildNodes = (node, treeData) => { if (node.childrenIds && node.fileNode instanceof FileSystem_Directory) { populateDirectoryTreeNodeChildren(node, treeData); return node.childrenIds .map((id) => treeData.nodes.get(id)) .filter(isNonNullable) .sort((a, b) => a.label.localeCompare(b.label)) .sort((a, b) => (b.fileNode instanceof FileSystem_Directory ? 1 : 0) - (a.fileNode instanceof FileSystem_Directory ? 1 : 0)); } return []; }; export const buildFileSystemDirectory = (rootDirectory, filesResultIndex, filesIndex) => { Array.from(filesResultIndex.values()).forEach((fileResult) => { const resultValue = fileResult.value; const filePath = resultValue.fileName; const index = filePath.lastIndexOf(DIRECTORY_PATH_DELIMITER); const fileName = index === -1 ? filePath : filePath.substring(index + DIRECTORY_PATH_DELIMITER.length, filePath.length); const directoryName = index === -1 ? undefined : filePath.substring(0, index); let directory = rootDirectory; if (directoryName) { directory = FileSystem_Directory.getOrCreateDirectory(rootDirectory, directoryName, true); } const file = new FileSystem_File(fileName, resultValue.content, fileResult.value.format, fileResult.parentId); directory.addElement(file); filesIndex.set(filePath, file); }); }; const openNodeById = (id, treeData) => { if (treeData) { const node = treeData.nodes.get(id); if (node) { node.isOpen = true; } } }; export const reprocessOpenNodes = (treeData, filesIndex, rootDirectory, openedNodeIds, showRoot) => { const openNodeElement = (elementPath) => { const element = filesIndex.get(elementPath) ?? returnUndefOnError(() => FileSystem_Directory.getOrCreateDirectory(rootDirectory, elementPath, false)); if (element) { return openNode(element, treeData, showRoot); } return undefined; }; openedNodeIds.forEach(openNodeElement); if (openedNodeIds.includes(rootDirectory.path)) { openNodeById(rootDirectory.path, treeData); } }; //# sourceMappingURL=FileSystemTreeUtils.js.map