@adfharrison1/go-db-typescript-sdk
v1.0.1
Published
TypeScript SDK for go-db document database API
Maintainers
Readme
go-db TypeScript SDK
A type-safe TypeScript SDK for the go-db document database API. Define your data schemas once and get full type inference, compile-time validation, and intelligent autocomplete for all database operations.
✨ Key Features
- 🎯 Fully Type-Safe: Define your schema once, get type safety everywhere
- 🚀 Zero Runtime Cost: Types disappear at compile time, zero performance overhead
- 🔍 Intelligent Autocomplete: IDE knows your collections and fields
- ⚡ Compile-Time Validation: Catch errors before they reach production
- 📦 Zero Dependencies: Built on top of axios for HTTP requests
- 🔄 Batch Operations: Efficient bulk insert and update operations
- 🌊 Streaming Support: Handle large result sets efficiently
🚀 Quick Start
1. Install
yarn add @adfharrison1/go-db-typescript-sdk
# or
npm install @adfharrison1/go-db-typescript-sdk2. Define Your Schema
import { createClient } from '@adfharrison1/go-db-typescript-sdk';
// Define your application's data types
type User = {
_id?: string; // Auto-generated by database
name: string;
age: number;
email: string;
active: boolean;
profile?: {
bio: string;
location: string;
};
};
type Product = {
_id?: string; // Auto-generated by database
title: string;
price: number;
category: string;
inStock: boolean;
};
// Define your database schema
type MySchema = {
users: User;
products: Product;
};
// Create a type-safe client
const db = createClient<MySchema>({
baseURL: 'http://localhost:8080',
timeout: 30000,
});3. Enjoy Full Type Safety
// ✅ TypeScript knows the exact structure
const user = await db.insert('users', {
name: 'John Doe', // ✅ Must be string
age: 30, // ✅ Must be number
email: '[email protected]', // ✅ Must be string
active: true, // ✅ Must be boolean
profile: {
// ✅ Optional nested object
bio: 'Developer',
location: 'SF',
},
});
// ✅ TypeScript knows user is User & { _id: string }
console.log(user._id); // Auto-generated ID
// ✅ Type-safe queries with filters
const activeUsers = await db.find('users', {
where: {
active: true, // ✅ TypeScript knows this should be boolean
age: 25, // ✅ TypeScript knows this should be number
},
select: ['name', 'email'] as const, // ✅ Only valid field names
limit: 10,
});
// ✅ TypeScript knows activeUsers is Array<Pick<User, 'name' | 'email'>>
activeUsers.forEach((u) => {
console.log(`${u.name}: ${u.email}`); // ✅ Full type safety
// u.age would cause TypeScript error - not selected!
});🎯 Type-Safe Operations
Document CRUD
// Insert - TypeScript enforces correct structure
const user = await db.insert('users', {
name: 'Jane Smith',
age: 28,
email: '[email protected]',
active: true,
});
// Get by ID - Returns User | null
const found = await db.getById('users', user._id!);
// Update - Only valid fields and types allowed
const updated = await db.updateById('users', user._id!, {
age: 29, // ✅ TypeScript knows this should be number
active: false, // ✅ TypeScript knows this should be boolean
});
// Delete
await db.deleteById('users', user._id!);Type-Safe Queries
// Find with filters - TypeScript validates field names and types
const results = await db.find('users', {
where: {
active: true, // ✅ Must be boolean
age: { $gte: 18 }, // ✅ Must be number
email: '[email protected]', // ✅ Must be string
},
select: ['name', 'email', 'age'] as const, // ✅ Only valid fields
limit: 10,
});
// TypeScript knows results is Array<Pick<User, 'name' | 'email' | 'age'>>Batch Operations
// Batch insert - Type-safe document arrays
const users = await db.batchInsert('users', [
{ name: 'User 1', age: 25, email: '[email protected]', active: true },
{ name: 'User 2', age: 30, email: '[email protected]', active: false },
]);
// Batch update - Type-safe operations
await db.batchUpdate('users', [
{ id: users.documents[0]._id!, updates: { active: false } },
{ id: users.documents[1]._id!, updates: { age: 31 } },
]);Indexing
// Create indexes - TypeScript validates field names
await db.createIndex('users', 'email'); // ✅ Valid field
await db.createIndex('users', 'age'); // ✅ Valid field
// await db.createIndex('users', 'invalid'); // ❌ TypeScript error!
// List indexes
const indexes = await db.getIndexes('users');
console.log(indexes.indexes); // ['_id', 'email', 'age']🔒 Compile-Time Validation
TypeScript catches errors at compile time:
// ❌ Invalid collection name
await db.getById('invalid_collection', 'id'); // TypeScript error!
// ❌ Invalid field in insert
await db.insert('users', {
name: 'John',
invalidField: 'value', // TypeScript error!
});
// ❌ Wrong type for field
await db.insert('users', {
name: 'John',
age: 'thirty', // TypeScript error - should be number!
});
// ❌ Invalid field in select
await db.find('users', {
select: ['name', 'invalid_field'], // TypeScript error!
});
// ❌ Invalid field in where clause
await db.find('users', {
where: {
invalidField: 'value', // TypeScript error!
},
});
// ❌ Wrong type in where clause
await db.find('users', {
where: {
age: 'old', // TypeScript error - should be number!
},
});🏗️ Advanced Usage
Complex Schemas
type Order = {
_id?: string;
userId: string;
total: number;
status: 'pending' | 'completed' | 'cancelled';
items: Array<{
productId: string;
quantity: number;
price: number;
}>;
createdAt: string;
metadata?: {
notes: string;
priority: 'low' | 'medium' | 'high';
};
};
type MySchema = {
users: User;
products: Product;
orders: Order;
};
const db = createClient<MySchema>({ baseURL: 'http://localhost:8080' });
// Full type safety for complex operations
const order = await db.insert('orders', {
userId: user._id!,
total: 99.99,
status: 'pending', // ✅ Must be one of the allowed values
items: [
{
productId: product._id!,
quantity: 1,
price: 99.99,
},
],
createdAt: new Date().toISOString(),
metadata: {
notes: 'Rush order',
priority: 'high', // ✅ Must be one of the allowed values
},
});Streaming Support
// Type-safe streaming
const stream = await db.findWithStream('users', {
active: true,
});
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
// value is typed as User
console.log(value.name); // ✅ TypeScript knows this is string
}Health Checks
const health = await db.health();
console.log(health.status); // 'healthy'📚 API Reference
Client Creation
import { createClient, GoDBClient } from '@adfharrison1/go-db-typescript-sdk';
// Factory function (recommended)
const db = createClient<MySchema>({
baseURL: 'http://localhost:8080',
timeout: 30000,
});
// Direct instantiation
const db = new GoDBClient<MySchema>({
baseURL: 'http://localhost:8080',
timeout: 30000,
});Configuration
interface GoDBClientConfig {
baseURL?: string; // Default: 'http://localhost:8080'
timeout?: number; // Default: 30000ms
headers?: Record<string, string>; // Additional headers
}Available Methods
All methods are fully type-safe based on your schema:
insert<K>(collection: K, doc: Omit<S[K], '_id'>): Promise<S[K]>getById<K>(collection: K, id: string): Promise<S[K] | null>find<K, Sel>(collection: K, opts?: FindOptions<S[K], Sel>): Promise<Array<Select<S[K], Sel>>>updateById<K>(collection: K, id: string, updates: Partial<Omit<S[K], '_id'>>): Promise<S[K]>replaceById<K>(collection: K, id: string, doc: Omit<S[K], '_id'>): Promise<S[K]>deleteById<K>(collection: K, id: string): Promise<void>batchInsert<K>(collection: K, docs: Array<Omit<S[K], '_id'>>): Promise<BatchResponse<S[K]>>batchUpdate<K>(collection: K, operations: BatchUpdateOps<S[K]>): Promise<BatchUpdateResponse<S[K]>>createIndex<K>(collection: K, field: keyof S[K]): Promise<IndexResponse>getIndexes<K>(collection: K): Promise<IndexListResponse>findWithStream<K>(collection: K, filters: Partial<S[K]>): Promise<ReadableStream<S[K]>>health(): Promise<HealthResponse>
🛠️ Development
Building
yarn buildDevelopment Mode
yarn devType Checking
yarn tsc --noEmit🎯 Why This Approach?
Traditional Approach (❌)
// No type safety - errors at runtime
const user = await client.insert('users', {
name: 'John',
age: 'thirty', // Oops! Wrong type, but no error until runtime
invalidField: 'value', // Oops! Invalid field, but no error until runtime
});
const results = await client.find('users', {
select: ['name', 'invalid_field'], // Oops! Invalid field, but no error until runtime
});Our Type-Safe Approach (✅)
// Full type safety - errors at compile time
const user = await db.insert('users', {
name: 'John',
age: 30, // ✅ TypeScript enforces correct type
// invalidField: 'value', // ❌ TypeScript error at compile time!
});
const results = await db.find('users', {
select: ['name', 'email'], // ✅ TypeScript validates field names
});📄 License
MIT License - see LICENSE file for details.
🤝 Contributing
Contributions are welcome! Please see the main project repository for contribution guidelines.
🆘 Support
For issues and questions, please visit the GitHub repository.
