{"version":3,"sources":["../../src/storage/fileSystem.ts"],"names":["path","relative","fs"],"mappings":"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","file":"fileSystem.cjs","sourcesContent":["import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport type { StorageAdapter } from \"./index\";\n\n/**\n * @deprecated Use repository implementations via `StorageConfig` instead.\n */\nexport class FileSystemStorageAdapter implements StorageAdapter {\n    private readonly basePath: string;\n\n    constructor(dirPath: string) {\n        // Normalize and resolve the storage base path once\n        this.basePath = path.resolve(dirPath).replace(/[/\\\\]+$/, \"\");\n    }\n\n    private validateAndGetFilePath(key: string): string {\n        // Reject dangerous keys\n        if (key === \".\" || key === \"..\") {\n            throw new Error(\"Invalid key: '.' and '..' are not allowed\");\n        }\n\n        // Check for null bytes\n        if (key.includes(\"\\0\")) {\n            throw new Error(\"Invalid key: null bytes are not allowed\");\n        }\n\n        // Check for path traversal attempts before normalization\n        if (key.includes(\"..\")) {\n            throw new Error(\"Invalid key: directory traversal is not allowed\");\n        }\n\n        // Check for reserved Windows names (case-insensitive)\n        const reservedNames = /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;\n        const keyWithoutExt = key.split(\".\")[0];\n        if (reservedNames.test(keyWithoutExt)) {\n            throw new Error(`Invalid key: '${key}' uses a reserved Windows name`);\n        }\n\n        // Check for trailing spaces or dots\n        if (key.endsWith(\" \") || key.endsWith(\".\")) {\n            throw new Error(\"Invalid key: trailing spaces or dots are not allowed\");\n        }\n\n        // Normalize path separators and sanitize key\n        const normalizedKey = key.replace(/[/\\\\]/g, \"_\").replace(/[^a-zA-Z0-9._-]/g, \"_\");\n\n        // Resolve the full path and check for directory traversal\n        const resolved = path.resolve(this.basePath, normalizedKey);\n        const relative = path.relative(this.basePath, resolved);\n\n        // Reject if trying to escape the base directory\n        if (relative.startsWith(\"..\") || relative.includes(path.sep + \"..\")) {\n            throw new Error(\"Invalid key: directory traversal is not allowed\");\n        }\n\n        return resolved;\n    }\n\n    private async ensureDirectory(): Promise<void> {\n        try {\n            await fs.access(this.basePath);\n        } catch {\n            await fs.mkdir(this.basePath, { recursive: true });\n        }\n    }\n\n    async getItem(key: string): Promise<string | null> {\n        try {\n            const filePath = this.validateAndGetFilePath(key);\n            const data = await fs.readFile(filePath, \"utf-8\");\n            return data;\n        } catch (error: any) {\n            if (error.code === \"ENOENT\") {\n                return null;\n            }\n            console.error(`Failed to read file for key ${key}:`, error);\n            return null;\n        }\n    }\n\n    async setItem(key: string, value: string): Promise<void> {\n        try {\n            await this.ensureDirectory();\n            const filePath = this.validateAndGetFilePath(key);\n            await fs.writeFile(filePath, value, \"utf-8\");\n        } catch (error) {\n            console.error(`Failed to write file for key ${key}:`, error);\n            throw error;\n        }\n    }\n\n    async removeItem(key: string): Promise<void> {\n        try {\n            const filePath = this.validateAndGetFilePath(key);\n            await fs.unlink(filePath);\n        } catch (error: any) {\n            if (error.code !== \"ENOENT\") {\n                console.error(`Failed to remove file for key ${key}:`, error);\n            }\n        }\n    }\n\n    async clear(): Promise<void> {\n        try {\n            const entries = await fs.readdir(this.basePath);\n            await Promise.all(\n                entries.map(async (entry) => {\n                    const entryPath = path.join(this.basePath, entry);\n                    // Use fs.rm with recursive option to handle both files and directories\n                    await fs.rm(entryPath, { recursive: true, force: true });\n                }),\n            );\n        } catch (error) {\n            console.error(\"Failed to clear storage directory:\", error);\n        }\n    }\n}\n"]}