scriptable-testlab
Version:
A lightweight, efficient tool designed to manage and update scripts for Scriptable.
882 lines • 31 kB
JavaScript
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