{"version":3,"file":"index5.cjs","sources":["../src/storage/adapter.ts"],"sourcesContent":["import { \n    discoverOvercontext, \n    OvercontextAPI,\n    BaseEntity,\n    createContext as createOvercontextContext,\n    createFjellGcsProvider,\n    createSchemaRegistry,\n} from '@utilarium/overcontext';\nimport {\n    redaksjonSchemas,\n    redaksjonPluralNames,\n} from '../schemas';\nimport type {\n    Person,\n    Project,\n    Company,\n    Term,\n    IgnoredTerm,\n    RedaksjonEntity,\n    RedaksjonEntityType,\n} from '../types';\nimport { existsSync, statSync, readdirSync } from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Entity filename strategy: first 8 chars of UUID + slug.\n * Produces filenames like `d00acdc4-gerald-corson.yaml`.\n * Falls back to entity.id when no slug is present.\n */\nexport const redaksjonFilenameStrategy = (entity: BaseEntity): string => {\n    const slug = (entity as RedaksjonEntity & { slug?: string }).slug;\n    if (slug) {\n        const prefix = entity.id.substring(0, 8);\n        return `${prefix}-${slug}`;\n    }\n    return entity.id;\n};\n\n// Re-export types for backwards compatibility\nexport type { Person, Project, Company, Term, IgnoredTerm, RedaksjonEntity };\nexport type EntityType = RedaksjonEntityType;\nexport type Entity = RedaksjonEntity;\n\n/**\n * StorageInstance interface - matches protokoll's current API.\n */\nexport interface StorageInstance {\n  load(contextDirs: string[]): Promise<void>;\n  save(entity: Entity, targetDir: string, allowUpdate?: boolean): 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\nexport interface GcsStorageOptions {\n    bucketName: string;\n    basePath: string;\n    projectId?: string;\n    credentialsFile?: string;\n}\n\nexport interface AdapterCreateOptions {\n    gcs?: GcsStorageOptions;\n}\n\n/**\n * Create a storage instance backed by overcontext.\n * Maintains API compatibility with protokoll's existing storage.\n */\n// Map entity types to their directory names\nconst TYPE_TO_DIRECTORY: Record<EntityType, string> = {\n    person: 'people',\n    project: 'projects',\n    company: 'companies',\n    term: 'terms',\n    ignored: 'ignored',\n};\n\nexport const create = (options: AdapterCreateOptions = {}): StorageInstance => {\n    // In-memory cache for sync access (matching original behavior)\n    const cache = new Map<EntityType, Map<string, Entity>>();\n    const aliasIndex = new Map<EntityType, Map<string, string>>();\n    let api: OvercontextAPI<typeof redaksjonSchemas> | undefined;\n    let loadedContextDirs: string[] = [];\n  \n    const initCache = () => {\n        cache.set('person', new Map());\n        cache.set('project', new Map());\n        cache.set('company', new Map());\n        cache.set('term', new Map());\n        cache.set('ignored', new Map());\n        aliasIndex.set('person', new Map());\n        aliasIndex.set('project', new Map());\n        aliasIndex.set('company', new Map());\n        aliasIndex.set('term', new Map());\n        aliasIndex.set('ignored', new Map());\n    };\n\n    const registerAlias = (type: EntityType, alias: string, canonicalId: string): void => {\n        const trimmed = alias.trim();\n        if (!trimmed) {\n            return;\n        }\n        aliasIndex.get(type)?.set(trimmed, canonicalId);\n    };\n\n    const resolveEntityId = (type: EntityType, identifier: string | null | undefined): string | undefined => {\n        if (identifier == null) {\n            return undefined;\n        }\n        const trimmed = identifier.trim();\n        if (!trimmed) {\n            return undefined;\n        }\n\n        const entities = cache.get(type);\n        if (entities?.has(trimmed)) {\n            return trimmed;\n        }\n\n        const aliases = aliasIndex.get(type);\n        const directAlias = aliases?.get(trimmed);\n        if (directAlias) {\n            return directAlias;\n        }\n\n        // Support full UUID lookup when filenames use only UUID prefixes.\n        const uuidPrefixMatch = trimmed.match(/^([a-f0-9]{8})/i);\n        if (uuidPrefixMatch) {\n            const byPrefix = aliases?.get(uuidPrefixMatch[1].toLowerCase());\n            if (byPrefix) {\n                return byPrefix;\n            }\n        }\n\n        return undefined;\n    };\n  \n    initCache();\n  \n    return {\n        async load(contextDirs: string[]): Promise<void> {\n            initCache();\n            loadedContextDirs = contextDirs;\n            \n            // If no context directories, leave API undefined (empty context)\n            if (contextDirs.length === 0) {\n                api = undefined;\n                return;\n            }\n      \n            try {\n                if (options.gcs) {\n                    const registry = createSchemaRegistry();\n                    for (const [type, schema] of Object.entries(redaksjonSchemas)) {\n                        registry.register({\n                            type,\n                            schema,\n                            pluralName: redaksjonPluralNames[type as RedaksjonEntityType] ?? `${type}s`,\n                        });\n                    }\n                    // Match RiotPlan precedence: explicit config credentials\n                    // should override ambient ADC env for deterministic behavior.\n                    if (options.gcs.credentialsFile) {\n                        process.env.GOOGLE_APPLICATION_CREDENTIALS = options.gcs.credentialsFile;\n                    }\n                    if (options.gcs.projectId) {\n                        process.env.GOOGLE_CLOUD_PROJECT = options.gcs.projectId;\n                    }\n                    const provider = await createFjellGcsProvider({\n                        bucketName: options.gcs.bucketName,\n                        basePath: options.gcs.basePath,\n                        registry,\n                    });\n                    api = createOvercontextContext({\n                        provider,\n                        registry,\n                        schemas: redaksjonSchemas,\n                    });\n                } else {\n                    // contextDirs are already resolved paths (e.g., /path/to/context or /path/to/.protokoll/context)\n                    // We need to determine the parent directory to start overcontext discovery from\n                    // The context directory could be at different levels depending on configuration\n\n                    // Take the last (most specific) context dir\n                    const lastContextDir = contextDirs[contextDirs.length - 1];\n\n                    // Get the parent directory of the context directory\n                    // This will be the directory containing the context/ folder\n                    const startDir = path.dirname(lastContextDir);\n\n                    // Create overcontext API with hierarchical discovery\n                    // Note: We use 'context' as contextDirName since we're starting from the parent\n                    // Use maxLevels: 1 to limit discovery - we've already done hierarchical discovery\n                    // in loadHierarchicalConfig and are passing the specific contextDirs we want.\n                    // maxLevels: 1 prevents walking too far up the tree in CI environments where\n                    // parent directories might contain unrelated context data.\n                    api = await discoverOvercontext({\n                        schemas: redaksjonSchemas,\n                        pluralNames: redaksjonPluralNames,\n                        startDir,\n                        contextDirName: path.basename(lastContextDir),\n                        maxLevels: 1,\n                        filenameStrategy: redaksjonFilenameStrategy,\n                    });\n                }\n      \n                // Load all entities into cache\n                for (const type of ['person', 'project', 'company', 'term', 'ignored'] as EntityType[]) {\n                    const entities = await api.getAll(type);\n                    for (const entity of entities) {\n                        cache.get(type)?.set(entity.id, entity as Entity);\n                        registerAlias(type, entity.id, entity.id);\n                        const slug = (entity as Entity & { slug?: string }).slug;\n                        if (typeof slug === 'string' && slug.trim().length > 0) {\n                            registerAlias(type, slug, entity.id);\n                        }\n                        const idPrefix = entity.id.match(/^([a-f0-9]{8})/i);\n                        if (idPrefix) {\n                            registerAlias(type, idPrefix[1].toLowerCase(), entity.id);\n                        }\n                        const slugFromName = entity.name\n                            .toLowerCase()\n                            .trim()\n                            .replace(/[^a-z0-9]+/g, '-')\n                            .replace(/-+/g, '-')\n                            .replace(/^-|-$/g, '');\n                        if (slugFromName.length > 0) {\n                            registerAlias(type, slugFromName, entity.id);\n                        }\n                    }\n                }\n\n                // Build UUID-prefix aliases from filenames to support UUID lookups\n                // when some entities still use slug IDs in YAML.\n                if (!options.gcs) {\n                    const allTypeDirs = ['person', 'project', 'company', 'term', 'ignored'] as EntityType[];\n                    for (const type of allTypeDirs) {\n                        const entityMap = cache.get(type);\n                        if (!entityMap || entityMap.size === 0) {\n                            continue;\n                        }\n\n                        const entitiesBySlug = new Map<string, string>();\n                        for (const entity of entityMap.values()) {\n                            const slug = (entity as Entity & { slug?: string }).slug;\n                            if (typeof slug === 'string' && slug.trim().length > 0) {\n                                entitiesBySlug.set(slug.trim(), entity.id);\n                            }\n                            const slugFromName = entity.name\n                                .toLowerCase()\n                                .trim()\n                                .replace(/[^a-z0-9]+/g, '-')\n                                .replace(/-+/g, '-')\n                                .replace(/^-|-$/g, '');\n                            if (slugFromName.length > 0 && !entitiesBySlug.has(slugFromName)) {\n                                entitiesBySlug.set(slugFromName, entity.id);\n                            }\n                            if (!entitiesBySlug.has(entity.id)) {\n                                entitiesBySlug.set(entity.id, entity.id);\n                            }\n                        }\n\n                        const typeDirName = TYPE_TO_DIRECTORY[type];\n                        for (const contextDir of contextDirs) {\n                            const entityDir = path.join(contextDir, typeDirName);\n                            if (!existsSync(entityDir)) {\n                                continue;\n                            }\n                            try {\n                                const files = readdirSync(entityDir);\n                                for (const file of files) {\n                                    if (!file.endsWith('.yaml') && !file.endsWith('.yml')) {\n                                        continue;\n                                    }\n                                    const stem = file.replace(/\\.(yaml|yml)$/i, '');\n                                    const prefixedMatch = stem.match(/^([a-f0-9]{8,})-(.+)$/i);\n                                    if (!prefixedMatch) {\n                                        continue;\n                                    }\n                                    const prefix = prefixedMatch[1].toLowerCase();\n                                    const slug = prefixedMatch[2];\n                                    const canonicalId = entitiesBySlug.get(slug);\n                                    if (canonicalId) {\n                                        registerAlias(type, prefix, canonicalId);\n                                    }\n                                }\n                            } catch {\n                                // Skip unreadable entity directories.\n                            }\n                        }\n                    }\n                }\n            } catch (error) {\n                // If no context directory found, leave API undefined (empty context)\n                if (error instanceof Error && error.message.includes('No context directory found')) {\n                    api = undefined;\n                } else {\n                    throw error;\n                }\n            }\n        },\n    \n        async save(entity: Entity, _targetDir: string, allowUpdate = false): Promise<void> {\n            // Check if entity already exists (for duplicate detection)\n            const existingId = resolveEntityId(entity.type, entity.id);\n            const existing = existingId ? cache.get(entity.type)?.get(existingId) : undefined;\n            if (existing && !allowUpdate) {\n                throw new Error(`Entity with id \"${entity.id}\" already exists`);\n            }\n\n            // If no API (empty context), just update cache (in-memory only)\n            if (!api) {\n                cache.get(entity.type)?.set(entity.id, entity);\n                return;\n            }\n      \n            // Save via overcontext (upsert will create or update)\n            const saved = await api.upsert(entity.type, entity);\n      \n            // Update cache\n            cache.get(entity.type)?.set(saved.id, saved as Entity);\n            registerAlias(entity.type, saved.id, saved.id);\n            const savedSlug = (saved as Entity & { slug?: string }).slug;\n            if (typeof savedSlug === 'string' && savedSlug.trim().length > 0) {\n                registerAlias(entity.type, savedSlug, saved.id);\n            }\n            const idPrefix = saved.id.match(/^([a-f0-9]{8})/i);\n            if (idPrefix) {\n                registerAlias(entity.type, idPrefix[1].toLowerCase(), saved.id);\n            }\n        },\n    \n        async delete(type: EntityType, id: string, _targetDir: string): Promise<boolean> {\n            if (!api) return false;\n            const resolvedId = resolveEntityId(type, id) || id;\n\n            const deleted = await api.delete(type, resolvedId);\n            if (deleted) {\n                cache.get(type)?.delete(resolvedId);\n            }\n            return deleted;\n        },\n    \n        get<T extends Entity>(type: EntityType, id: string): T | undefined {\n            const resolvedId = resolveEntityId(type, id);\n            return resolvedId ? cache.get(type)?.get(resolvedId) as T | undefined : undefined;\n        },\n    \n        getAll<T extends Entity>(type: EntityType): T[] {\n            return Array.from(cache.get(type)?.values() ?? []) as T[];\n        },\n    \n        search(query: string): Entity[] {\n            const normalizedQuery = query.toLowerCase();\n            const results: Entity[] = [];\n            const seen = new Set<string>();\n      \n            for (const entityMap of cache.values()) {\n                for (const entity of entityMap.values()) {\n                    if (seen.has(entity.id)) continue;\n          \n                    // Check name\n                    if (entity.name.toLowerCase().includes(normalizedQuery)) {\n                        results.push(entity);\n                        seen.add(entity.id);\n                        continue;\n                    }\n          \n                    // Check sounds_like\n                    const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n                    if (sounds?.some((s: string) => s.toLowerCase().includes(normalizedQuery))) {\n                        results.push(entity);\n                        seen.add(entity.id);\n                    }\n                }\n            }\n      \n            return results;\n        },\n    \n        findBySoundsLike(phonetic: string): Entity | undefined {\n            const normalized = phonetic.toLowerCase().trim();\n      \n            for (const entityMap of cache.values()) {\n                for (const entity of entityMap.values()) {\n                    const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n                    if (sounds?.some((s: string) => s.toLowerCase() === normalized)) {\n                        return entity;\n                    }\n                }\n            }\n      \n            return undefined;\n        },\n    \n        clear(): void {\n            initCache();\n            api = undefined;\n        },\n    \n        getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined {\n            if (options.gcs) {\n                // GCS-backed storage does not expose local file paths.\n                return undefined;\n            }\n\n            const dirName = TYPE_TO_DIRECTORY[type];\n            const dirsToSearch = contextDirs.length > 0 ? contextDirs : loadedContextDirs;\n            const entity = cache.get(type)?.get(id);\n            \n            for (const contextDir of [...dirsToSearch].reverse()) {\n                const entityDir = path.join(contextDir, dirName);\n\n                // Try compound filename first (e.g. d00acdc4-gerald-corson.yaml)\n                if (entity) {\n                    const compoundName = redaksjonFilenameStrategy(entity as RedaksjonEntity & { slug?: string });\n                    for (const ext of ['.yaml', '.yml']) {\n                        const filePath = path.join(entityDir, `${compoundName}${ext}`);\n                        if (existsSync(filePath) && statSync(filePath).isFile()) {\n                            return filePath;\n                        }\n                    }\n                }\n\n                // Fall back to direct id-based filename (legacy)\n                for (const ext of ['.yaml', '.yml']) {\n                    const filePath = path.join(entityDir, `${id}${ext}`);\n                    if (existsSync(filePath) && statSync(filePath).isFile()) {\n                        return filePath;\n                    }\n                }\n\n                // Prefix scan as last resort (handles files we haven't cached yet)\n                if (existsSync(entityDir)) {\n                    const prefix = id.substring(0, 8);\n                    try {\n                        const files = readdirSync(entityDir);\n                        const match = files.find(f =>\n                            f.startsWith(prefix) && (f.endsWith('.yaml') || f.endsWith('.yml'))\n                        );\n                        if (match) {\n                            return path.join(entityDir, match);\n                        }\n                    } catch { /* directory read failed */ }\n                }\n            }\n            \n            return undefined;\n        },\n    };\n};\n"],"names":["createSchemaRegistry","redaksjonSchemas","redaksjonPluralNames","createFjellGcsProvider","createOvercontextContext","path","discoverOvercontext","existsSync","readdirSync","statSync"],"mappings":"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"}