UNPKG

scriptable-testlab

Version:

A lightweight, efficient tool designed to manage and update scripts for Scriptable.

107 lines (92 loc) 2.81 kB
import path from 'path'; import {ERROR_MESSAGES, FileManagerError} from '../types/errors'; import {FileSystemNode} from '../types/file'; /** * Validates if a file path is valid and within the root directory */ export function validatePath(filePath: string, rootPath: string): void { if (!filePath || typeof filePath !== 'string') { throw new FileManagerError(ERROR_MESSAGES.INVALID_PATH, 'INVALID_PATH', filePath); } const normalizedPath = path.normalize(filePath).replace(/\\/g, '/'); const normalizedRoot = path.normalize(rootPath).replace(/\\/g, '/'); if (!normalizedPath.startsWith(normalizedRoot)) { throw new FileManagerError(ERROR_MESSAGES.OUTSIDE_ROOT, 'INVALID_PATH', filePath); } } /** * Validates if a node exists and is of the expected type */ export function validateNode( node: FileSystemNode | undefined, expectedType: 'file' | 'directory', path: string, ): asserts node is FileSystemNode { if (!node) { throw new FileManagerError( expectedType === 'file' ? ERROR_MESSAGES.FILE_NOT_FOUND : ERROR_MESSAGES.DIRECTORY_NOT_FOUND, 'NOT_FOUND', path, ); } if (node.type !== expectedType) { throw new FileManagerError( expectedType === 'file' ? ERROR_MESSAGES.NOT_A_FILE : ERROR_MESSAGES.NOT_A_DIRECTORY, 'INVALID_PATH', path, ); } } /** * Creates a deep clone of a file system node */ export function cloneNode(node: FileSystemNode): FileSystemNode { const clonedMetadata = { ...node.metadata, creationDate: new Date(node.metadata.creationDate), modificationDate: new Date(node.metadata.modificationDate), tags: node.metadata.tags ? new Set(node.metadata.tags) : undefined, extendedAttributes: node.metadata.extendedAttributes ? new Map(node.metadata.extendedAttributes) : undefined, }; if (node.type === 'file') { return { type: 'file', content: node.content, metadata: clonedMetadata, }; } return { type: 'directory', children: new Map(node.children), metadata: clonedMetadata, }; } /** * Calculates the total size of a directory */ export function calculateDirectorySize(dir: FileSystemNode): number { if (dir.type !== 'directory') { return 0; } let totalSize = 0; for (const child of dir.children?.values() ?? []) { if (child.type === 'file') { totalSize += child.metadata.size; } else { totalSize += calculateDirectorySize(child); } } return totalSize; } export type FileSystemUtils = { validatePath: typeof validatePath; validateNode: typeof validateNode; cloneNode: typeof cloneNode; calculateDirectorySize: typeof calculateDirectorySize; }; export const FileSystemUtils: FileSystemUtils = { validatePath, validateNode, cloneNode, calculateDirectorySize, };