UNPKG

kotadb-client

Version:

TypeScript/JavaScript client for KotaDB - PostgreSQL-level ease of use for document database

450 lines (368 loc) 10.7 kB
# KotaDB TypeScript/JavaScript Client A simple, PostgreSQL-level easy-to-use TypeScript/JavaScript client for KotaDB with built-in type safety and validation. ## Features - **Type Safety**: Validated types prevent common errors before they reach the server - **Security**: Protection against path injection and other client-side attacks - **Builder Patterns**: Fluent APIs with IntelliSense-friendly construction - **Consistency**: Same patterns as Python client for consistent developer experience - **Backward Compatible**: All existing code continues to work unchanged ## Installation ```bash npm install kotadb-client ``` ## Quick Start ### Basic Usage (TypeScript) ```typescript import { KotaDB } from 'kotadb-client'; // Connect to KotaDB const db = new KotaDB({ url: 'http://localhost:8080' }); // Insert a document const docId = await db.insert({ path: '/notes/meeting.md', title: 'Team Meeting Notes', content: 'Discussed project roadmap and next steps...', tags: ['work', 'meeting', 'planning'] }); // Search for documents const results = await db.query('project roadmap'); for (const result of results.results) { console.log(`Found: ${result.document.title} (score: ${result.score})`); } // Get a specific document const doc = await db.get(docId); console.log(`Document: ${doc.title}`); // Update a document const updatedDoc = await db.update(docId, { content: 'Updated meeting notes with action items...' }); // Delete a document await db.delete(docId); ``` ### Type-Safe Usage with Builders (Recommended) ```typescript import { KotaDB, DocumentBuilder, QueryBuilder, ValidatedPath, ValidatedTitle } from 'kotadb-client'; const db = new KotaDB({ url: 'http://localhost:8080' }); // Create document with type safety and validation const docId = await db.insertWithBuilder( new DocumentBuilder() .path("/notes/meeting.md") // Validates path safety .title("Team Meeting Notes") // Ensures non-empty .content("Safe content") // Validates content .addTag("work") // Validates tag format .addTag("meeting") .addMetadata("priority", "high") ); // Type-safe search queries const results = await db.queryWithBuilder( new QueryBuilder() .text("project roadmap") .limit(10) .tagFilter("work") .pathFilter("/notes/*") ); // Semantic search with validation const semanticResults = await db.semanticSearchWithBuilder( new QueryBuilder() .text("machine learning concepts") .limit(5) .semanticWeight(0.7) // Validates 0.0-1.0 range ); ``` ### JavaScript (CommonJS) ```javascript const { KotaDB } = require('kotadb-client'); // Connect to KotaDB const db = new KotaDB({ url: 'http://localhost:8080' }); // Use with async/await or promises db.query('search term') .then(results => { console.log(`Found ${results.total_count} results`); }) .catch(error => { console.error('Search failed:', error); }); ``` ### JavaScript (ES Modules) ```javascript import { KotaDB } from 'kotadb-client'; const db = new KotaDB({ url: 'http://localhost:8080' }); const results = await db.query('search term'); ``` ## Type Safety and Validation ### Validated Types The client provides validated types that ensure data integrity and security: ```typescript import { ValidatedPath, ValidatedDocumentId, ValidatedTitle, ValidationError } from 'kotadb-client'; // Safe path validation try { const path = new ValidatedPath("/notes/meeting.md"); console.log(path.asStr()); // "/notes/meeting.md" } catch (error) { if (error instanceof ValidationError) { console.error("Invalid path:", error.message); } } // Prevents directory traversal attacks try { new ValidatedPath("../../../etc/passwd"); // Throws ValidationError } catch (error) { console.log("Security threat blocked!"); } // Document ID validation const docId = ValidatedDocumentId.new(); // Generates valid UUID const existingId = ValidatedDocumentId.parse("123e4567-e89b-12d3-a456-426614174000"); // Title validation const title = new ValidatedTitle("My Document"); // Ensures non-empty, length limits ``` ### Builder Patterns Use builders for fluent, validated construction: ```typescript import { DocumentBuilder, QueryBuilder, UpdateBuilder } from 'kotadb-client'; // Document builder with validation at each step const document = new DocumentBuilder() .path("/documents/report.md") // Validates path security .title("Quarterly Report") // Validates non-empty title .content("Report content here...") // Accepts string or byte array .addTag("business") // Validates tag format .addTag("quarterly") .addMetadata("author", "jane.doe") .addMetadata("department", "finance") .autoId() // Generates secure UUID .build(); // Query builder with parameter validation const searchParams = new QueryBuilder() .text("quarterly business") // Validates search query .limit(25) // Validates positive numbers .offset(50) // Validates non-negative .semanticWeight(0.8) // Validates 0.0-1.0 range .tagFilter("business") // Validates tag format .pathFilter("/documents/*") // Path pattern filter .build(); // Update builder for safe document modifications const updates = new UpdateBuilder() .title("Updated Quarterly Report") // Validates title .addTag("updated") // Validates and merges tags .removeTag("draft") // Safe tag removal .addMetadata("revised_by", "john.doe") // Metadata updates .build(); ``` ### Security Features Built-in protection against common attacks: ```typescript // Path traversal protection try { new DocumentBuilder().path("../../../etc/passwd"); // Blocked } catch (error) { console.log("Directory traversal blocked"); } // Null byte injection protection try { new DocumentBuilder().path("/file\x00.txt"); // Blocked } catch (error) { console.log("Null byte injection blocked"); } // Reserved name protection (Windows compatibility) try { new DocumentBuilder().path("CON.txt"); // Blocked } catch (error) { console.log("Reserved filename blocked"); } // Input validation try { new QueryBuilder().limit(-1); // Blocked new QueryBuilder().semanticWeight(1.5); // Blocked new DocumentBuilder().addTag("invalid@tag"); // Blocked } catch (error) { console.log("Invalid input blocked"); } ``` ## Connection Options ### Environment Variable ```bash export KOTADB_URL="http://localhost:8080" ``` ```typescript // Will use KOTADB_URL automatically const db = new KotaDB(); ``` ### Connection String ```typescript // PostgreSQL-style connection string const db = new KotaDB({ url: 'kotadb://localhost:8080/myapp' }); // Direct HTTP URL const db = new KotaDB({ url: 'http://localhost:8080' }); ``` ### Advanced Configuration ```typescript const db = new KotaDB({ url: 'http://localhost:8080', timeout: 30000, // 30 second timeout retries: 3, // 3 retry attempts headers: { // Custom headers 'Authorization': 'Bearer token', 'X-Custom-Header': 'value' } }); ``` ## Search Options ### Text Search ```typescript const results = await db.query('rust programming patterns', { limit: 10, offset: 0 }); ``` ### Semantic Search ```typescript const results = await db.semanticSearch('machine learning concepts', { limit: 5, model: 'all-MiniLM-L6-v2' }); ``` ### Hybrid Search ```typescript const results = await db.hybridSearch('database optimization', { limit: 10, semantic_weight: 0.7 // 70% semantic, 30% text }); ``` ## Document Operations ### Create Document ```typescript const docId = await db.insert({ path: '/docs/guide.md', title: 'User Guide', content: 'How to use the system...', tags: ['documentation', 'guide'], metadata: { author: 'jane@example.com' } }); ``` ### List Documents ```typescript // Get all documents const allDocs = await db.listAll(); // With pagination const docs = await db.listAll({ limit: 50, offset: 100 }); ``` ### Database Health ```typescript // Check health const health = await db.health(); console.log(`Status: ${health.status}`); // Get statistics const stats = await db.stats(); console.log(`Document count: ${stats.document_count}`); ``` ## Error Handling ```typescript import { KotaDBError, NotFoundError, ConnectionError, ValidationError } from 'kotadb-client'; try { const doc = await db.get('non-existent-id'); } catch (error) { if (error instanceof ValidationError) { console.log(`Validation failed: ${error.message}`); } else if (error instanceof NotFoundError) { console.log('Document not found'); } else if (error instanceof ConnectionError) { console.log('Failed to connect to database'); } else if (error instanceof KotaDBError) { console.log(`Database error: ${error.message}`); } else { console.log(`Unexpected error: ${error}`); } } // Builder validation errors try { const builder = new DocumentBuilder() .path("../../../etc/passwd") // Invalid path .title("") // Empty title .build(); } catch (error) { if (error instanceof ValidationError) { console.log("Input validation failed:", error.message); // Handle validation error appropriately } } ``` ## Type Definitions ### Document ```typescript interface Document { id: string; path: string; title: string; content: string; tags: string[]; created_at: string; updated_at: string; size: number; metadata?: Record<string, any>; } ``` ### SearchResult ```typescript interface SearchResult { document: Document; score: number; content_preview: string; } ``` ### QueryResult ```typescript interface QueryResult { results: SearchResult[]; total_count: number; query_time_ms: number; } ``` ## Browser Support This client works in both Node.js and modern browsers. For browser usage: ```html <!-- Using a CDN (once published) --> <script src="https://unpkg.com/kotadb-client@latest/dist/index.js"></script> <script> const db = new KotaDB.default({ url: 'http://localhost:8080' }); // Use the client... </script> ``` ## Development ### Building ```bash npm run build ``` ### Testing ```bash npm test ``` ### Linting ```bash npm run lint npm run lint:fix ``` ### Formatting ```bash npm run format ``` ## License MIT License - see LICENSE file for details. ## Contributing See CONTRIBUTING.md for contribution guidelines. ## Support - GitHub Issues: https://github.com/jayminwest/kota-db/issues - Documentation: https://github.com/jayminwest/kota-db/docs