@sihle.dev/yugo-kit-core
v0.1.34
Published
> **Enterprise-grade TypeScript framework** for building scalable applications with database operations, payments, analytics, and more.
Downloads
7
Readme
🚀 Yugo Kit Core
Enterprise-grade TypeScript framework for building scalable applications with database operations, payments, analytics, and more.
📋 Table of Contents
- Overview
- Features
- Quick Start
- Core Concepts
- Database Operations
- Payment Integration
- Analytics & Reporting
- Email & Workflows
- Authentication
- Caching & Queues
- Production Features
- API Reference
- Examples
- Contributing
🌟 Overview
Yugo Kit Core is a comprehensive TypeScript framework that provides enterprise-grade tools for building scalable applications. It combines type-safe database operations, payment processing, analytics, email workflows, and production-ready features into a unified, developer-friendly package.
Key Benefits
- Type Safety: Full TypeScript support with compile-time type checking
- Database Agnostic: Support for PostgreSQL, PGlite, and connection pooling
- Payment Ready: Built-in Paystack and Yoco integration
- Analytics Built-in: 65+ pre-built analytics views and custom reporting
- Production Ready: Health checks, monitoring, and deployment tools
- Developer Experience: Intuitive API with comprehensive error handling
✨ Features
🗄️ Database Operations
- Type-safe queries with QueryBuilder and MutationBuilder
- Connection pooling for high-performance applications
- Migration management with Drizzle ORM
- Batch operations for bulk data processing
- Query optimization with built-in performance tools
💳 Payment Integration
- Multi-provider support: Paystack (ZAR/NGN) and Yoco (ZAR)
- Subscription management with automatic billing
- Webhook handling for real-time payment events
- Payment analytics and reporting
- Error handling and retry mechanisms
📊 Analytics & Reporting
- 65+ pre-built views for common business metrics
- Custom analytics with flexible query building
- Real-time dashboards with performance optimization
- Data aggregation and statistical functions
- Export capabilities for reports
📧 Email & Workflows
- Resend integration for reliable email delivery
- Template system with dynamic content
- Scheduled emails and workflow automation
- Email analytics and delivery tracking
- Multi-format support (HTML, text, attachments)
🔐 Authentication
- Flexible auth system with multiple providers
- Role-based access control (RBAC)
- Session management with secure tokens
- OAuth integration ready
- Custom auth schemas support
⚡ Performance & Caching
- Redis integration for high-speed caching
- Message queues for background processing
- Connection pooling for database optimization
- Query caching with intelligent invalidation
- Performance monitoring and metrics
🏭 Production Features
- Health checks and readiness probes
- Monitoring integration with Prometheus/Grafana
- Error tracking and logging
- Rate limiting and security middleware
- Deployment tools for Docker/Kubernetes
🚀 Quick Start
Installation
npm install @sihle.dev/yugo-kit-core
# or
bun add @sihle.dev/yugo-kit-coreBasic Setup
import { YugoPGlite, QueryBuilder, MutationBuilder } from '@sihle.dev/yugo-kit-core';
import { PGlite } from '@electric-sql/pglite';
// Initialize database
const pglite = new PGlite();
await pglite.init();
// Create Yugo client
const yugo = YugoPGlite(pglite);
// Define your schema
const users = pgTable("users", {
id: serial("id").primaryKey(),
name: text("name").notNull(),
email: text("email").notNull().unique(),
createdAt: timestamp("created_at").defaultNow(),
});
// Type-safe queries
const allUsers = await yugo.Database.get({
tableName: "users",
request: {
query: new QueryBuilder()
.select(["id", "name", "email"])
.orderBy({ createdAt: "desc" })
.limit(10)
}
});
// Type-safe mutations
const newUser = await yugo.Database.create({
tableName: "users",
data: {
name: "John Doe",
email: "[email protected]"
}
});🧠 Core Concepts
YugoClient
The main entry point that provides access to all Yugo Kit features:
const yugo = YugoPGlite(pglite, {
plugins: [/* optional plugins */],
middleware: [/* optional middleware */]
});
// Access different services
yugo.Database // Database operations
yugo.Payments // Payment processing
yugo.Analytics // Analytics and reporting
yugo.Email // Email services
yugo.Auth // Authentication
yugo.Cache // Caching
yugo.Queue // Message queuesQueryBuilder & MutationBuilder
Type-safe database operations with fluent API:
// Complex queries
const results = await yugo.Database.get({
tableName: "orders",
request: {
query: new QueryBuilder()
.select(["id", "total", "status"])
.where({
status: { $in: ["pending", "processing"] },
total: { $gte: 100 }
})
.join("users", { "orders.user_id": "users.id" })
.orderBy({ createdAt: "desc" })
.limit(20)
}
});
// Batch operations
const mutations = new MutationBuilder()
.insert("users", [
{ name: "Alice", email: "[email protected]" },
{ name: "Bob", email: "[email protected]" }
])
.update("orders", { status: "shipped" }, { id: { $in: [1, 2, 3] } });
await yugo.Database.batch(mutations);🗄️ Database Operations
Connection Types
Yugo Kit supports multiple database connection types:
// PGlite (local development)
import { YugoPGlite } from '@sihle.dev/yugo-kit-core';
const yugo = YugoPGlite(pglite);
// PostgreSQL (production)
import { YugoPostgres } from '@sihle.dev/yugo-kit-core';
const yugo = YugoPostgres('postgresql://user:pass@localhost:5432/db');
// Connection pooling
import { YugoPostgres } from '@sihle.dev/yugo-kit-core';
const yugo = YugoPostgres('postgresql://user:pass@localhost:5432/db', {
poolConfig: {
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
}
});Advanced Queries
// Aggregations
const analytics = await yugo.Database.get({
tableName: "orders",
request: {
query: new QueryBuilder()
.select([
"status",
{ $count: "total_orders" },
{ $sum: "total" }
])
.groupBy(["status"])
.having({ total: { $gte: 1000 } })
}
});
// Subqueries
const highValueCustomers = await yugo.Database.get({
tableName: "users",
request: {
query: new QueryBuilder()
.where({
id: {
$in: new QueryBuilder()
.select(["user_id"])
.from("orders")
.where({ total: { $gte: 500 } })
}
})
}
});💳 Payment Integration
Setup Payment Providers
// Configure payment providers
const yugo = YugoPGlite(pglite, {
payments: {
paystack: {
secretKey: process.env.PAYSTACK_SECRET_KEY,
publicKey: process.env.PAYSTACK_PUBLIC_KEY,
},
yoco: {
secretKey: process.env.YOCO_SECRET_KEY,
publicKey: process.env.YOCO_PUBLIC_KEY,
}
}
});Process Payments
// Initialize payment
const payment = await yugo.Payments.initialize({
amount: 5000, // 50.00 in cents
currency: "ZAR",
email: "[email protected]",
reference: "order_123",
provider: "paystack",
metadata: {
order_id: "123",
customer_id: "456"
}
});
// Verify payment
const verification = await yugo.Payments.verify({
reference: payment.reference,
provider: "paystack"
});
// Create subscription
const subscription = await yugo.Payments.createSubscription({
customer: "customer_123",
plan: "plan_monthly",
provider: "paystack",
startDate: new Date()
});Handle Webhooks
// Webhook handler
app.post('/webhooks/paystack', async (req, res) => {
const event = await yugo.Payments.handleWebhook({
provider: "paystack",
payload: req.body,
signature: req.headers['x-paystack-signature']
});
switch (event.type) {
case 'charge.success':
await processSuccessfulPayment(event.data);
break;
case 'subscription.create':
await activateSubscription(event.data);
break;
}
});📊 Analytics & Reporting
Pre-built Analytics Views
// Get user analytics
const userStats = await yugo.Analytics.getUserAnalytics({
timeRange: "last_30_days",
groupBy: "day"
});
// Get revenue analytics
const revenueStats = await yugo.Analytics.getRevenueAnalytics({
timeRange: "last_12_months",
groupBy: "month",
currency: "ZAR"
});
// Get custom analytics
const customStats = await yugo.Analytics.buildQuery({
tableName: "orders",
metrics: [
{ $count: "total_orders" },
{ $sum: "total" },
{ $avg: "total" }
],
dimensions: ["status", "payment_method"],
filters: {
created_at: { $gte: "2024-01-01" }
}
});Custom Analytics
// Build custom analytics queries
const statement = new AnalyticsStatementBuilder()
.select([
"product_category",
{ $count: "orders" },
{ $sum: "revenue" },
{ $avg: "order_value" }
])
.from("orders")
.join("products", { "orders.product_id": "products.id" })
.where({
created_at: { $gte: "2024-01-01" },
status: "completed"
})
.groupBy(["product_category"])
.orderBy({ revenue: "desc" });
const results = await yugo.Analytics.execute(statement);📧 Email & Workflows
Send Emails
// Configure email service
const yugo = YugoPGlite(pglite, {
email: {
resend: {
apiKey: process.env.RESEND_API_KEY
}
}
});
// Send simple email
await yugo.Email.send({
to: "[email protected]",
subject: "Welcome to our platform!",
html: "<h1>Welcome!</h1><p>Thank you for joining us.</p>"
});
// Send with template
await yugo.Email.sendTemplate({
to: "[email protected]",
templateId: "welcome-email",
data: {
name: "John Doe",
activationLink: "https://example.com/activate"
}
});
// Schedule email
await yugo.Email.schedule({
to: "[email protected]",
subject: "Follow-up",
html: "<p>How are you finding our service?</p>",
sendAt: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 hours from now
});Email Workflows
// Create email workflow
const workflow = await yugo.Email.createWorkflow({
name: "onboarding",
triggers: ["user.signup"],
steps: [
{
type: "email",
template: "welcome",
delay: 0
},
{
type: "email",
template: "tutorial",
delay: 24 * 60 * 60 * 1000 // 24 hours
},
{
type: "email",
template: "feedback",
delay: 7 * 24 * 60 * 60 * 1000 // 7 days
}
]
});🔐 Authentication
Setup Authentication
// Configure auth service
const yugo = YugoPGlite(pglite, {
auth: {
secret: process.env.JWT_SECRET,
expiresIn: "7d",
refreshTokenExpiresIn: "30d"
}
});
// Create user
const user = await yugo.Auth.createUser({
email: "[email protected]",
password: "securepassword",
name: "John Doe"
});
// Authenticate user
const session = await yugo.Auth.authenticate({
email: "[email protected]",
password: "securepassword"
});
// Verify token
const payload = await yugo.Auth.verifyToken(session.token);
// Refresh token
const newSession = await yugo.Auth.refreshToken(session.refreshToken);Role-based Access Control
// Create roles and permissions
await yugo.Auth.createRole({
name: "admin",
permissions: ["users.read", "users.write", "payments.read"]
});
await yugo.Auth.assignRole({
userId: user.id,
roleName: "admin"
});
// Check permissions
const hasPermission = await yugo.Auth.hasPermission({
userId: user.id,
permission: "users.write"
});⚡ Caching & Queues
Caching
// Set cache
await yugo.Cache.set("user:123", userData, 3600); // 1 hour
// Get cache
const userData = await yugo.Cache.get("user:123");
// Cache with tags
await yugo.Cache.setWithTags("user:123", userData, ["users", "profile"]);
// Invalidate by tags
await yugo.Cache.invalidateByTags(["users"]);
// Cache database queries
const cachedUsers = await yugo.Cache.remember("users:active", 300, async () => {
return await yugo.Database.get({
tableName: "users",
request: {
query: new QueryBuilder().where({ status: "active" })
}
});
});Message Queues
// Enqueue job
await yugo.Queue.enqueue("email", {
to: "[email protected]",
subject: "Welcome!",
template: "welcome"
});
// Process jobs
yugo.Queue.process("email", async (job) => {
const { to, subject, template } = job.data;
await yugo.Email.sendTemplate({ to, subject, template });
});
// Schedule delayed job
await yugo.Queue.enqueue("reminder", {
userId: "123",
message: "Don't forget to complete your profile"
}, {
delay: 24 * 60 * 60 * 1000 // 24 hours
});🏭 Production Features
Health Checks
// Create health check endpoint
app.get('/health', async (req, res) => {
const health = await yugo.Production.healthCheck();
if (health.status === 'healthy') {
res.json(health);
} else {
res.status(503).json(health);
}
});
// Custom health checks
const customHealth = await yugo.Production.healthCheck({
checks: [
{
name: "database",
check: async () => {
await yugo.Database.get({
tableName: "users",
request: { query: new QueryBuilder().limit(1) }
});
return { status: "ok" };
}
},
{
name: "payments",
check: async () => {
// Check payment provider connectivity
return { status: "ok" };
}
}
]
});Monitoring & Metrics
// Enable monitoring
const yugo = YugoPGlite(pglite, {
plugins: [
new MonitoringPlugin({
metrics: true,
tracing: true,
logging: true
})
]
});
// Custom metrics
yugo.Production.recordMetric("orders.created", 1);
yugo.Production.recordMetric("payment.success", 1, { provider: "paystack" });
// Performance monitoring
const performance = yugo.Production.startTimer("database.query");
try {
await yugo.Database.get(/* ... */);
} finally {
performance.end();
}Error Handling
// Global error handler
yugo.Production.onError((error) => {
console.error('Yugo Kit Error:', error);
// Send to error tracking service
});
// Custom error types
import { YugoError, YugoValidationError } from '@sihle.dev/yugo-kit-core';
try {
// Your code
} catch (error) {
if (error instanceof YugoValidationError) {
// Handle validation errors
} else if (error instanceof YugoError) {
// Handle Yugo Kit errors
}
}📚 API Reference
YugoClient
The main client class that provides access to all services.
class YugoClient<T> {
// Database operations
get Database(): PGliteRouter<T> | DrizzleRouter<T> | PooledDrizzleRouter<T>
// Payment processing
get Payments(): PaymentsService
// Analytics and reporting
get Analytics(): AnalyticsService<T>
// Email services
get Email(): ResendEmailService
// Authentication
get Auth(): YugoAuthService
// Caching
get Cache(): InMemoryCacheAdapter
// Message queues
get Queue(): MessageQueue<T>
// Production features
get Production(): ProductionManager
}QueryBuilder
Type-safe query building for database operations.
class QueryBuilder {
select(fields: string[] | Record<string, any>): QueryBuilder
where(conditions: Record<string, any>): QueryBuilder
join(table: string, conditions: Record<string, string>): QueryBuilder
orderBy(sort: Record<string, "asc" | "desc">): QueryBuilder
limit(count: number): QueryBuilder
offset(count: number): QueryBuilder
groupBy(fields: string[]): QueryBuilder
having(conditions: Record<string, any>): QueryBuilder
}MutationBuilder
Type-safe mutation building for database operations.
class MutationBuilder {
insert(table: string, data: Record<string, any>[]): MutationBuilder
update(table: string, data: Record<string, any>, where: Record<string, any>): MutationBuilder
delete(table: string, where: Record<string, any>): MutationBuilder
upsert(table: string, data: Record<string, any>): MutationBuilder
}💡 Examples
Complete E-commerce Example
import { YugoPGlite, QueryBuilder, MutationBuilder } from '@sihle.dev/yugo-kit-core';
// Initialize
const yugo = YugoPGlite(pglite, {
payments: {
paystack: { secretKey: process.env.PAYSTACK_SECRET_KEY }
},
email: {
resend: { apiKey: process.env.RESEND_API_KEY }
}
});
// Create order
const order = await yugo.Database.create({
tableName: "orders",
data: {
customer_id: 123,
total: 5000,
status: "pending"
}
});
// Process payment
const payment = await yugo.Payments.initialize({
amount: order.total,
currency: "ZAR",
email: "[email protected]",
reference: `order_${order.id}`,
provider: "paystack"
});
// Send confirmation email
await yugo.Email.sendTemplate({
to: "[email protected]",
templateId: "order-confirmation",
data: { orderId: order.id, total: order.total }
});
// Update analytics
await yugo.Analytics.recordEvent("order.created", {
order_id: order.id,
customer_id: order.customer_id,
total: order.total
});Subscription Management
// Create subscription
const subscription = await yugo.Database.create({
tableName: "subscriptions",
data: {
customer_id: 123,
plan_id: 1,
status: "active",
current_period_start: new Date(),
current_period_end: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
}
});
// Schedule renewal
await yugo.Queue.enqueue("subscription.renew", {
subscriptionId: subscription.id
}, {
delay: 29 * 24 * 60 * 60 * 1000 // 29 days
});
// Process renewal
yugo.Queue.process("subscription.renew", async (job) => {
const { subscriptionId } = job.data;
// Charge customer
const payment = await yugo.Payments.chargeSubscription({
subscriptionId,
provider: "paystack"
});
if (payment.status === "success") {
// Extend subscription
await yugo.Database.update({
tableName: "subscriptions",
data: {
current_period_start: new Date(),
current_period_end: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
},
where: { id: subscriptionId }
});
}
});🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone the repository
git clone https://github.com/your-org/yugo-kit.git
cd yugo-kit
# Install dependencies
bun install
# Run tests
bun test
# Build the package
bun run buildTesting
# Run all tests
bun test
# Run specific test suite
bun test packages/core/src/library/database.test.ts
# Run with coverage
bun test --coverage📄 License
MIT License - see LICENSE for details.
🆘 Support
- Documentation: docs/
- Tutorials: docs/tutorials/
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Built with ❤️ by the glue.africa
