blendsdk
v5.42.0
Published
Enterprise-grade TypeScript SDK for web applications, database operations, caching, pub/sub, email, i18n, and code generation
Maintainers
Readme
blendsdk
Enterprise-grade TypeScript SDK for web applications, database operations, caching, pub/sub, email, i18n, and code generation.
Installation
npm install blendsdkAvailable Modules
| Module | Import | Description | Peer Deps Required |
| --- | --- | --- | --- |
| stdlib | blendsdk/stdlib | Type guards, utilities, helpers | — |
| cmdline | blendsdk/cmdline | CLI argument parser | — |
| expression | blendsdk/expression | Immutable SQL WHERE clause builder | — |
| dbcore | blendsdk/dbcore | Database abstractions, CRUD statement builders | — |
| postgresql | blendsdk/postgresql | PostgreSQL client + connection pooling | pg, yesql |
| webafx | blendsdk/webafx | Express 5 web framework with DI, plugins, routing | express, cors, helmet, cookie-parser |
| webafx-cache | blendsdk/webafx-cache | Caching + pub/sub (Redis and in-memory backends) | ioredis |
| webafx-mailer | blendsdk/webafx-mailer | Email sending (SMTP and in-memory backends) | nodemailer |
| webafx-auth | blendsdk/webafx-auth | Token validation plugin (JWT/OIDC) | jose |
| i18n | blendsdk/i18n | Internationalization core (Translator, catalogs) | — |
| i18n-node | blendsdk/i18n-node | i18n Node.js sources (JSON files, content files) | — |
| webafx-i18n | blendsdk/webafx-i18n | i18n webafx plugin (locale resolution) | — |
| codegen | blendsdk/codegen | Code generators (TypeScript, Zod, OpenAPI, SQL) | pg, postgres-array |
Quick Start
Web API with Express 5
import { WebApplication, BaseController, RouteDefinition } from "blendsdk/webafx";
// Define a controller with routes
class HelloController extends BaseController {
routes(): RouteDefinition[] {
return [
this.route()
.get("/hello")
.handle(async (_req, res) => {
this.ok(res, { message: "Hello from BlendSDK!" });
}),
];
}
}
// Create the application and register the controller
const app = new WebApplication({
PORT: 3000,
ENV_MODE: "development",
});
app.registerController("/api", HelloController);
const shutdown = await app.start();
// Server running → GET /api/hello returns { success: true, data: { message: "Hello from BlendSDK!" } }SQL Expression Building
import { query } from "blendsdk/expression";
// Build a type-safe WHERE clause
const filter = query()
.where("status").equals("active")
.and("age").greaterThanOrEqual(18);
// Compile to parameterized SQL
const { sql, params } = filter.compile();
// sql: "status = :p1 AND age >= :p2"
// params: { p1: "active", p2: 18 }
// Nested conditions with grouping
const advanced = query()
.where("status").equals("active")
.and(q => q
.where("age").greaterThan(21)
.or("verified").equals(true)
)
.compile();
// sql: "status = :p1 AND (age > :p2 OR verified = :p3)"
// params: { p1: "active", p2: 21, p3: true }CLI Argument Parser
import { CommandLineParser } from "blendsdk/cmdline";
const cli = new CommandLineParser({ name: "my-cli", version: "1.0.0" });
cli.addCommand({
name: "deploy",
description: "Deploy the application",
options: [
{
name: "environment",
short: "e",
type: "string",
required: true,
choices: ["dev", "staging", "production"],
},
{
name: "verbose",
short: "v",
type: "boolean",
description: "Verbose output",
},
],
handler: async (params) => {
console.log(`Deploying to ${params.environment}...`);
},
});
await cli.execute();
// Usage: my-cli deploy --environment=staging --verboseDatabase CRUD Operations
import { Database } from "blendsdk/dbcore";
// Insert with returning clause
const user = await db
.insert<{ name: string; email: string }>("users")
.values({ name: "Alice", email: "[email protected]" })
.returning("*")
.execute();
// Update with filter
await db
.update<{ name: string }, { id: number }>("users")
.values({ name: "Bob" })
.filter({ id: 1 })
.returning("*")
.execute();
// Delete with expression filter
await db
.delete<{ status: string }>("users")
.filterByExpression(q => q.where("status").equals("inactive"))
.execute();Caching
import { MemoryCacheProvider } from "blendsdk/webafx-cache";
const cache = new MemoryCacheProvider({
rootKey: "MyApp",
defaultTTL: 300, // 5 minutes
});
// Simple set/get with type safety
await cache.set("user:1", { name: "Alice", role: "admin" });
const user = await cache.get<{ name: string; role: string }>("user:1");
// Cache-aside pattern (getOrSet)
const product = await cache.getOrSet(
"product:42",
async () => {
return await fetchProductFromDatabase(42);
},
60, // TTL in seconds
);
// Pattern-based deletion
await cache.deletePattern("user:*"); // Remove all user cache entriesPub/Sub Messaging
import { MemoryPubSubProvider } from "blendsdk/webafx-cache";
const pubsub = new MemoryPubSubProvider();
// Subscribe to a specific channel with typed messages
await pubsub.subscribe<{ id: number; total: number }>("order:new", (msg) => {
console.log(`New order on ${msg.channel}:`, msg.data);
});
// Pattern subscription (wildcard matching)
await pubsub.psubscribe("order:*", (msg) => {
console.log(`Order event [${msg.pattern}] on ${msg.channel}`);
});
// Publish returns the number of receivers
const receiverCount = await pubsub.publish("order:new", { id: 1, total: 99.99 });Internationalization
import { Translator } from "blendsdk/i18n";
const translator = new Translator({
defaultLocale: "en",
catalog: {
greeting: { en: "Hello ${name}", nl: "Hallo ${name}" },
farewell: { en: "Goodbye", nl: "Tot ziens" },
book: {
en: ["${count} book", "${count} books"],
nl: ["${count} boek", "${count} boeken"],
},
},
});
translator.translate("greeting", "en", { name: "Alice" }); // "Hello Alice"
translator.translate("greeting", "nl", { name: "Alice" }); // "Hallo Alice"
translator.translate("book", "en", { count: 1 }); // "1 book"
translator.translate("book", "en", { count: 5 }); // "5 books"
translator.translate("farewell", "en_GB"); // "Goodbye" (falls back to "en")Utilities
import { isNullOrUndef, isString } from "blendsdk/stdlib";
const value: unknown = getUserInput();
if (!isNullOrUndef(value) && isString(value)) {
console.log("Got a string:", value);
}Peer Dependencies
Install only the peer dependencies for the modules you use:
# Web framework (webafx)
npm install express cors helmet cookie-parser
# PostgreSQL database (postgresql, codegen)
npm install pg yesql
# Redis caching + pub/sub (webafx-cache)
npm install ioredis
# Email sending (webafx-mailer)
npm install nodemailer
# Authentication — JWT/OIDC (webafx-auth)
npm install jose
# Code generation (codegen)
npm install pg postgres-arrayRequirements
- Node.js >= 22.0.0
- TypeScript >= 5.6.0 (peer dependency)
- ESM only — this package uses
"type": "module"
