Skip to main content
Glama
config.test.ts14.1 kB
/** * Tests for config loading and path resolution */ import { describe, expect, test } from "bun:test"; describe("config", () => { const CONFIG_FILE = ".doclea/config.json"; describe("config file path", () => { function getConfigPath(projectPath: string): string { return `${projectPath}/${CONFIG_FILE}`; } test("builds correct path", () => { expect(getConfigPath("/home/user/project")).toBe( "/home/user/project/.doclea/config.json", ); }); test("handles root path", () => { expect(getConfigPath("/")).toBe("//.doclea/config.json"); }); test("handles relative path", () => { expect(getConfigPath(".")).toBe("./.doclea/config.json"); }); }); describe("db path resolution", () => { interface Config { storage: { dbPath: string }; } function getDbPath(config: Config, projectPath: string): string { return `${projectPath}/${config.storage.dbPath}`; } test("resolves db path from config", () => { const config = { storage: { dbPath: ".doclea/local.db" } }; expect(getDbPath(config, "/home/user/project")).toBe( "/home/user/project/.doclea/local.db", ); }); test("handles custom db path", () => { const config = { storage: { dbPath: "data/memories.db" } }; expect(getDbPath(config, "/project")).toBe("/project/data/memories.db"); }); }); describe("default config structure", () => { interface DefaultConfig { embedding: { provider: string; endpoint: string }; qdrant: { url: string; collectionName: string }; storage: { dbPath: string }; } const DEFAULT_CONFIG: DefaultConfig = { embedding: { provider: "local", endpoint: "http://localhost:8080" }, qdrant: { url: "http://localhost:6333", collectionName: "doclea_memories", }, storage: { dbPath: ".doclea/local.db" }, }; test("uses local provider by default", () => { expect(DEFAULT_CONFIG.embedding.provider).toBe("local"); }); test("uses default local endpoint", () => { expect(DEFAULT_CONFIG.embedding.endpoint).toBe("http://localhost:8080"); }); test("uses default qdrant url", () => { expect(DEFAULT_CONFIG.qdrant.url).toBe("http://localhost:6333"); }); test("uses default collection name", () => { expect(DEFAULT_CONFIG.qdrant.collectionName).toBe("doclea_memories"); }); test("uses default db path", () => { expect(DEFAULT_CONFIG.storage.dbPath).toBe(".doclea/local.db"); }); }); describe("config validation", () => { interface Config { embedding: { provider: string }; qdrant: { url: string; collectionName: string }; storage: { dbPath: string }; } function isValidConfig(config: unknown): config is Config { if (typeof config !== "object" || config === null) return false; const c = config as Record<string, unknown>; if (typeof c.embedding !== "object" || c.embedding === null) return false; if (typeof c.qdrant !== "object" || c.qdrant === null) return false; if (typeof c.storage !== "object" || c.storage === null) return false; const embedding = c.embedding as Record<string, unknown>; const qdrant = c.qdrant as Record<string, unknown>; const storage = c.storage as Record<string, unknown>; return ( typeof embedding.provider === "string" && typeof qdrant.url === "string" && typeof qdrant.collectionName === "string" && typeof storage.dbPath === "string" ); } test("validates complete config", () => { const config = { embedding: { provider: "local", endpoint: "http://localhost:8080" }, qdrant: { url: "http://localhost:6333", collectionName: "memories" }, storage: { dbPath: ".doclea/local.db" }, }; expect(isValidConfig(config)).toBe(true); }); test("rejects missing embedding", () => { const config = { qdrant: { url: "http://localhost:6333", collectionName: "memories" }, storage: { dbPath: ".doclea/local.db" }, }; expect(isValidConfig(config)).toBe(false); }); test("rejects missing qdrant", () => { const config = { embedding: { provider: "local" }, storage: { dbPath: ".doclea/local.db" }, }; expect(isValidConfig(config)).toBe(false); }); test("rejects missing storage", () => { const config = { embedding: { provider: "local" }, qdrant: { url: "http://localhost:6333", collectionName: "memories" }, }; expect(isValidConfig(config)).toBe(false); }); test("rejects null config", () => { expect(isValidConfig(null)).toBe(false); }); }); describe("config error building", () => { function buildConfigError(path: string, message: string): string { return `Failed to load config from ${path}: ${message}`; } test("builds error message", () => { const error = buildConfigError( "/project/.doclea/config.json", "Invalid JSON", ); expect(error).toBe( "Failed to load config from /project/.doclea/config.json: Invalid JSON", ); }); test("handles parse error", () => { const error = buildConfigError("/config.json", "Unexpected token"); expect(error).toContain("Unexpected token"); }); }); describe("embedding provider extraction", () => { type Provider = "local" | "openai" | "nomic" | "voyage" | "ollama"; function getEmbeddingProvider(config: { embedding: { provider: string }; }): Provider | null { const p = config.embedding.provider; if (["local", "openai", "nomic", "voyage", "ollama"].includes(p)) { return p as Provider; } return null; } test("extracts local provider", () => { expect(getEmbeddingProvider({ embedding: { provider: "local" } })).toBe( "local", ); }); test("extracts openai provider", () => { expect(getEmbeddingProvider({ embedding: { provider: "openai" } })).toBe( "openai", ); }); test("returns null for invalid provider", () => { expect( getEmbeddingProvider({ embedding: { provider: "invalid" } }), ).toBeNull(); }); }); describe("qdrant config extraction", () => { interface QdrantConfig { url: string; apiKey?: string; collectionName: string; } function extractQdrantConfig(config: { qdrant: Record<string, unknown>; }): QdrantConfig | null { const q = config.qdrant; if (typeof q.url !== "string" || typeof q.collectionName !== "string") { return null; } return { url: q.url, apiKey: typeof q.apiKey === "string" ? q.apiKey : undefined, collectionName: q.collectionName, }; } test("extracts complete qdrant config", () => { const config = { qdrant: { url: "http://localhost:6333", apiKey: "secret", collectionName: "memories", }, }; const extracted = extractQdrantConfig(config); expect(extracted?.url).toBe("http://localhost:6333"); expect(extracted?.apiKey).toBe("secret"); expect(extracted?.collectionName).toBe("memories"); }); test("extracts config without apiKey", () => { const config = { qdrant: { url: "http://localhost:6333", collectionName: "memories" }, }; const extracted = extractQdrantConfig(config); expect(extracted?.apiKey).toBeUndefined(); }); test("returns null for missing url", () => { const config = { qdrant: { collectionName: "memories" } }; expect(extractQdrantConfig(config)).toBeNull(); }); }); describe("auto-detection", () => { // Constants matching the implementation const QDRANT_DEFAULT_URL = "http://localhost:6333"; const TEI_DEFAULT_ENDPOINT = "http://localhost:8080"; interface Config { embedding: { provider: string; endpoint?: string; model?: string }; vector: { provider: string; url?: string; collectionName?: string; dbPath?: string; }; storage: { dbPath: string }; } const DEFAULT_CONFIG: Config = { embedding: { provider: "transformers", model: "mxbai-embed-xsmall-v1" }, vector: { provider: "sqlite-vec", dbPath: ".doclea/vectors.db" }, storage: { dbPath: ".doclea/local.db" }, }; function simulateDetectConfig( qdrantRunning: boolean, teiRunning: boolean, ): Config { const config: Config = { ...DEFAULT_CONFIG }; if (qdrantRunning) { config.vector = { provider: "qdrant", url: QDRANT_DEFAULT_URL, collectionName: "doclea-memories", }; } if (teiRunning) { config.embedding = { provider: "local", endpoint: TEI_DEFAULT_ENDPOINT, }; } return config; } test("uses embedded backends when no services running", () => { const config = simulateDetectConfig(false, false); expect(config.embedding.provider).toBe("transformers"); expect(config.vector.provider).toBe("sqlite-vec"); }); test("uses Qdrant when running", () => { const config = simulateDetectConfig(true, false); expect(config.vector.provider).toBe("qdrant"); expect(config.vector.url).toBe(QDRANT_DEFAULT_URL); expect(config.vector.collectionName).toBe("doclea-memories"); }); test("uses TEI when running", () => { const config = simulateDetectConfig(false, true); expect(config.embedding.provider).toBe("local"); expect(config.embedding.endpoint).toBe(TEI_DEFAULT_ENDPOINT); }); test("uses both Docker services when running", () => { const config = simulateDetectConfig(true, true); expect(config.embedding.provider).toBe("local"); expect(config.vector.provider).toBe("qdrant"); }); test("keeps embedded storage regardless of services", () => { const configNoServices = simulateDetectConfig(false, false); const configAllServices = simulateDetectConfig(true, true); expect(configNoServices.storage.dbPath).toBe(".doclea/local.db"); expect(configAllServices.storage.dbPath).toBe(".doclea/local.db"); }); }); describe("vector config extraction (new schema)", () => { type VectorProvider = "sqlite-vec" | "qdrant"; interface SqliteVecConfig { provider: "sqlite-vec"; dbPath: string; vectorSize?: number; } interface QdrantConfig { provider: "qdrant"; url: string; apiKey?: string; collectionName: string; } type VectorConfig = SqliteVecConfig | QdrantConfig; function extractVectorConfig( config: Record<string, unknown>, ): VectorConfig | null { if (typeof config.provider !== "string") return null; if (config.provider === "sqlite-vec") { if (typeof config.dbPath !== "string") return null; return { provider: "sqlite-vec", dbPath: config.dbPath, vectorSize: typeof config.vectorSize === "number" ? config.vectorSize : undefined, }; } if (config.provider === "qdrant") { if ( typeof config.url !== "string" || typeof config.collectionName !== "string" ) { return null; } return { provider: "qdrant", url: config.url, apiKey: typeof config.apiKey === "string" ? config.apiKey : undefined, collectionName: config.collectionName, }; } return null; } test("extracts sqlite-vec config", () => { const config = { provider: "sqlite-vec", dbPath: ".doclea/vectors.db", vectorSize: 384, }; const extracted = extractVectorConfig(config); expect(extracted?.provider).toBe("sqlite-vec"); expect((extracted as SqliteVecConfig)?.dbPath).toBe(".doclea/vectors.db"); expect((extracted as SqliteVecConfig)?.vectorSize).toBe(384); }); test("extracts qdrant config", () => { const config = { provider: "qdrant", url: "http://localhost:6333", collectionName: "memories", }; const extracted = extractVectorConfig(config); expect(extracted?.provider).toBe("qdrant"); expect((extracted as QdrantConfig)?.url).toBe("http://localhost:6333"); }); test("returns null for invalid provider", () => { const config = { provider: "invalid", dbPath: "test.db" }; expect(extractVectorConfig(config)).toBeNull(); }); }); describe("embedding provider extraction (new schema)", () => { type Provider = | "local" | "openai" | "nomic" | "voyage" | "ollama" | "transformers"; function getEmbeddingProviderNew(config: { embedding: { provider: string }; }): Provider | null { const p = config.embedding.provider; if ( [ "local", "openai", "nomic", "voyage", "ollama", "transformers", ].includes(p) ) { return p as Provider; } return null; } test("extracts transformers provider", () => { expect( getEmbeddingProviderNew({ embedding: { provider: "transformers" } }), ).toBe("transformers"); }); test("extracts local provider", () => { expect( getEmbeddingProviderNew({ embedding: { provider: "local" } }), ).toBe("local"); }); test("extracts all valid providers", () => { const providers: Provider[] = [ "local", "openai", "nomic", "voyage", "ollama", "transformers", ]; for (const provider of providers) { expect(getEmbeddingProviderNew({ embedding: { provider } })).toBe( provider, ); } }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/docleaai/doclea-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server