npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kotadb-client

v0.6.1

Published

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

Readme

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

npm install kotadb-client

Quick Start

Basic Usage (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)

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)

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)

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:

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:

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:

// 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

export KOTADB_URL="http://localhost:8080"
// Will use KOTADB_URL automatically
const db = new KotaDB();

Connection String

// 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

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

const results = await db.query('rust programming patterns', {
  limit: 10,
  offset: 0
});

Semantic Search

const results = await db.semanticSearch('machine learning concepts', {
  limit: 5,
  model: 'all-MiniLM-L6-v2'
});

Hybrid Search

const results = await db.hybridSearch('database optimization', {
  limit: 10,
  semantic_weight: 0.7  // 70% semantic, 30% text
});

Document Operations

Create Document

const docId = await db.insert({
  path: '/docs/guide.md',
  title: 'User Guide',
  content: 'How to use the system...',
  tags: ['documentation', 'guide'],
  metadata: { author: '[email protected]' }
});

List Documents

// Get all documents
const allDocs = await db.listAll();

// With pagination
const docs = await db.listAll({ limit: 50, offset: 100 });

Database Health

// 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

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

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

interface SearchResult {
  document: Document;
  score: number;
  content_preview: string;
}

QueryResult

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:

<!-- 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

npm run build

Testing

npm test

Linting

npm run lint
npm run lint:fix

Formatting

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