blendsdk 5.34.0 → 5.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +169 -17
  2. package/package.json +14 -14
package/README.md CHANGED
@@ -35,20 +35,31 @@ npm install blendsdk
35
35
  ### Web API with Express 5
36
36
 
37
37
  ```typescript
38
- import { WebApplication, RouteBuilder } from "blendsdk/webafx";
38
+ import { WebApplication, BaseController, RouteDefinition } from "blendsdk/webafx";
39
+
40
+ // Define a controller with routes
41
+ class HelloController extends BaseController {
42
+ routes(): RouteDefinition[] {
43
+ return [
44
+ this.route()
45
+ .get("/hello")
46
+ .handle(async (_req, res) => {
47
+ this.ok(res, { message: "Hello from BlendSDK!" });
48
+ }),
49
+ ];
50
+ }
51
+ }
39
52
 
53
+ // Create the application and register the controller
40
54
  const app = new WebApplication({
41
- port: 3000,
42
- name: "my-api",
55
+ PORT: 3000,
56
+ ENV_MODE: "development",
43
57
  });
44
58
 
45
- app.route(
46
- RouteBuilder.get("/hello").handler((_req, res) => {
47
- res.json({ message: "Hello from BlendSDK!" });
48
- })
49
- );
59
+ app.registerController("/api", HelloController);
50
60
 
51
- await app.start();
61
+ const shutdown = await app.start();
62
+ // Server running → GET /api/hello returns { success: true, data: { message: "Hello from BlendSDK!" } }
52
63
  ```
53
64
 
54
65
  ### SQL Expression Building
@@ -58,16 +69,157 @@ import { query } from "blendsdk/expression";
58
69
 
59
70
  // Build a type-safe WHERE clause
60
71
  const filter = query()
61
- .field("status")
62
- .eq("active")
63
- .and()
64
- .field("age")
65
- .gte(18);
72
+ .where("status").equals("active")
73
+ .and("age").greaterThanOrEqual(18);
66
74
 
67
75
  // Compile to parameterized SQL
