UNPKG

scriptable-testlab

Version:

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

882 lines 31 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var filemanager_exports = {}; __export(filemanager_exports, { MockFileManager: () => MockFileManager }); module.exports = __toCommonJS(filemanager_exports); var fs = __toESM(require("fs")); var path = __toESM(require("path")); var import_scriptable_abstract = require("scriptable-abstract"); var import_errors = require("../../types/errors"); var import_file = require("../../types/file"); var import_paths = require("../../utils/paths"); var import_data = require("../data"); var import_media = require("../media"); const _MockFileManager = class _MockFileManager extends import_scriptable_abstract.AbsFileManager { constructor(type, options = {}) { super(); __publicField(this, "bookmarks", /* @__PURE__ */ new Map()); __publicField(this, "eventListeners", []); const rootPath = options.rootPath ?? import_paths.DEFAULT_ROOT_PATH; const normalizedRootPath = import_paths.FileUtils.normalizePath(rootPath); const baseDirectories = { ...import_paths.DEFAULT_BASE_DIRECTORIES }; Object.entries(options.baseDirectories ?? {}).forEach(([key, value]) => { if (typeof value === "string" && key in import_paths.DEFAULT_BASE_DIRECTORIES) { baseDirectories[key] = import_paths.FileUtils.joinPaths(normalizedRootPath, value); } }); this.setState({ store: {}, rootPath: normalizedRootPath, baseDirectories, type: type === import_paths.FileManagerType.LOCAL ? "local" : "icloud", fileSystem: { type: "directory", children: /* @__PURE__ */ new Map(), metadata: { creationDate: /* @__PURE__ */ new Date(), modificationDate: /* @__PURE__ */ new Date(), size: 0 } } }); } /** * @inheritdoc * Gets or creates a local file manager instance */ static local() { if (!this.localInstance) { this.localInstance = _MockFileManager.create(import_paths.FileManagerType.LOCAL, { rootPath: path.join(import_paths.DEFAULT_ROOT_PATH, "local") }); } return this.localInstance; } /** * @inheritdoc * Gets or creates an iCloud file manager instance */ static iCloud() { if (!this.iCloudInstance) { this.iCloudInstance = _MockFileManager.create(import_paths.FileManagerType.ICLOUD, { rootPath: path.join(import_paths.DEFAULT_ROOT_PATH, "icloud") }); } return this.iCloudInstance; } /** * @additional * Creates a new file manager instance */ static create(type, options = {}) { const instance = new _MockFileManager(type, options); instance.initializeBaseDirectories(); return instance; } /** * @additional * Resets both local and iCloud instances */ static reset(options = {}) { if (this.localInstance) { this.localInstance.resetInstance(options); } if (this.iCloudInstance) { this.iCloudInstance.resetInstance(options); } if (!options.preserveInstances) { this.localInstance = null; this.iCloudInstance = null; } } /** * @additional * Reset this instance */ resetInstance(options = {}) { if (!options.preserveBookmarks) { this.bookmarks.clear(); } const baseDirectories = options.preserveBaseDirectories ? this.state.baseDirectories : { ...import_paths.DEFAULT_BASE_DIRECTORIES }; this.setState({ store: {}, rootPath: this.state.rootPath, baseDirectories, type: this.state.type, fileSystem: { type: "directory", children: /* @__PURE__ */ new Map(), metadata: { creationDate: /* @__PURE__ */ new Date(), modificationDate: /* @__PURE__ */ new Date(), size: 0 } } }); if (!options.preserveBaseDirectories) { this.initializeBaseDirectories(); } } // Core file operations /** * @inheritdoc * Read data from a file * @throws {FileManagerError} If file does not exist or is a directory */ read(filePath) { try { const content = this.readString(filePath); return import_data.MockData.fromString(content); } catch (error) { throw this.wrapError(error, import_errors.FILE_MANAGER_ERROR_CODES.IO_ERROR, filePath); } } /** * @inheritdoc * Write data to a file * @throws {FileManagerError} If parent directory does not exist */ write(filePath, content) { try { this.writeString(filePath, content.toRawString()); } catch (error) { throw this.wrapError(error, import_errors.FILE_MANAGER_ERROR_CODES.IO_ERROR, filePath); } } /** * @inheritdoc * Read string content from a file * @throws {FileManagerError} If file does not exist or is a directory */ readString(filePath) { const normalizedPath = this.resolvePath(filePath); const node = this.getNode(normalizedPath); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, filePath ); } if (node.type !== "file") { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_FILE], import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_FILE, filePath ); } return node.content; } /** * @inheritdoc * Write string content to a file * @throws {FileManagerError} If parent directory does not exist */ writeString(filePath, content) { const normalizedPath = this.resolvePath(filePath); const parentDir = this.ensureParentDirectory(normalizedPath); const fileName = path.basename(normalizedPath); const now = /* @__PURE__ */ new Date(); const fileNode = { type: "file", content, metadata: { creationDate: now, modificationDate: now, size: content.length, isInCloud: this.state.type === "icloud", isDownloaded: this.state.type === "local" } }; const existingNode = parentDir.children.get(fileName); if (existingNode?.type === "file") { parentDir.metadata.size -= existingNode.metadata.size; } parentDir.children.set(fileName, fileNode); parentDir.metadata.modificationDate = now; parentDir.metadata.size += content.length; this.emitEvent({ type: existingNode ? "modify" : "create", path: normalizedPath, timestamp: now, metadata: fileNode.metadata }); } // Image operations /** * @inheritdoc * Read image from a file * @throws {FileManagerError} If file does not exist or is a directory */ readImage(filePath) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, filePath ); } if (!(0, import_file.isFileNode)(node)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_FILE], import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_FILE, filePath ); } return new import_media.MockImage(); } /** * @inheritdoc * Write image to a file * @throws {FileManagerError} If parent directory does not exist */ writeImage(filePath, _image) { this.write(filePath, new import_data.MockData()); } // File system operations /** * @inheritdoc * Remove a file or directory * @throws {FileManagerError} If path does not exist */ remove(filePath) { const normalizedPath = this.resolvePath(filePath); const parentPath = path.dirname(normalizedPath); const fileName = path.basename(normalizedPath); const parentNode = this.getNode(parentPath); if (!parentNode || !(0, import_file.isDirectoryNode)(parentNode)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, parentPath ); } const node = parentNode.children.get(fileName); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, filePath ); } if ((0, import_file.isDirectoryNode)(node)) { for (const childName of node.children.keys()) { this.remove(path.join(normalizedPath, childName)); } } parentNode.children.delete(fileName); parentNode.metadata.modificationDate = /* @__PURE__ */ new Date(); if ((0, import_file.isFileNode)(node)) { parentNode.metadata.size -= node.metadata.size; } this.emitEvent({ type: "delete", path: normalizedPath, timestamp: /* @__PURE__ */ new Date(), metadata: node.metadata }); } fileExists(filePath) { return this.getNode(this.resolvePath(filePath)) !== void 0; } isDirectory(filePath) { const node = this.getNode(this.resolvePath(filePath)); return node?.type === "directory"; } /** * @inheritdoc * Create a directory * @throws {FileManagerError} If parent directory does not exist and createParents is false */ createDirectory(dirPath, createParents = false) { const normalizedPath = this.resolvePath(dirPath); const rootPath = import_paths.FileUtils.normalizePath(this.state.rootPath); if (normalizedPath === rootPath) { return; } const parentPath = path.dirname(normalizedPath); const parentExists = this.fileExists(parentPath); if (!parentExists && !createParents) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.PARENT_DIRECTORY_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.PARENT_DIRECTORY_NOT_FOUND, parentPath ); } if (!parentExists && createParents) { this.createDirectory(parentPath, true); } const parentNode = this.getNode(parentPath); if (!parentNode || !(0, import_file.isDirectoryNode)(parentNode)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY], import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY, parentPath ); } const dirName = path.basename(normalizedPath); const existingNode = parentNode.children.get(dirName); if (existingNode && !(0, import_file.isDirectoryNode)(existingNode)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY], import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY, normalizedPath ); } if (existingNode) { return; } const now = /* @__PURE__ */ new Date(); const newNode = { type: "directory", children: /* @__PURE__ */ new Map(), metadata: { creationDate: now, modificationDate: now, size: 0, isInCloud: this.state.type === "icloud", isDownloaded: this.state.type === "local" } }; parentNode.children.set(dirName, newNode); parentNode.metadata.modificationDate = now; this.emitEvent({ type: "create", path: normalizedPath, timestamp: now, metadata: newNode.metadata }); } /** * @inheritdoc * List contents of a directory * @throws {FileManagerError} If directory does not exist */ listContents(directoryPath) { const node = this.getNode(this.resolvePath(directoryPath)); if (!node || !(0, import_file.isDirectoryNode)(node)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY], import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY, directoryPath ); } return Array.from(node.children.keys()); } // Directory paths documentsDirectory() { return this.state.baseDirectories.documents; } libraryDirectory() { return this.state.baseDirectories.library; } cacheDirectory() { return this.state.baseDirectories.cache; } temporaryDirectory() { return this.state.baseDirectories.temporary; } // Path operations joinPath(lhs, rhs) { return import_paths.FileUtils.joinPaths(lhs, rhs); } // File operations /** * @inheritdoc * Move a file or directory * @throws {FileManagerError} If source or destination parent directory does not exist */ move(sourceFile, destinationFile) { const normalizedSourcePath = this.resolvePath(sourceFile); const normalizedDestPath = this.resolvePath(destinationFile); const sourceParentPath = path.dirname(normalizedSourcePath); const sourceFileName = path.basename(normalizedSourcePath); const destParentPath = path.dirname(normalizedDestPath); const destFileName = path.basename(normalizedDestPath); const sourceParentNode = this.getNode(sourceParentPath); if (!sourceParentNode || !(0, import_file.isDirectoryNode)(sourceParentNode)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, sourceParentPath ); } const sourceNode = sourceParentNode.children.get(sourceFileName); if (!sourceNode) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, sourceFile ); } const destParentNode = this.getNode(destParentPath); if (!destParentNode || !(0, import_file.isDirectoryNode)(destParentNode)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, destParentPath ); } sourceParentNode.children.delete(sourceFileName); destParentNode.children.set(destFileName, sourceNode); const now = /* @__PURE__ */ new Date(); sourceParentNode.metadata.modificationDate = now; destParentNode.metadata.modificationDate = now; if ((0, import_file.isFileNode)(sourceNode)) { sourceParentNode.metadata.size -= sourceNode.metadata.size; destParentNode.metadata.size += sourceNode.metadata.size; } } /** * @inheritdoc * Copy a file or directory * @throws {FileManagerError} If source file does not exist or destination parent directory does not exist */ copy(sourceFile, destinationFile) { const normalizedSourcePath = this.resolvePath(sourceFile); const normalizedDestPath = this.resolvePath(destinationFile); const sourceNode = this.getNode(normalizedSourcePath); if (!sourceNode) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, sourceFile ); } const clonedNode = (0, import_file.isDirectoryNode)(sourceNode) ? { type: "directory", children: new Map(sourceNode.children), metadata: { ...sourceNode.metadata, creationDate: /* @__PURE__ */ new Date(), modificationDate: /* @__PURE__ */ new Date() } } : { type: "file", content: sourceNode.content, metadata: { ...sourceNode.metadata, creationDate: /* @__PURE__ */ new Date(), modificationDate: /* @__PURE__ */ new Date() } }; this.createNode(normalizedDestPath, clonedNode); } // Bookmark operations bookmarkedPath(name) { const bookmark = this.bookmarks.get(name); if (!bookmark) { throw new Error("Bookmark not found"); } return bookmark.path; } bookmarkExists(name) { return this.bookmarks.has(name); } createBookmark(name, path2) { this.bookmarks.set(name, { path: path2, source: this.state.type === "local" ? "local" : "icloud" }); } removeBookmark(name) { this.bookmarks.delete(name); } allFileBookmarks() { return Array.from(this.bookmarks.entries()).map(([name, data]) => ({ name, path: data.path, source: data.source })); } // Cloud operations downloadFileFromiCloud(filePath) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new Error("File not found"); } node.metadata.isDownloaded = true; return Promise.resolve(); } isFileDownloaded(filePath) { const node = this.getNode(filePath); return node?.metadata.isDownloaded ?? false; } isFileStoredIniCloud(filePath) { const node = this.getNode(this.resolvePath(filePath)); return node?.metadata.isInCloud ?? false; } // Metadata operations modificationDate(filePath) { const node = this.getNode(filePath); if (!node) { throw new Error("File not found"); } return node.metadata.modificationDate; } creationDate(filePath) { const node = this.getNode(filePath); if (!node) { throw new Error("File not found"); } return node.metadata.creationDate; } fileSize(filePath) { const node = this.getNode(filePath); if (!node) { throw new Error("File not found"); } return node.metadata.size; } // File information fileName(filePath, includeFileExtension = true) { const name = import_paths.FileUtils.getFileName(filePath); if (!includeFileExtension) { const extIndex = name.lastIndexOf("."); return extIndex > 0 ? name.substring(0, extIndex) : name; } return name; } fileExtension(filePath) { return import_paths.FileUtils.getFileExtension(filePath).slice(1); } getUTI(filePath) { const extension = this.fileExtension(filePath); return import_paths.FileUtils.getUTI(extension); } // Extended Attributes operations writeExtendedAttribute(filePath, attributeName, value) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND, filePath ); } if (!node.metadata.extendedAttributes) { node.metadata.extendedAttributes = /* @__PURE__ */ new Map(); } node.metadata.extendedAttributes.set(attributeName, value); } readExtendedAttribute(filePath, attributeName) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND, filePath ); } const value = node.metadata.extendedAttributes?.get(attributeName); if (value === void 0) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.EXTENDED_ATTRIBUTE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.EXTENDED_ATTRIBUTE_NOT_FOUND ); } return value; } allExtendedAttributes(filePath) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND, filePath ); } return Array.from(node.metadata.extendedAttributes?.keys() ?? []); } removeExtendedAttribute(filePath, attributeName) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND, filePath ); } if (!node.metadata.extendedAttributes?.delete(attributeName)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.EXTENDED_ATTRIBUTE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.EXTENDED_ATTRIBUTE_NOT_FOUND ); } } // Tags operations addTag(filePath, tag) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND, filePath ); } if (!node.metadata.tags) { node.metadata.tags = /* @__PURE__ */ new Set(); } node.metadata.tags.add(tag); } removeTag(filePath, tag) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND, filePath ); } if (!node.metadata.tags?.delete(tag)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.TAG_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.TAG_NOT_FOUND ); } } allTags(filePath) { const node = this.getNode(this.resolvePath(filePath)); if (!node) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.FILE_NOT_FOUND, filePath ); } return Array.from(node.metadata.tags ?? []); } // Event handling /** * @additional * Add a file system event listener */ addEventListener(listener) { this.eventListeners.push(listener); } /** * @additional * Remove a file system event listener */ removeEventListener(listener) { const index = this.eventListeners.indexOf(listener); if (index !== -1) { this.eventListeners.splice(index, 1); } } /** * @additional * Emit a file system event */ emitEvent(event) { this.eventListeners.forEach((listener) => listener(event)); } // Error handling /** * @additional * Wrap an error in a FileManagerError */ wrapError(error, code, path2) { if (error instanceof import_errors.FileManagerError) { return error; } const message = import_errors.FILE_MANAGER_ERROR_MESSAGES[code]; return new import_errors.FileManagerError(message, code, path2, error instanceof Error ? error : void 0); } // Private helper methods /** * @additional * Initialize base directories */ initializeBaseDirectories() { if (!fs.existsSync(this.state.rootPath)) { fs.mkdirSync(this.state.rootPath, { recursive: true }); } Object.values(this.state.baseDirectories).forEach((dirPath) => { const normalizedPath = import_paths.FileUtils.normalizePath(dirPath); if (!fs.existsSync(normalizedPath)) { fs.mkdirSync(normalizedPath, { recursive: true }); } const parts = normalizedPath.split("/").filter(Boolean); let current = this.state.fileSystem; for (const part of parts) { if (!current.children.has(part)) { const newNode = { type: "directory", children: /* @__PURE__ */ new Map(), metadata: { creationDate: /* @__PURE__ */ new Date(), modificationDate: /* @__PURE__ */ new Date(), size: 0 } }; current.children.set(part, newNode); } const nextNode = current.children.get(part); if (!nextNode || !(0, import_file.isDirectoryNode)(nextNode)) { throw new Error(`Path component ${part} exists but is not a directory`); } current = nextNode; } }); } /** * @additional * Resolve a path to its normalized form */ resolvePath(filePath) { const normalizedPath = import_paths.FileUtils.normalizePath(filePath); const rootPath = import_paths.FileUtils.normalizePath(this.state.rootPath); if (normalizedPath === rootPath) { return rootPath; } if (path.isAbsolute(normalizedPath)) { const isBaseDir = Object.values(this.state.baseDirectories).some( (dir) => import_paths.FileUtils.normalizePath(dir) === normalizedPath ); if (isBaseDir) { return normalizedPath; } const relativePath = path.relative(rootPath, normalizedPath); if (relativePath.startsWith("..")) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.OUTSIDE_ROOT], import_errors.FILE_MANAGER_ERROR_CODES.OUTSIDE_ROOT ); } if (normalizedPath.startsWith(rootPath)) { const relPath = path.relative(rootPath, normalizedPath); return path.join(rootPath, relPath).replace(/\\/g, "/"); } return normalizedPath; } const resolvedPath = path.join(rootPath, normalizedPath); return import_paths.FileUtils.normalizePath(resolvedPath); } /** * @additional * Get a node from the file system */ getNode(filePath) { const normalizedPath = import_paths.FileUtils.normalizePath(filePath); const rootPath = import_paths.FileUtils.normalizePath(this.state.rootPath); if (normalizedPath === rootPath) { return this.state.fileSystem; } let relativePath; if (normalizedPath.startsWith(rootPath)) { relativePath = path.relative(rootPath, normalizedPath); } else { relativePath = path.relative(rootPath, path.resolve(rootPath, normalizedPath)); } const parts = relativePath.split(/[/\\]/).filter(Boolean); let current = this.state.fileSystem; for (const part of parts) { const next = current.children.get(part); if (!next) return void 0; if (part !== parts[parts.length - 1] && !(0, import_file.isDirectoryNode)(next)) { return void 0; } if ((0, import_file.isDirectoryNode)(next)) { current = next; } else { return next; } } return current; } /** * @additional * Ensure a parent directory exists */ ensureParentDirectory(filePath) { const normalizedPath = this.resolvePath(filePath); const parentPath = path.dirname(normalizedPath); if (!this.fileExists(parentPath)) { this.createDirectory(parentPath, true); } const node = this.getNode(parentPath); if (!node || !(0, import_file.isDirectoryNode)(node)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY], import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY, parentPath ); } return node; } createNode(filePath, node, createParents = true) { const normalizedPath = this.resolvePath(filePath); const parentPath = path.dirname(normalizedPath); const fileName = path.basename(normalizedPath); if (parentPath !== this.state.rootPath && !this.fileExists(parentPath)) { if (createParents) { this.createDirectory(parentPath, true); } else { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND], import_errors.FILE_MANAGER_ERROR_CODES.NOT_FOUND, parentPath ); } } const parentNode = this.getNode(parentPath); if (!parentNode || !(0, import_file.isDirectoryNode)(parentNode)) { throw new import_errors.FileManagerError( import_errors.FILE_MANAGER_ERROR_MESSAGES[import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY], import_errors.FILE_MANAGER_ERROR_CODES.NOT_A_DIRECTORY, parentPath ); } if (this.state.type === "icloud") { node.metadata = { ...node.metadata, isInCloud: true, isDownloaded: false }; } parentNode.children.set(fileName, node); parentNode.metadata.modificationDate = /* @__PURE__ */ new Date(); if ((0, import_file.isFileNode)(node)) { parentNode.metadata.size += node.metadata.size; } } }; __publicField(_MockFileManager, "localInstance", null); __publicField(_MockFileManager, "iCloudInstance", null); let MockFileManager = _MockFileManager; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { MockFileManager }); //# sourceMappingURL=filemanager.js.map