{"version":3,"file":"index6.cjs","sources":["../src/storage/storage.ts"],"sourcesContent":["/**\n * Context Storage\n * \n * Handles loading and saving entity YAML files from context directories.\n * Supports hierarchical loading where later directories override earlier ones.\n * \n * Design Note: This module is designed to be self-contained and may be\n * extracted for use in other tools (kronologi, observasjon) in the future.\n */\n\nimport * as yaml from 'js-yaml';\nimport * as fs from 'fs/promises';\n// eslint-disable-next-line no-restricted-imports\nimport { existsSync, statSync, readdirSync } from 'fs';\nimport * as path from 'node:path';\nimport { RedaksjonEntity as Entity, RedaksjonEntityType as EntityType } from '../types';\n\nexport interface StorageInstance {\n  load(contextDirs: string[]): Promise<void>;\n  save(entity: Entity, targetDir: string): Promise<void>;\n  delete(type: EntityType, id: string, targetDir: string): Promise<boolean>;\n  get<T extends Entity>(type: EntityType, id: string): T | undefined;\n  getAll<T extends Entity>(type: EntityType): T[];\n  search(query: string): Entity[];\n  findBySoundsLike(phonetic: string): Entity | undefined;\n  clear(): void;\n  getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined;\n}\n\ntype DirectoryName = 'people' | 'projects' | 'companies' | 'terms' | 'ignored';\n\nconst DIRECTORY_TO_TYPE: Record<DirectoryName, EntityType> = {\n    'people': 'person',\n    'projects': 'project',\n    'companies': 'company',\n    'terms': 'term',\n    'ignored': 'ignored',\n};\n\nconst TYPE_TO_DIRECTORY: Record<EntityType, DirectoryName> = {\n    'person': 'people',\n    'project': 'projects',\n    'company': 'companies',\n    'term': 'terms',\n    'ignored': 'ignored',\n};\n\n/**\n * Simple slugify function for generating slugs from names\n */\nfunction slugify(text: string): string {\n    return text\n        .toLowerCase()\n        .trim()\n        .replace(/[^\\w\\s-]/g, '')\n        .replace(/[\\s_-]+/g, '-')\n        .replace(/^-+|-+$/g, '');\n}\n\nexport const create = (): StorageInstance => {\n    const entities: Map<EntityType, Map<string, Entity>> = new Map([\n        ['person', new Map()],\n        ['project', new Map()],\n        ['company', new Map()],\n        ['term', new Map()],\n        ['ignored', new Map()],\n    ]);\n\n    const load = async (contextDirs: string[]): Promise<void> => {\n    // Load from all context directories (later directories override)\n        for (const contextDir of contextDirs) {\n            for (const dirName of Object.keys(DIRECTORY_TO_TYPE) as DirectoryName[]) {\n                const typeDir = path.join(contextDir, dirName);\n                const entityType = DIRECTORY_TO_TYPE[dirName];\n        \n                try {\n                    const files = await fs.readdir(typeDir);\n                    for (const file of files) {\n                        if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;\n            \n                        const content = await fs.readFile(path.join(typeDir, file), 'utf-8');\n                        const parsed = yaml.load(content) as Partial<Entity>;\n            \n                        if (parsed && parsed.id) {\n                            entities.get(entityType)?.set(parsed.id, {\n                                ...parsed,\n                                type: entityType,\n                            } as Entity);\n                        }\n                    }\n                } catch {\n                    // Directory doesn't exist, skip\n                }\n            }\n        }\n    };\n\n    const save = async (entity: Entity, targetDir: string): Promise<void> => {\n        const dirName = TYPE_TO_DIRECTORY[entity.type];\n        // Save to context subdirectory (context/people/, context/projects/, etc.)\n        const dirPath = path.join(targetDir, 'context', dirName);\n        await fs.mkdir(dirPath, { recursive: true });\n    \n        // Generate filename: {uuid-prefix}-{slug}.yaml\n        const entityWithSlug = entity as Entity & { slug?: string };\n        const uuidPrefix = entity.id.substring(0, 10);\n        const slug = entityWithSlug.slug || slugify(entity.name);\n        const filename = `${uuidPrefix}-${slug}.yaml`;\n        const filePath = path.join(dirPath, filename);\n    \n        // Remove type from saved YAML (it's inferred from directory)\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        const { type: _entityType, ...entityWithoutType } = entity;\n        const content = yaml.dump(entityWithoutType, { lineWidth: -1, noRefs: true });\n        await fs.writeFile(filePath, content, 'utf-8');\n    \n        entities.get(entity.type)?.set(entity.id, entity);\n    };\n\n    const deleteEntity = async (type: EntityType, id: string, targetDir: string): Promise<boolean> => {\n        const dirName = TYPE_TO_DIRECTORY[type];\n        \n        // Resolve ID to UUID if it's a slug\n        const resolvedId = resolveEntityId(type, id);\n        if (!resolvedId) return false;\n        \n        // Try to find file with UUID prefix\n        const uuidPrefix = resolvedId.substring(0, 10);\n        const possibleDirs = [\n            path.join(targetDir, dirName),\n            path.join(targetDir, 'context', dirName),\n        ];\n        \n        for (const dir of possibleDirs) {\n            try {\n                const files = await fs.readdir(dir);\n                for (const file of files) {\n                    if (file.startsWith(uuidPrefix) && (file.endsWith('.yaml') || file.endsWith('.yml'))) {\n                        await fs.unlink(path.join(dir, file));\n                        entities.get(type)?.delete(resolvedId);\n                        return true;\n                    }\n                }\n            } catch {\n                // Directory doesn't exist or can't be read, try next\n            }\n        }\n        \n        // Fallback: try legacy slug-based filenames\n        const possiblePaths = [\n            path.join(targetDir, dirName, `${resolvedId}.yaml`),\n            path.join(targetDir, dirName, `${resolvedId}.yml`),\n            path.join(targetDir, 'context', dirName, `${resolvedId}.yaml`),\n            path.join(targetDir, 'context', dirName, `${resolvedId}.yml`),\n        ];\n        \n        for (const filePath of possiblePaths) {\n            try {\n                await fs.unlink(filePath);\n                entities.get(type)?.delete(resolvedId);\n                return true;\n            } catch {\n                // File doesn't exist at this path, try next\n            }\n        }\n        \n        return false;\n    };\n\n    const getEntityFilePath = (type: EntityType, id: string, contextDirs: string[]): string | undefined => {\n        const dirName = TYPE_TO_DIRECTORY[type];\n        \n        // Resolve ID to UUID if it's a slug\n        const resolvedId = resolveEntityId(type, id);\n        if (!resolvedId) return undefined;\n        \n        // Search in reverse order (closest first) to find where the entity is defined\n        for (const contextDir of [...contextDirs].reverse()) {\n            const typeDir = path.join(contextDir, dirName);\n            \n            // Check if directory exists\n            if (!existsSync(typeDir)) continue;\n            \n            try {\n                // List all files in directory and find matching UUID prefix\n                const files = readdirSync(typeDir);\n                const uuidPrefix = resolvedId.substring(0, 10);\n                \n                for (const file of files) {\n                    if (file.startsWith(uuidPrefix) && (file.endsWith('.yaml') || file.endsWith('.yml'))) {\n                        const filePath = path.join(typeDir, file);\n                        const stat = statSync(filePath);\n                        if (stat.isFile()) {\n                            return filePath;\n                        }\n                    }\n                }\n            } catch {\n                // Directory read failed, continue\n            }\n            \n            // Fallback: try legacy slug-based filenames\n            const possiblePaths = [\n                path.join(contextDir, dirName, `${resolvedId}.yaml`),\n                path.join(contextDir, dirName, `${resolvedId}.yml`),\n            ];\n            \n            for (const filePath of possiblePaths) {\n                if (existsSync(filePath)) {\n                    const stat = statSync(filePath);\n                    if (stat.isFile()) {\n                        return filePath;\n                    }\n                }\n            }\n        }\n        \n        return undefined;\n    };\n\n    /**\n     * Resolve entity ID from UUID or slug\n     * Tries UUID first, then slug lookup\n     */\n    const resolveEntityId = (type: EntityType, identifier: string): string | undefined => {\n        // Try direct UUID lookup first\n        if (entities.get(type)?.has(identifier)) {\n            return identifier;\n        }\n        \n        // Try slug lookup\n        const entityMap = entities.get(type);\n        if (entityMap) {\n            for (const entity of entityMap.values()) {\n                const entityWithSlug = entity as Entity & { slug?: string };\n                if (entityWithSlug.slug === identifier) {\n                    return entity.id;\n                }\n            }\n        }\n        \n        return undefined;\n    };\n\n    const get = <T extends Entity>(type: EntityType, id: string): T | undefined => {\n        // Support both UUID and slug lookup\n        const resolvedId = resolveEntityId(type, id);\n        return resolvedId ? entities.get(type)?.get(resolvedId) as T | undefined : undefined;\n    };\n\n    const getAll = <T extends Entity>(type: EntityType): T[] => {\n        return Array.from(entities.get(type)?.values() ?? []) as T[];\n    };\n\n    const search = (query: string): Entity[] => {\n        const normalizedQuery = query.toLowerCase();\n        const results: Entity[] = [];\n        const seen = new Set<string>(); // Track by ID to avoid duplicates\n    \n        for (const entityMap of entities.values()) {\n            for (const entity of entityMap.values()) {\n                let matched = false;\n                \n                // Check name\n                if (entity.name.toLowerCase().includes(normalizedQuery)) {\n                    matched = true;\n                }\n                \n                // Also check sounds_like field\n                if (!matched) {\n                    const entityWithSoundsLike = entity as Entity & { sounds_like?: string[] };\n                    const variants = entityWithSoundsLike.sounds_like;\n                    if (variants?.some(v => v.toLowerCase().includes(normalizedQuery))) {\n                        matched = true;\n                    }\n                }\n                \n                // Also check exact match in sounds_like (for full phrase matching)\n                if (!matched) {\n                    const entityWithSoundsLike = entity as Entity & { sounds_like?: string[] };\n                    const variants = entityWithSoundsLike.sounds_like;\n                    if (variants?.some(v => v.toLowerCase() === normalizedQuery)) {\n                        matched = true;\n                    }\n                }\n                \n                if (matched && !seen.has(entity.id)) {\n                    results.push(entity);\n                    seen.add(entity.id);\n                }\n            }\n        }\n    \n        return results;\n    };\n\n    const findBySoundsLike = (phonetic: string): Entity | undefined => {\n        const normalized = phonetic.toLowerCase().trim();\n    \n        for (const entityMap of entities.values()) {\n            for (const entity of entityMap.values()) {\n                // Check sounds_like field on entities that have it\n                const entityWithSoundsLike = entity as Entity & { sounds_like?: string[] };\n                const variants = entityWithSoundsLike.sounds_like;\n                if (variants?.some(v => v.toLowerCase() === normalized)) {\n                    return entity;\n                }\n            }\n        }\n    \n        return undefined;\n    };\n\n    const clear = (): void => {\n        for (const entityMap of entities.values()) {\n            entityMap.clear();\n        }\n    };\n\n    return { load, save, delete: deleteEntity, get, getAll, search, findBySoundsLike, clear, getEntityFilePath };\n};\n\n"],"names":["path","fs","yaml","existsSync","readdirSync","statSync"],"mappings":"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"}