68
- const { sql, parameters } = filter.compile();
69
- // sql: "status" = $1 AND "age" >= $2
70
- // parameters: ["active", 18]
76
+ const { sql, params } = filter.compile();
77
+ // sql: "status = :p1 AND age >= :p2"
78
+ // params: { p1: "active", p2: 18 }
79
+
80
+ // Nested conditions with grouping
81
+ const advanced = query()
82
+ .where("status").equals("active")
83
+ .and(q => q
84
+ .where("age").greaterThan(21)
85
+ .or("verified").equals(true)
86
+ )
87
+ .compile();
88
+ // sql: "status = :p1 AND (age > :p2 OR verified = :p3)"
89
+ // params: { p1: "active", p2: 21, p3: true }
90
+ ```
91
+
92
+ ### CLI Argument Parser
93
+
94
+ ```typescript
95
+ import { CommandLineParser } from "blendsdk/cmdline";
96
+
97
+ const cli = new CommandLineParser({ name: "my-cli", version: "1.0.0" });
98
+
99
+ cli.addCommand({
100
+ name: "deploy",
101
+ description: "Deploy the application",
102
+ options: [
103
+ {
104
+ name: "environment",
105
+ short: "e",
106
+ type: "string",
107
+ required: true,
108
+ choices: ["dev", "staging", "production"],
109
+ },
110
+ {
111
+ name: "verbose",
112
+ short: "v",
113
+ type: "boolean",
114
+ description: "Verbose output",
115
+ },
116
+ ],
117
+ handler: async (params) => {
118
+ console.log(`Deploying to ${params.environment}...`);
119
+ },
120
+ });
121
+
122
+ await cli.execute();
123
+ // Usage: my-cli deploy --environment=staging --verbose
124
+ ```
125
+
126
+ ### Database CRUD Operations
127
+
128
+ ```typescript
129
+ import { Database } from "blendsdk/dbcore";
130
+
131
+ // Insert with returning clause
132
+ const user = await db
133
+ .insert<{ name: string; email: string }>("users")
134
+ .values({ name: "Alice", email: "alice@example.com" })
135
+ .returning("*")
136
+ .execute();
137
+
138
+ // Update with filter
139
+ await db
140
+ .update<{ name: string }, { id: number }>("users")
141
+ .values({ name: "Bob" })
142
+ .filter({ id: 1 })
143
+ .returning("*")
144
+ .execute();
145
+
146
+ // Delete with expression filter
147
+ await db
148
+ .delete<{ status: string }>("users")
149
+ .filterByExpression(q => q.where("status").equals("inactive"))
150
+ .execute();
151
+ ```
152
+
153
+ ### Caching
154
+
155
+ ```typescript
156
+ import { MemoryCacheProvider } from "blendsdk/webafx-cache";
157
+
158
+ const cache = new MemoryCacheProvider({
159
+ rootKey: "MyApp",
160
+ defaultTTL: 300, // 5 minutes
161
+ });
162
+
163
+ // Simple set/get with type safety
164
+ await cache.set("user:1", { name: "Alice", role: "admin" });
165
+ const user = await cache.get<{ name: string; role: string }>("user:1");
166
+
167
+ // Cache-aside pattern (getOrSet)
168
+ const product = await cache.getOrSet(
169
+ "product:42",
170
+ async () => {
171
+ return await fetchProductFromDatabase(42);
172
+ },
173
+ 60, // TTL in seconds
174
+ );
175
+
176
+ // Pattern-based deletion
177
+ await cache.deletePattern("user:*"); // Remove all user cache entries
178
+ ```
179
+
180
+ ### Pub/Sub Messaging
181
+
182
+ ```typescript
183
+ import { MemoryPubSubProvider } from "blendsdk/webafx-cache";
184
+
185
+ const pubsub = new MemoryPubSubProvider();
186
+
187
+ // Subscribe to a specific channel with typed messages
188
+ await pubsub.subscribe<{ id: number; total: number }>("order:new", (msg) => {
189
+ console.log(`New order on ${msg.channel}:`, msg.data);
190
+ });
191
+
192
+ // Pattern subscription (wildcard matching)
193
+ await pubsub.psubscribe("order:*", (msg) => {
194
+ console.log(`Order event [${msg.pattern}] on ${msg.channel}`);
195
+ });
196
+
197
+ // Publish returns the number of receivers
198
+ const receiverCount = await pubsub.publish("order:new", { id: 1, total: 99.99 });
199
+ ```
200
+
201
+ ### Internationalization
202
+
203
+ ```typescript
204
+ import { Translator } from "blendsdk/i18n";
205
+
206
+ const translator = new Translator({
207
+ defaultLocale: "en",
208
+ catalog: {
209
+ greeting: { en: "Hello ${name}", nl: "Hallo ${name}" },
210
+ farewell: { en: "Goodbye", nl: "Tot ziens" },
211
+ book: {
212
+ en: ["${count} book", "${count} books"],
213
+ nl: ["${count} boek", "${count} boeken"],
214
+ },
215
+ },
216
+ });
217
+
218
+ translator.translate("greeting", "en", { name: "Alice" }); // "Hello Alice"
219
+ translator.translate("greeting", "nl", { name: "Alice" }); // "Hallo Alice"
220
+ translator.translate("book", "en", { count: 1 }); // "1 book"
221
+ translator.translate("book", "en", { count: 5 }); // "5 books"
222
+ translator.translate("farewell", "en_GB"); // "Goodbye" (falls back to "en")
71
223
  ```
72
224
 
73
225
  ### Utilities
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blendsdk",
3
- "version": "5.34.0",
3
+ "version": "5.35.0",
4
4
  "description": "Enterprise-grade TypeScript SDK for web applications, database operations, caching, pub/sub, email, i18n, and code generation",
5
5
  "type": "module",
6
6
  "engines": {
@@ -74,21 +74,21 @@
74
74
  "prepack": "npm run build"
75
75
  },
76
76
  "dependencies": {
77
- "zod": "^4.0.0"
77
+ "zod": "^4.3.6"
78
78
  },
79
79
  "devDependencies": {
80
- "@blendsdk/stdlib": "5.34.0",
81
- "@blendsdk/cmdline": "5.34.0",
82
- "@blendsdk/expression": "5.34.0",
83
- "@blendsdk/dbcore": "5.34.0",
84
- "@blendsdk/postgresql": "5.34.0",
85
- "@blendsdk/webafx": "5.34.0",
86
- "@blendsdk/webafx-cache": "5.34.0",
87
- "@blendsdk/webafx-mailer": "5.34.0",
88
- "@blendsdk/webafx-auth": "5.34.0",
89
- "@blendsdk/i18n": "5.34.0",
90
- "@blendsdk/webafx-i18n": "5.34.0",
91
- "@blendsdk/codegen": "5.34.0"
80
+ "@blendsdk/stdlib": "5.35.0",
81
+ "@blendsdk/cmdline": "5.35.0",
82
+ "@blendsdk/expression": "5.35.0",
83
+ "@blendsdk/dbcore": "5.35.0",
84
+ "@blendsdk/postgresql": "5.35.0",
85
+ "@blendsdk/webafx": "5.35.0",
86
+ "@blendsdk/webafx-cache": "5.35.0",
87
+ "@blendsdk/webafx-mailer": "5.35.0",
88
+ "@blendsdk/webafx-auth": "5.35.0",
89
+ "@blendsdk/i18n": "5.35.0",
90
+ "@blendsdk/webafx-i18n": "5.35.0",
91
+ "@blendsdk/codegen": "5.35.0"
92
92
  },
93
93
  "peerDependencies": {
94
94
  "typescript": "^5.6.0",