@bloomneo/appkit 1.5.1 โ 1.5.2
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.
- package/AGENTS.md +195 -0
- package/CHANGELOG.md +253 -0
- package/README.md +147 -799
- package/bin/commands/generate.js +7 -7
- package/cookbook/README.md +26 -0
- package/cookbook/api-key-service.ts +106 -0
- package/cookbook/auth-protected-crud.ts +112 -0
- package/cookbook/file-upload-pipeline.ts +113 -0
- package/cookbook/multi-tenant-saas.ts +87 -0
- package/cookbook/real-time-chat.ts +121 -0
- package/dist/auth/auth.d.ts +21 -4
- package/dist/auth/auth.d.ts.map +1 -1
- package/dist/auth/auth.js +56 -44
- package/dist/auth/auth.js.map +1 -1
- package/dist/auth/defaults.d.ts +1 -1
- package/dist/auth/defaults.js +35 -35
- package/dist/cache/cache.d.ts +29 -6
- package/dist/cache/cache.d.ts.map +1 -1
- package/dist/cache/cache.js +72 -44
- package/dist/cache/cache.js.map +1 -1
- package/dist/cache/defaults.js +25 -25
- package/dist/cache/index.d.ts +19 -10
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +21 -18
- package/dist/cache/index.js.map +1 -1
- package/dist/config/defaults.d.ts +1 -1
- package/dist/config/defaults.js +8 -8
- package/dist/config/index.d.ts +3 -3
- package/dist/config/index.js +4 -4
- package/dist/database/adapters/mongoose.js +2 -2
- package/dist/database/adapters/prisma.js +2 -2
- package/dist/database/defaults.d.ts +1 -1
- package/dist/database/defaults.js +4 -4
- package/dist/database/index.js +2 -2
- package/dist/database/index.js.map +1 -1
- package/dist/email/defaults.js +20 -20
- package/dist/error/defaults.d.ts +1 -1
- package/dist/error/defaults.js +12 -12
- package/dist/error/error.d.ts +12 -0
- package/dist/error/error.d.ts.map +1 -1
- package/dist/error/error.js +19 -0
- package/dist/error/error.js.map +1 -1
- package/dist/error/index.d.ts +14 -3
- package/dist/error/index.d.ts.map +1 -1
- package/dist/error/index.js +14 -3
- package/dist/error/index.js.map +1 -1
- package/dist/event/defaults.js +30 -30
- package/dist/logger/defaults.d.ts +1 -1
- package/dist/logger/defaults.js +40 -40
- package/dist/logger/index.d.ts +1 -0
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/logger/logger.d.ts +8 -0
- package/dist/logger/logger.d.ts.map +1 -1
- package/dist/logger/logger.js +13 -3
- package/dist/logger/logger.js.map +1 -1
- package/dist/logger/transports/console.js +1 -1
- package/dist/logger/transports/http.d.ts +1 -1
- package/dist/logger/transports/http.js +1 -1
- package/dist/logger/transports/webhook.d.ts +1 -1
- package/dist/logger/transports/webhook.js +1 -1
- package/dist/queue/defaults.d.ts +2 -2
- package/dist/queue/defaults.js +38 -38
- package/dist/security/defaults.d.ts +1 -1
- package/dist/security/defaults.js +29 -29
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +3 -3
- package/dist/security/security.d.ts +1 -1
- package/dist/security/security.js +4 -4
- package/dist/storage/defaults.js +19 -19
- package/dist/util/defaults.d.ts +1 -1
- package/dist/util/defaults.js +34 -34
- package/dist/util/env.d.ts +35 -0
- package/dist/util/env.d.ts.map +1 -0
- package/dist/util/env.js +50 -0
- package/dist/util/env.js.map +1 -0
- package/dist/util/errors.d.ts +52 -0
- package/dist/util/errors.d.ts.map +1 -0
- package/dist/util/errors.js +82 -0
- package/dist/util/errors.js.map +1 -0
- package/examples/.env.example +80 -0
- package/examples/README.md +16 -0
- package/examples/auth.ts +228 -0
- package/examples/cache.ts +36 -0
- package/examples/config.ts +45 -0
- package/examples/database.ts +69 -0
- package/examples/email.ts +53 -0
- package/examples/error.ts +50 -0
- package/examples/event.ts +42 -0
- package/examples/logger.ts +41 -0
- package/examples/queue.ts +58 -0
- package/examples/security.ts +46 -0
- package/examples/storage.ts +44 -0
- package/examples/util.ts +47 -0
- package/llms.txt +591 -0
- package/package.json +19 -10
- package/src/auth/README.md +850 -0
- package/src/cache/README.md +756 -0
- package/src/config/README.md +604 -0
- package/src/database/README.md +818 -0
- package/src/email/README.md +759 -0
- package/src/error/README.md +660 -0
- package/src/event/README.md +729 -0
- package/src/logger/README.md +435 -0
- package/src/queue/README.md +851 -0
- package/src/security/README.md +612 -0
- package/src/storage/README.md +1008 -0
- package/src/util/README.md +955 -0
- package/bin/templates/backend/docs/APPKIT_CLI.md +0 -507
- package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +0 -61
- package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +0 -2539
package/README.md
CHANGED
|
@@ -5,898 +5,246 @@
|
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
[](https://github.com/bloomneo/appkit)
|
|
7
7
|
|
|
8
|
-
>
|
|
8
|
+
> Minimal, framework-agnostic Node.js toolkit designed for AI agentic backend development.
|
|
9
|
+
> Previously published as `@voilajsx/appkit`. Same code, new home, new namespace.
|
|
10
|
+
> See [migration](#migration) below.
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
> backend development**
|
|
12
|
+
**12 integrated modules. One pattern. Zero config to start, enterprise scaling on demand.**
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## ๐ What Bloomneo AppKit Really Is
|
|
17
|
-
|
|
18
|
-
Bloomneo AppKit is a **complete Node.js development toolkit** that eliminates
|
|
19
|
-
the complexity of building production-ready applications. Instead of juggling
|
|
20
|
-
dozens of libraries and configuration files, you get 12 integrated modules that
|
|
21
|
-
work together seamlessly.
|
|
22
|
-
|
|
23
|
-
### **How Developers Can Leverage AppKit**
|
|
24
|
-
|
|
25
|
-
**๐ฏ For Rapid Development**
|
|
26
|
-
|
|
27
|
-
- **One function per module**: `authClass.get()`, `databaseClass.get()`,
|
|
28
|
-
`securityClass.get()`
|
|
29
|
-
- **Instant setup**: No configuration files, just environment variables
|
|
30
|
-
- **Production patterns**: Enterprise-grade security and scalability built-in
|
|
31
|
-
|
|
32
|
-
**๐๏ธ For Maintainable Architecture**
|
|
33
|
-
|
|
34
|
-
- **Consistent APIs**: Same `{moduleClass}.get()` pattern across all modules
|
|
35
|
-
- **Progressive complexity**: Start simple, scale to enterprise automatically
|
|
36
|
-
- **Type-safe**: Full TypeScript support with intelligent IntelliSense
|
|
37
|
-
|
|
38
|
-
**โก For Performance**
|
|
39
|
-
|
|
40
|
-
- **Smart defaults**: Memory caching, connection pooling, resource management
|
|
41
|
-
- **Auto-scaling**: Modules automatically upgrade (Memory โ Redis โ Database)
|
|
42
|
-
- **Optimized**: Battle-tested patterns for high-throughput applications
|
|
43
|
-
|
|
44
|
-
## ๐ค Enhanced for AI-Driven Development
|
|
45
|
-
|
|
46
|
-
While perfectly designed for human developers, AppKit excels in AI-assisted
|
|
47
|
-
development:
|
|
48
|
-
|
|
49
|
-
- **๐ฏ Predictable Code Generation**: AI agents generate consistent, working
|
|
50
|
-
applications
|
|
51
|
-
- **๐ LLM-Optimized Documentation**: Every function includes clear usage
|
|
52
|
-
patterns
|
|
53
|
-
- **๐ Built-in Best Practices**: Security, scalability, and maintainability by
|
|
54
|
-
default
|
|
55
|
-
- **โ๏ธ Non-Ambiguous APIs**: Clear function signatures prevent common mistakes
|
|
56
|
-
|
|
57
|
-
### **Why This Matters for Developers**
|
|
58
|
-
|
|
59
|
-
| Traditional Approach | Bloomneo AppKit Approach |
|
|
60
|
-
| ----------------------------------------- | --------------------------------------- |
|
|
61
|
-
| Research โ Configure โ Integrate โ Secure | **Import โ Use โ Deploy** |
|
|
62
|
-
| Multiple libraries, version conflicts | **Integrated modules, tested together** |
|
|
63
|
-
| Manual scaling decisions | **Environment-driven auto-scaling** |
|
|
64
|
-
| Security implemented later | **Security enabled by default** |
|
|
65
|
-
| Inconsistent error handling | **Unified error patterns** |
|
|
66
|
-
|
|
67
|
-
## ๐ข Enterprise Benefits
|
|
68
|
-
|
|
69
|
-
### **Progressive Complexity**
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// Day 1: Simple development
|
|
73
|
-
const auth = authClass.get();
|
|
74
|
-
const token = auth.signToken({ userId: 123, role: 'user', level: 'basic' });
|
|
75
|
-
|
|
76
|
-
// Month 6: Multi-tenant (just add environment variable)
|
|
77
|
-
// VOILA_DB_TENANT=auto
|
|
78
|
-
const database = await databaseClass.get(); // Now auto-filtered by tenant
|
|
79
|
-
|
|
80
|
-
// Year 1: Multi-organization enterprise (same code)
|
|
81
|
-
// ORG_ACME=postgresql://acme.aws.com/prod
|
|
82
|
-
const acmeDatabase = await databaseClass.org('acme').get(); // Enterprise scaling
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## ๐ Quick Start
|
|
86
|
-
|
|
87
|
-
**Two Ways to Use AppKit:**
|
|
88
|
-
|
|
89
|
-
**๐ฆ As a Library** - Install AppKit modules into your existing Node.js/Express projects (NestJS, Fastify, Koa, etc.):
|
|
90
|
-
```bash
|
|
91
|
-
npm install @bloomneo/appkit
|
|
92
|
-
```
|
|
93
|
-
Import modules directly: `import { authClass, databaseClass } from '@bloomneo/appkit'`
|
|
94
|
-
|
|
95
|
-
**๐ Complete Microservice Scaffolding** - Use AppKit CLI to generate enterprise-ready backend applications:
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
# Step 1: Install AppKit CLI globally
|
|
99
|
-
npm install -g @bloomneo/appkit
|
|
100
|
-
|
|
101
|
-
# Check if you have the latest version
|
|
102
|
-
npm list -g @bloomneo/appkit
|
|
103
|
-
|
|
104
|
-
# Step 2: Create your app
|
|
105
|
-
appkit generate app myproject
|
|
106
|
-
cd myproject && npm run dev:api
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
**Done.** Your API is running with authentication, database, and enterprise features ready at http://localhost:3000/api
|
|
110
|
-
|
|
111
|
-
### **Add Features Instantly**
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
# Add custom feature
|
|
115
|
-
appkit generate feature product
|
|
116
|
-
|
|
117
|
-
# Add complete authentication system
|
|
118
|
-
appkit generate feature user
|
|
119
|
-
|
|
120
|
-
# Add database-enabled feature
|
|
121
|
-
appkit generate feature order --db
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### **Library Integration Example**
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
# For library usage in existing projects
|
|
128
|
-
npm install @bloomneo/appkit
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
```typescript
|
|
132
|
-
import { authClass } from '@bloomneo/appkit/auth';
|
|
133
|
-
import { databaseClass } from '@bloomneo/appkit/database';
|
|
134
|
-
import { errorClass } from '@bloomneo/appkit/error';
|
|
135
|
-
import { loggerClass } from '@bloomneo/appkit/logger';
|
|
14
|
+
```ts
|
|
15
|
+
import { authClass, databaseClass, errorClass, loggerClass } from '@bloomneo/appkit';
|
|
136
16
|
|
|
137
17
|
const auth = authClass.get();
|
|
138
18
|
const database = await databaseClass.get();
|
|
139
19
|
const error = errorClass.get();
|
|
140
20
|
const logger = loggerClass.get('api');
|
|
141
21
|
|
|
142
|
-
// Protected API endpoint
|
|
143
22
|
app.post(
|
|
144
23
|
'/api/users',
|
|
145
|
-
auth.
|
|
24
|
+
auth.requireLoginToken(), // 1. authenticate the user
|
|
25
|
+
auth.requireUserRoles(['admin.tenant']), // 2. check the role (always chained)
|
|
146
26
|
error.asyncRoute(async (req, res) => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const newUser = await database.user.create({ data: req.body });
|
|
154
|
-
logger.info('User created', { userId: newUser.id });
|
|
155
|
-
|
|
156
|
-
res.json({ user: newUser });
|
|
27
|
+
if (!req.body?.email) throw error.badRequest('Email required');
|
|
28
|
+
const user = await database.user.create({ data: req.body });
|
|
29
|
+
logger.info('User created', { userId: user.id });
|
|
30
|
+
res.json({ user });
|
|
157
31
|
})
|
|
158
32
|
);
|
|
159
33
|
|
|
160
|
-
//
|
|
161
|
-
app.use(error.handleErrors());
|
|
34
|
+
app.use(error.handleErrors()); // last middleware
|
|
162
35
|
```
|
|
163
36
|
|
|
164
|
-
**
|
|
165
|
-
and logging. **Zero configuration needed.**
|
|
166
|
-
|
|
167
|
-
## ๐ ๏ธ AppKit CLI
|
|
168
|
-
|
|
169
|
-
### **Project Generation**
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
# Create complete backend application
|
|
173
|
-
appkit generate app [name]
|
|
174
|
-
|
|
175
|
-
# What you get:
|
|
176
|
-
# โ
TypeScript setup with proper configuration
|
|
177
|
-
# โ
Express server with auto-discovery routing
|
|
178
|
-
# โ
Environment variables with secure random keys
|
|
179
|
-
# โ
Database integration ready
|
|
180
|
-
# โ
Complete documentation included
|
|
181
|
-
# โ
Production-ready npm scripts
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### **Feature Generation**
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
# Basic feature (route + service + types)
|
|
188
|
-
appkit generate feature product
|
|
37
|
+
**Production-ready API with auth, database, error handling, logging. Zero config files.**
|
|
189
38
|
|
|
190
|
-
|
|
191
|
-
appkit generate feature order --db
|
|
192
|
-
|
|
193
|
-
# Complete authentication system (9-role hierarchy)
|
|
194
|
-
appkit generate feature user
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### **Generated Project Structure**
|
|
39
|
+
---
|
|
198
40
|
|
|
199
|
-
|
|
200
|
-
myproject/
|
|
201
|
-
โโโ docs/ # Complete documentation
|
|
202
|
-
โ โโโ APPKIT_CLI.md # CLI reference
|
|
203
|
-
โ โโโ APPKIT_LLM_GUIDE.md # AI integration guide
|
|
204
|
-
โ โโโ APPKIT_COMMENTS_GUIDELINES.md # Code standards
|
|
205
|
-
โโโ src/api/
|
|
206
|
-
โ โโโ server.ts # Main server
|
|
207
|
-
โ โโโ lib/api-router.ts # Auto-discovery routing
|
|
208
|
-
โ โโโ features/ # Feature-based architecture
|
|
209
|
-
โ โโโ welcome/ # Default endpoints
|
|
210
|
-
โ โโโ [your-features]/ # Generated features
|
|
211
|
-
โโโ .env # Secure environment variables
|
|
212
|
-
โโโ package.json # With backend scripts
|
|
213
|
-
โโโ README.md # Project-specific guide
|
|
214
|
-
```
|
|
41
|
+
## ๐ค For AI coding agents โ read these first
|
|
215
42
|
|
|
216
|
-
|
|
43
|
+
Three files at the package root tell agents everything they need to know:
|
|
217
44
|
|
|
218
|
-
|
|
|
219
|
-
|
|
220
|
-
|
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
|
|
|
224
|
-
| 5 | **[Cache](/src/cache/README.md)** | ๐ Data & Communication | Memory โ Redis auto-scaling | `cacheClass.get('namespace')` - Namespace isolation, TTL management, getOrSet pattern |
|
|
225
|
-
| 6 | **[Storage](/src/storage/README.md)** | ๐ Data & Communication | Local โ S3/R2 auto-scaling | `storageClass.get()` - CDN integration, signed URLs, automatic provider detection |
|
|
226
|
-
| 7 | **[Queue](/src/queue/README.md)** | ๐ Data & Communication | Memory โ Redis โ DB scaling | `queueClass.get()` - Background jobs, scheduling, retry logic with exponential backoff |
|
|
227
|
-
| 8 | **[Email](/src/email/README.md)** | ๐ Data & Communication | Console โ SMTP โ Resend | `emailClass.get()` - Templates, multi-provider, automatic strategy selection |
|
|
228
|
-
| 9 | **[Event](/src/event/README.md)** | ๐ Data & Communication | Memory โ Redis distribution | `eventClass.get('namespace')` - Real-time, pub/sub, wildcard patterns (user.\*) |
|
|
229
|
-
| 10 | **[Util](/src/util/README.md)** | ๐ ๏ธ Developer Experience | 12 essential utilities | `utilClass.get()` - Safe property access (get), performance helpers (debounce, chunk) |
|
|
230
|
-
| 11 | **[Config](/src/config/README.md)** | ๐ ๏ธ Developer Experience | Environment variables | `configClass.get()` - Type-safe, UPPER_SNAKE_CASE convention, validation included |
|
|
231
|
-
| 12 | **[Logger](/src/logger/README.md)** | ๐ ๏ธ Developer Experience | Structured logging | `loggerClass.get('component')` - Multi-transport, auto-scaling (Console โ File โ HTTP) |
|
|
45
|
+
| File | Purpose |
|
|
46
|
+
|---|---|
|
|
47
|
+
| **[`AGENTS.md`](./AGENTS.md)** | Rules: always-do, never-do, canonical patterns. Read first. |
|
|
48
|
+
| **[`llms.txt`](./llms.txt)** | Reference: every export, every method, signatures + examples. |
|
|
49
|
+
| **[`examples/`](./examples)** | 12 minimal `.ts` files, one per module. Copy and modify. |
|
|
50
|
+
| **[`cookbook/`](./cookbook)** | Composed recipes for whole patterns (CRUD, multi-tenant, file upload, real-time). |
|
|
232
51
|
|
|
233
|
-
|
|
52
|
+
All four ship inside the npm tarball. AI agents installing `@bloomneo/appkit`
|
|
53
|
+
can read them directly from `node_modules/@bloomneo/appkit/`.
|
|
234
54
|
|
|
235
|
-
|
|
236
|
-
database, security, error handling
|
|
237
|
-
- **๐ Data & Communication (5 modules)**: Data flow and external interactions -
|
|
238
|
-
cache, storage, queue, email, events
|
|
239
|
-
- **๐ ๏ธ Developer Experience (3 modules)**: Development productivity - utilities,
|
|
240
|
-
configuration, logging
|
|
55
|
+
---
|
|
241
56
|
|
|
242
|
-
##
|
|
57
|
+
## ๐ Quick start
|
|
243
58
|
|
|
244
|
-
###
|
|
59
|
+
### As a library (in any Node.js project)
|
|
245
60
|
|
|
246
61
|
```bash
|
|
247
|
-
npm
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### **Production** (Auto-Detection)
|
|
251
|
-
|
|
252
|
-
```bash
|
|
253
|
-
# Set these environment variables - everything scales automatically
|
|
254
|
-
DATABASE_URL=postgresql://prod-db/app # โ Database persistence
|
|
255
|
-
REDIS_URL=redis://prod-cache:6379 # โ Distributed cache/queue
|
|
256
|
-
AWS_S3_BUCKET=prod-assets # โ Cloud storage + CDN
|
|
257
|
-
RESEND_API_KEY=re_production_key # โ Professional email
|
|
258
|
-
VOILA_DB_TENANT=auto # โ Multi-tenant mode
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
**Same code. Different environment. Enterprise features automatically enabled.**
|
|
262
|
-
|
|
263
|
-
## ๐ข Enterprise-Ready Examples
|
|
264
|
-
|
|
265
|
-
### **Multi-Tenant SaaS API**
|
|
266
|
-
|
|
267
|
-
```typescript
|
|
268
|
-
import { authClass } from '@bloomneo/appkit/auth';
|
|
269
|
-
import { databaseClass } from '@bloomneo/appkit/database';
|
|
270
|
-
import { securityClass } from '@bloomneo/appkit/security';
|
|
271
|
-
import { cacheClass } from '@bloomneo/appkit/cache';
|
|
272
|
-
|
|
273
|
-
const auth = authClass.get();
|
|
274
|
-
const database = await databaseClass.get(); // Auto-filtered by tenant
|
|
275
|
-
const security = securityClass.get();
|
|
276
|
-
const cache = cacheClass.get('api');
|
|
277
|
-
|
|
278
|
-
// User endpoint (tenant-isolated)
|
|
279
|
-
app.get(
|
|
280
|
-
'/api/users',
|
|
281
|
-
auth.requireLogin(),
|
|
282
|
-
security.requests(100, 900000), // Rate limiting
|
|
283
|
-
async (req, res) => {
|
|
284
|
-
const users = await cache.getOrSet(
|
|
285
|
-
'users',
|
|
286
|
-
async () => {
|
|
287
|
-
return await database.user.findMany(); // Only current tenant
|
|
288
|
-
},
|
|
289
|
-
300
|
|
290
|
-
);
|
|
291
|
-
|
|
292
|
-
res.json(users);
|
|
293
|
-
}
|
|
294
|
-
);
|
|
295
|
-
|
|
296
|
-
// Admin endpoint (cross-tenant access)
|
|
297
|
-
app.get(
|
|
298
|
-
'/api/admin/analytics',
|
|
299
|
-
auth.requireRole('admin.system'),
|
|
300
|
-
async (req, res) => {
|
|
301
|
-
const dbTenants = await databaseClass.getTenants(); // All tenants
|
|
302
|
-
const stats = await dbTenants.user.groupBy({
|
|
303
|
-
by: ['tenant_id'],
|
|
304
|
-
_count: true,
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
res.json(stats);
|
|
308
|
-
}
|
|
309
|
-
);
|
|
62
|
+
npm install @bloomneo/appkit
|
|
310
63
|
```
|
|
311
64
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
```typescript
|
|
315
|
-
import { eventClass } from '@bloomneo/appkit/event';
|
|
65
|
+
```ts
|
|
316
66
|
import { authClass } from '@bloomneo/appkit/auth';
|
|
317
67
|
import { databaseClass } from '@bloomneo/appkit/database';
|
|
318
68
|
|
|
319
|
-
const events = eventClass.get();
|
|
320
69
|
const auth = authClass.get();
|
|
321
70
|
const database = await databaseClass.get();
|
|
322
|
-
|
|
323
|
-
// Handle user connections
|
|
324
|
-
events.on('user.connected', async (data) => {
|
|
325
|
-
const { userId, socketId } = data;
|
|
326
|
-
|
|
327
|
-
// Join user to their rooms
|
|
328
|
-
await events.emit('socket.join', {
|
|
329
|
-
socketId,
|
|
330
|
-
rooms: [`user:${userId}`, `tenant:${data.tenantId}`],
|
|
331
|
-
});
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
// Handle chat messages
|
|
335
|
-
events.on('message.send', async (data) => {
|
|
336
|
-
const message = await database.message.create({
|
|
337
|
-
data: {
|
|
338
|
-
content: data.content,
|
|
339
|
-
userId: data.userId,
|
|
340
|
-
roomId: data.roomId,
|
|
341
|
-
},
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
// Broadcast to room (tenant-isolated)
|
|
345
|
-
await events.emit('message.broadcast', {
|
|
346
|
-
roomId: data.roomId,
|
|
347
|
-
message: {
|
|
348
|
-
id: message.id,
|
|
349
|
-
content: message.content,
|
|
350
|
-
user: { name: data.userName },
|
|
351
|
-
timestamp: message.createdAt,
|
|
352
|
-
},
|
|
353
|
-
});
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
// REST API integration
|
|
357
|
-
app.post('/api/notifications', auth.requireLogin(), async (req, res) => {
|
|
358
|
-
const user = auth.user(req);
|
|
359
|
-
|
|
360
|
-
// Send real-time notification
|
|
361
|
-
await events.emit('notification.send', {
|
|
362
|
-
userId: user.userId,
|
|
363
|
-
type: 'info',
|
|
364
|
-
message: req.body.message,
|
|
365
|
-
timestamp: new Date(),
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
res.json({ sent: true });
|
|
369
|
-
});
|
|
370
71
|
```
|
|
371
72
|
|
|
372
|
-
###
|
|
73
|
+
### As a complete scaffold (CLI)
|
|
373
74
|
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const storage = storageClass.get();
|
|
381
|
-
const queue = queueClass.get();
|
|
382
|
-
const logger = loggerClass.get('upload');
|
|
383
|
-
const security = securityClass.get();
|
|
75
|
+
```bash
|
|
76
|
+
npm install -g @bloomneo/appkit
|
|
77
|
+
appkit generate app myproject
|
|
78
|
+
cd myproject && npm run dev:api
|
|
79
|
+
```
|
|
384
80
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
'/upload',
|
|
388
|
-
security.requests(10, 60000), // 10 uploads per minute
|
|
389
|
-
async (req, res) => {
|
|
390
|
-
// Sanitize filename
|
|
391
|
-
const safeName = security.input(req.file.originalname);
|
|
392
|
-
const key = `uploads/${Date.now()}-${safeName}`;
|
|
393
|
-
|
|
394
|
-
// Store file (auto-detects Local/S3/R2)
|
|
395
|
-
await storage.put(key, req.file.buffer, {
|
|
396
|
-
contentType: req.file.mimetype,
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
// Queue background processing
|
|
400
|
-
await queue.add('process-image', {
|
|
401
|
-
key,
|
|
402
|
-
userId: req.user.id,
|
|
403
|
-
originalName: req.file.originalname,
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
logger.info('File uploaded', { key, userId: req.user.id });
|
|
407
|
-
|
|
408
|
-
res.json({
|
|
409
|
-
url: storage.url(key),
|
|
410
|
-
key,
|
|
411
|
-
processing: true,
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
);
|
|
81
|
+
โ Production-ready Express API at `http://localhost:3000` with auth, database,
|
|
82
|
+
logging, error handling all wired.
|
|
415
83
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const logger = loggerClass.get('processor');
|
|
419
|
-
|
|
420
|
-
try {
|
|
421
|
-
const buffer = await storage.get(data.key);
|
|
422
|
-
|
|
423
|
-
// Process image (resize, optimize, etc.)
|
|
424
|
-
const processed = await processImage(buffer);
|
|
425
|
-
|
|
426
|
-
// Store processed version
|
|
427
|
-
const processedKey = data.key.replace('.', '-processed.');
|
|
428
|
-
await storage.put(processedKey, processed);
|
|
429
|
-
|
|
430
|
-
logger.info('Image processed', {
|
|
431
|
-
original: data.key,
|
|
432
|
-
processed: processedKey,
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
return { processedKey };
|
|
436
|
-
} catch (error) {
|
|
437
|
-
logger.error('Processing failed', {
|
|
438
|
-
key: data.key,
|
|
439
|
-
error: error.message,
|
|
440
|
-
});
|
|
441
|
-
throw error;
|
|
442
|
-
}
|
|
443
|
-
});
|
|
444
|
-
```
|
|
84
|
+
For full-stack scaffolding (frontend + backend), use [`@bloomneo/bloom`](https://www.npmjs.com/package/@bloomneo/bloom)
|
|
85
|
+
which assembles AppKit + UIKit + FBCA convention into one CLI.
|
|
445
86
|
|
|
446
|
-
|
|
87
|
+
---
|
|
447
88
|
|
|
448
|
-
|
|
89
|
+
## โจ The one rule that matters most
|
|
449
90
|
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
and protected admin routes using Bloomneo AppKit.
|
|
91
|
+
```ts
|
|
92
|
+
const auth = authClass.get(); // ALWAYS .get(), NEVER `new AuthClass()`
|
|
453
93
|
```
|
|
454
94
|
|
|
455
|
-
|
|
95
|
+
Every module follows this exact pattern. There are no exceptions, no
|
|
96
|
+
constructors, no factories with custom names.
|
|
456
97
|
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
import { errorClass } from '@bloomneo/appkit/error';
|
|
460
|
-
import { databaseClass } from '@bloomneo/appkit/database';
|
|
461
|
-
import { loggerClass } from '@bloomneo/appkit/logger';
|
|
462
|
-
|
|
463
|
-
const auth = authClass.get();
|
|
464
|
-
const error = errorClass.get();
|
|
98
|
+
```ts
|
|
99
|
+
const auth = authClass.get();
|
|
465
100
|
const database = await databaseClass.get();
|
|
466
|
-
const
|
|
101
|
+
const error = errorClass.get();
|
|
102
|
+
const cache = cacheClass.get(); // default 'app' namespace
|
|
103
|
+
const userCache = cacheClass.get('users'); // custom namespace
|
|
104
|
+
const logger = loggerClass.get('api'); // component-tagged
|
|
105
|
+
```
|
|
467
106
|
|
|
468
|
-
|
|
469
|
-
app.post(
|
|
470
|
-
'/auth/login',
|
|
471
|
-
error.asyncRoute(async (req, res) => {
|
|
472
|
-
const { email, password } = req.body;
|
|
473
|
-
|
|
474
|
-
if (!email || !password) {
|
|
475
|
-
throw error.badRequest('Email and password required');
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const user = await database.user.findUnique({ where: { email } });
|
|
479
|
-
if (!user) {
|
|
480
|
-
throw error.unauthorized('Invalid credentials');
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
const isValid = await auth.comparePassword(password, user.password);
|
|
484
|
-
if (!isValid) {
|
|
485
|
-
throw error.unauthorized('Invalid credentials');
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// Generate login token for user authentication
|
|
489
|
-
const loginToken = auth.generateLoginToken({
|
|
490
|
-
userId: user.id,
|
|
491
|
-
role: user.role,
|
|
492
|
-
level: user.level,
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
logger.info('User logged in', { userId: user.id });
|
|
496
|
-
res.json({ token: loginToken, user: { id: user.id, email: user.email } });
|
|
497
|
-
})
|
|
498
|
-
);
|
|
107
|
+
**One function per module. Predictable. Non-ambiguous. AI-agent friendly.**
|
|
499
108
|
|
|
500
|
-
|
|
501
|
-
app.post(
|
|
502
|
-
'/admin/api-tokens',
|
|
503
|
-
auth.requireLoginToken(),
|
|
504
|
-
auth.requireUserRoles(['admin.tenant']),
|
|
505
|
-
error.asyncRoute(async (req, res) => {
|
|
506
|
-
const { keyId, permissions } = req.body;
|
|
507
|
-
|
|
508
|
-
// Generate API token for service authentication
|
|
509
|
-
const apiToken = auth.generateApiToken(
|
|
510
|
-
{
|
|
511
|
-
keyId,
|
|
512
|
-
role: 'service',
|
|
513
|
-
level: 'external',
|
|
514
|
-
permissions,
|
|
515
|
-
},
|
|
516
|
-
'1y'
|
|
517
|
-
);
|
|
518
|
-
|
|
519
|
-
res.json({ apiToken });
|
|
520
|
-
})
|
|
521
|
-
);
|
|
109
|
+
---
|
|
522
110
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
111
|
+
## ๐ญ The 12 modules
|
|
112
|
+
|
|
113
|
+
| # | Module | Purpose | Auto-scales |
|
|
114
|
+
|---|---|---|---|
|
|
115
|
+
| 1 | **Auth** | JWT tokens, role.level permissions, middleware | โ |
|
|
116
|
+
| 2 | **Database** | Prisma/Mongoose with multi-tenant filtering | per-org databases |
|
|
117
|
+
| 3 | **Security** | CSRF, rate limiting, AES-256-GCM, input sanitization | โ |
|
|
118
|
+
| 4 | **Error** | HTTP errors with semantic types + middleware | โ |
|
|
119
|
+
| 5 | **Cache** | Memory โ Redis | `REDIS_URL` |
|
|
120
|
+
| 6 | **Storage** | Local โ S3/R2 | `AWS_S3_BUCKET` |
|
|
121
|
+
| 7 | **Queue** | Memory โ Redis โ DB | `REDIS_URL` / `BLOOM_QUEUE_DB` |
|
|
122
|
+
| 8 | **Email** | Console โ SMTP โ Resend | `RESEND_API_KEY` |
|
|
123
|
+
| 9 | **Event** | Memory โ Redis pub/sub | `REDIS_URL` |
|
|
124
|
+
| 10 | **Logger** | Console โ File โ HTTP | `BLOOM_LOGGER_*` |
|
|
125
|
+
| 11 | **Config** | Type-safe env var access | โ |
|
|
126
|
+
| 12 | **Util** | Safe property access, debounce, chunk, uuid, slugify | โ |
|
|
127
|
+
|
|
128
|
+
For full method signatures and per-module examples, read [`llms.txt`](./llms.txt).
|
|
535
129
|
|
|
536
|
-
|
|
537
|
-
app.get(
|
|
538
|
-
'/api/admin/users',
|
|
539
|
-
auth.requireLoginToken(),
|
|
540
|
-
auth.requireUserRoles(['admin.tenant']),
|
|
541
|
-
error.asyncRoute(async (req, res) => {
|
|
542
|
-
const users = await database.user.findMany();
|
|
543
|
-
res.json(users);
|
|
544
|
-
})
|
|
545
|
-
);
|
|
130
|
+
---
|
|
546
131
|
|
|
547
|
-
|
|
548
|
-
app.post(
|
|
549
|
-
'/webhook/data',
|
|
550
|
-
auth.requireApiToken(),
|
|
551
|
-
error.asyncRoute(async (req, res) => {
|
|
552
|
-
const token = auth.user(req);
|
|
553
|
-
logger.info('Webhook received', { keyId: token.keyId });
|
|
554
|
-
res.json({ received: true });
|
|
555
|
-
})
|
|
556
|
-
);
|
|
132
|
+
## ๐ Environment-driven progressive scaling
|
|
557
133
|
|
|
558
|
-
|
|
559
|
-
app.use(error.handleErrors());
|
|
560
|
-
```
|
|
134
|
+
Same code. Different `.env`. Enterprise features automatically enabled.
|
|
561
135
|
|
|
562
|
-
|
|
136
|
+
```bash
|
|
137
|
+
# Day 1 โ local development (zero config)
|
|
138
|
+
BLOOM_AUTH_SECRET=<min 32 chars>
|
|
139
|
+
DATABASE_URL=postgresql://localhost/myapp
|
|
140
|
+
# โ Memory cache, local file storage, console logs, console email
|
|
563
141
|
|
|
142
|
+
# Month 6 โ production (just add env vars, no code changes)
|
|
143
|
+
REDIS_URL=redis://prod-cache:6379 # โ distributed cache + queue
|
|
144
|
+
AWS_S3_BUCKET=prod-assets # โ cloud storage + CDN
|
|
145
|
+
RESEND_API_KEY=re_production_key # โ professional email
|
|
146
|
+
BLOOM_DB_TENANT=auto # โ multi-tenant filtering
|
|
147
|
+
BLOOM_LOGGER_HTTP_URL=https://logs.example.com # โ centralized logging
|
|
564
148
|
```
|
|
565
|
-
Build a multi-tenant API where users can only see their organization's data,
|
|
566
|
-
but admins can access all organizations.
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
**AI Agent Output**:
|
|
570
149
|
|
|
571
|
-
|
|
572
|
-
import { databaseClass } from '@bloomneo/appkit/database';
|
|
573
|
-
import { authClass } from '@bloomneo/appkit/auth';
|
|
574
|
-
import { errorClass } from '@bloomneo/appkit/error';
|
|
150
|
+
See [`examples/.env.example`](./examples/.env.example) for the full canonical template.
|
|
575
151
|
|
|
576
|
-
|
|
577
|
-
const error = errorClass.get();
|
|
152
|
+
---
|
|
578
153
|
|
|
579
|
-
|
|
580
|
-
app.get(
|
|
581
|
-
'/api/projects',
|
|
582
|
-
auth.requireLogin(),
|
|
583
|
-
error.asyncRoute(async (req, res) => {
|
|
584
|
-
const database = await databaseClass.get(); // Auto-filtered by user's tenant
|
|
585
|
-
const projects = await database.project.findMany({
|
|
586
|
-
include: { tasks: true },
|
|
587
|
-
});
|
|
588
|
-
res.json(projects); // Only current tenant's projects
|
|
589
|
-
})
|
|
590
|
-
);
|
|
154
|
+
## ๐ ๏ธ AppKit CLI
|
|
591
155
|
|
|
592
|
-
|
|
593
|
-
app.get(
|
|
594
|
-
'/api/admin/all-projects',
|
|
595
|
-
auth.requireRole('admin.system'),
|
|
596
|
-
error.asyncRoute(async (req, res) => {
|
|
597
|
-
const dbTenants = await databaseClass.getTenants(); // All tenants
|
|
598
|
-
const allProjects = await dbTenants.project.findMany({
|
|
599
|
-
include: {
|
|
600
|
-
tasks: true,
|
|
601
|
-
_count: { select: { tasks: true } },
|
|
602
|
-
},
|
|
603
|
-
});
|
|
604
|
-
res.json(allProjects); // All organizations' projects
|
|
605
|
-
})
|
|
606
|
-
);
|
|
156
|
+
Project generation:
|
|
607
157
|
|
|
608
|
-
|
|
609
|
-
app
|
|
610
|
-
'/api/admin/org/:orgId/projects',
|
|
611
|
-
auth.requireRole('admin.org'),
|
|
612
|
-
error.asyncRoute(async (req, res) => {
|
|
613
|
-
const { orgId } = req.params;
|
|
614
|
-
const orgDatabase = await databaseClass.org(orgId).get();
|
|
615
|
-
const projects = await orgDatabase.project.findMany();
|
|
616
|
-
res.json(projects); // Specific organization's projects
|
|
617
|
-
})
|
|
618
|
-
);
|
|
158
|
+
```bash
|
|
159
|
+
appkit generate app myproject # full backend scaffold (Express + auth + db + error + logger)
|
|
619
160
|
```
|
|
620
161
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
### **Required Environment Variables**
|
|
162
|
+
Feature generation:
|
|
624
163
|
|
|
625
164
|
```bash
|
|
626
|
-
#
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
# Database (Required)
|
|
630
|
-
DATABASE_URL=postgresql://user:pass@host:5432/database
|
|
631
|
-
|
|
632
|
-
# Production Services (Auto-detected)
|
|
633
|
-
REDIS_URL=redis://user:pass@host:6379
|
|
634
|
-
AWS_S3_BUCKET=your-bucket
|
|
635
|
-
RESEND_API_KEY=re_your_api_key
|
|
636
|
-
VOILA_SECURITY_CSRF_SECRET=your-csrf-secret-32-chars
|
|
637
|
-
|
|
638
|
-
# Multi-tenancy (Optional)
|
|
639
|
-
VOILA_DB_TENANT=auto
|
|
640
|
-
|
|
641
|
-
# Organization Scaling (Optional)
|
|
642
|
-
ORG_ACME=postgresql://acme.dedicated.aws.com/prod
|
|
643
|
-
ORG_STARTUP=mongodb://startup.azure.com/db
|
|
165
|
+
appkit generate feature product # basic feature (route + service + types)
|
|
166
|
+
appkit generate feature order --db # database-enabled feature (+ model + HTTP tests)
|
|
167
|
+
appkit generate feature user # complete authentication system (9-role hierarchy)
|
|
644
168
|
```
|
|
645
169
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
```dockerfile
|
|
649
|
-
FROM node:18-alpine
|
|
650
|
-
WORKDIR /app
|
|
170
|
+
Generated project structure:
|
|
651
171
|
|
|
652
|
-
# Copy package files
|
|
653
|
-
COPY package*.json ./
|
|
654
|
-
RUN npm ci --only=production
|
|
655
|
-
|
|
656
|
-
# Copy application
|
|
657
|
-
COPY . .
|
|
658
|
-
|
|
659
|
-
# Health check
|
|
660
|
-
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
661
|
-
CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
|
|
662
|
-
|
|
663
|
-
EXPOSE 3000
|
|
664
|
-
CMD ["node", "server.js"]
|
|
665
172
|
```
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
matchLabels:
|
|
678
|
-
app: voila-app
|
|
679
|
-
template:
|
|
680
|
-
metadata:
|
|
681
|
-
labels:
|
|
682
|
-
app: voila-app
|
|
683
|
-
spec:
|
|
684
|
-
containers:
|
|
685
|
-
- name: app
|
|
686
|
-
image: my-app:latest
|
|
687
|
-
ports:
|
|
688
|
-
- containerPort: 3000
|
|
689
|
-
env:
|
|
690
|
-
- name: DATABASE_URL
|
|
691
|
-
valueFrom:
|
|
692
|
-
secretKeyRef:
|
|
693
|
-
name: app-secrets
|
|
694
|
-
key: database-url
|
|
695
|
-
- name: REDIS_URL
|
|
696
|
-
valueFrom:
|
|
697
|
-
secretKeyRef:
|
|
698
|
-
name: app-secrets
|
|
699
|
-
key: redis-url
|
|
700
|
-
livenessProbe:
|
|
701
|
-
httpGet:
|
|
702
|
-
path: /health
|
|
703
|
-
port: 3000
|
|
704
|
-
initialDelaySeconds: 30
|
|
705
|
-
periodSeconds: 10
|
|
173
|
+
myproject/
|
|
174
|
+
โโโ AGENTS.md # โ copied from @bloomneo/appkit at scaffold time
|
|
175
|
+
โโโ llms.txt # โ copied from @bloomneo/appkit at scaffold time
|
|
176
|
+
โโโ .env # โ contains generated BLOOM_AUTH_SECRET
|
|
177
|
+
โโโ src/api/
|
|
178
|
+
โ โโโ server.ts # Express bootstrap
|
|
179
|
+
โ โโโ lib/api-router.ts # auto-discovery routing
|
|
180
|
+
โ โโโ features/
|
|
181
|
+
โ โโโ welcome/
|
|
182
|
+
โ โโโ [your-features]/
|
|
183
|
+
โโโ package.json
|
|
706
184
|
```
|
|
707
185
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
### **Benchmarks**
|
|
711
|
-
|
|
712
|
-
- **Startup Time**: < 100ms (all modules loaded)
|
|
713
|
-
- **Memory Usage**: < 50MB baseline (production)
|
|
714
|
-
- **Request Throughput**: 10,000+ req/sec (with Redis)
|
|
715
|
-
- **Database Connections**: Automatic pooling and management
|
|
716
|
-
|
|
717
|
-
### **Scaling Characteristics**
|
|
186
|
+
---
|
|
718
187
|
|
|
719
|
-
|
|
720
|
-
| --------------- | ------------- | ----------- | ------------- | ------------- |
|
|
721
|
-
| **Development** | Memory | Local | Memory | Single |
|
|
722
|
-
| **Staging** | Redis | S3 | Redis | Single |
|
|
723
|
-
| **Production** | Redis Cluster | S3/R2 + CDN | Redis Cluster | Read Replicas |
|
|
724
|
-
| **Enterprise** | Multi-region | Multi-cloud | Distributed | Multi-tenant |
|
|
188
|
+
## ๐๏ธ Migration
|
|
725
189
|
|
|
726
|
-
|
|
190
|
+
### From `@voilajsx/appkit`
|
|
727
191
|
|
|
728
|
-
|
|
192
|
+
Two breaking changes between `@voilajsx/appkit@1.2.8` and `@bloomneo/appkit@1.5.2`:
|
|
729
193
|
|
|
730
|
-
|
|
731
|
-
import { utilClass } from '@bloomneo/appkit/util';
|
|
732
|
-
import { loggerClass } from '@bloomneo/appkit/logger';
|
|
733
|
-
import { cacheClass } from '@bloomneo/appkit/cache';
|
|
734
|
-
import { databaseClass } from '@bloomneo/appkit/database';
|
|
735
|
-
import { authClass } from '@bloomneo/appkit/auth';
|
|
194
|
+
**1. The npm scope changed.** Project-wide find-and-replace:
|
|
736
195
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
utilClass.clearCache();
|
|
741
|
-
});
|
|
742
|
-
|
|
743
|
-
afterEach(async () => {
|
|
744
|
-
// Clean up resources
|
|
745
|
-
await loggerClass.clear();
|
|
746
|
-
await cacheClass.clear();
|
|
747
|
-
await databaseClass.clear();
|
|
748
|
-
});
|
|
749
|
-
|
|
750
|
-
test('should handle user creation safely', async () => {
|
|
751
|
-
const auth = authClass.get();
|
|
752
|
-
const util = utilClass.get();
|
|
753
|
-
|
|
754
|
-
const userData = {
|
|
755
|
-
email: 'test@example.com',
|
|
756
|
-
name: 'Test User',
|
|
757
|
-
};
|
|
758
|
-
|
|
759
|
-
// Test safe property access
|
|
760
|
-
const email = util.get(userData, 'email');
|
|
761
|
-
expect(email).toBe('test@example.com');
|
|
762
|
-
|
|
763
|
-
// Test JWT token creation
|
|
764
|
-
const token = auth.signToken({
|
|
765
|
-
userId: 123,
|
|
766
|
-
role: 'user',
|
|
767
|
-
level: 'basic',
|
|
768
|
-
});
|
|
769
|
-
|
|
770
|
-
expect(token).toBeDefined();
|
|
771
|
-
|
|
772
|
-
// Test token verification
|
|
773
|
-
const payload = auth.verifyToken(token);
|
|
774
|
-
expect(payload.userId).toBe(123);
|
|
775
|
-
});
|
|
776
|
-
});
|
|
196
|
+
```diff
|
|
197
|
+
- import { authClass } from '@voilajsx/appkit/auth';
|
|
198
|
+
+ import { authClass } from '@bloomneo/appkit/auth';
|
|
777
199
|
```
|
|
778
200
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
- **100% TypeScript**: Full type safety across all modules
|
|
782
|
-
- **Comprehensive Tests**: Unit, integration, and e2e testing
|
|
783
|
-
- **Security Audits**: Regular dependency and vulnerability scanning
|
|
784
|
-
- **Performance Monitoring**: Built-in metrics and observability
|
|
785
|
-
|
|
786
|
-
## ๐ SEO & Discovery
|
|
787
|
-
|
|
788
|
-
### **Keywords & Technologies**
|
|
201
|
+
**2. The env var prefix changed.** This is a hard cutover with no fallback:
|
|
789
202
|
|
|
790
|
-
|
|
791
|
-
-
|
|
792
|
-
|
|
793
|
-
- **Zero Configuration**: Environment-driven, production-ready
|
|
794
|
-
- **TypeScript Ready**: Full type safety, modern development
|
|
795
|
-
- **Microservices**: Modular architecture, independent scaling
|
|
796
|
-
- **JWT Authentication**: Role-based access control, security
|
|
797
|
-
- **Real-time Applications**: WebSocket support, event-driven, pub/sub
|
|
798
|
-
- **Cloud Native**: Docker, Kubernetes, auto-scaling
|
|
799
|
-
- **Developer Experience**: Fast development, maintainable code
|
|
800
|
-
|
|
801
|
-
### **Use Cases**
|
|
802
|
-
|
|
803
|
-
- **SaaS Applications**: Multi-tenant, progressive scaling
|
|
804
|
-
- **API Backends**: RESTful, GraphQL, real-time
|
|
805
|
-
- **E-commerce Platforms**: Payments, inventory, user management
|
|
806
|
-
- **Content Management**: File handling, media processing
|
|
807
|
-
- **Enterprise Applications**: Security, compliance, audit trails
|
|
808
|
-
- **Microservices**: Independent, scalable, maintainable
|
|
809
|
-
- **AI Applications**: LLM integration, automated workflows
|
|
810
|
-
- **Startup MVPs**: Rapid development, production-ready
|
|
811
|
-
|
|
812
|
-
## ๐ Learning Resources
|
|
813
|
-
|
|
814
|
-
### **Quick References**
|
|
815
|
-
|
|
816
|
-
- [๐ CLI Reference](docs/APPKIT_CLI.md) - Complete command guide and usage
|
|
817
|
-
examples
|
|
818
|
-
- [๐ค LLM Integration Guide](docs/APPKIT_LLM_GUIDE.md) - AI development patterns
|
|
819
|
-
and module usage
|
|
820
|
-
- [๐ Code Standards](docs/APPKIT_COMMENTS_GUIDELINES.md) - Documentation
|
|
821
|
-
guidelines for backend apps
|
|
822
|
-
|
|
823
|
-
### **Module Documentation**
|
|
824
|
-
|
|
825
|
-
- [Authentication & Authorization](/src/auth/README.md) - Dual token system,
|
|
826
|
-
role.level hierarchy, automatic inheritance
|
|
827
|
-
- [Database & Multi-tenancy](/src/database/README.md) - Progressive scaling,
|
|
828
|
-
organizations
|
|
829
|
-
- [File Storage & CDN](/src/storage/README.md) - Local to cloud, automatic
|
|
830
|
-
optimization
|
|
831
|
-
- [Caching & Performance](/src/cache/README.md) - Memory to Redis, namespace
|
|
832
|
-
isolation
|
|
833
|
-
- [Background Jobs](/src/queue/README.md) - Processing, scheduling, reliability
|
|
834
|
-
- [Email & Communications](/src/email/README.md) - Multi-provider, templates
|
|
835
|
-
- [Real-time Events](/src/event/README.md) - WebSocket, pub/sub, notifications
|
|
836
|
-
- [Security & Compliance](/src/security/README.md) - CSRF, encryption, rate
|
|
837
|
-
limiting
|
|
838
|
-
- [Error Handling](/src/error/README.md) - HTTP status codes, semantic errors
|
|
839
|
-
- [Logging & Observability](/src/logger/README.md) - Structured, multi-transport
|
|
840
|
-
- [Configuration Management](/src/config/README.md) - Environment-driven,
|
|
841
|
-
type-safe
|
|
842
|
-
- [Utilities & Helpers](/src/util/README.md) - 12 essential developer tools
|
|
843
|
-
|
|
844
|
-
## ๐ Community & Support
|
|
845
|
-
|
|
846
|
-
### **Getting Help**
|
|
847
|
-
|
|
848
|
-
- ๐ [GitHub Issues](https://github.com/bloomneo/appkit/issues) - Bug reports
|
|
849
|
-
and feature requests
|
|
850
|
-
- ๐ง [Email Support](mailto:kt@voilacode.com) - Direct support for enterprises
|
|
203
|
+
```diff
|
|
204
|
+
- VOILA_AUTH_SECRET=...
|
|
205
|
+
+ BLOOM_AUTH_SECRET=...
|
|
851
206
|
|
|
852
|
-
|
|
207
|
+
- VOILA_SECURITY_CSRF_SECRET=...
|
|
208
|
+
+ BLOOM_SECURITY_CSRF_SECRET=...
|
|
853
209
|
|
|
854
|
-
|
|
210
|
+
- VOILA_DB_TENANT=auto
|
|
211
|
+
+ BLOOM_DB_TENANT=auto
|
|
212
|
+
```
|
|
855
213
|
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
- โจ New module features
|
|
859
|
-
- ๐งช Test coverage improvements
|
|
860
|
-
- ๐ก Feature suggestions
|
|
214
|
+
Every `VOILA_*` in your `.env` files needs to become `BLOOM_*`. There is no
|
|
215
|
+
deprecation period โ the legacy prefix is gone.
|
|
861
216
|
|
|
862
|
-
|
|
217
|
+
Rationale: the rebrand was a clean break, the env var prefix was the last
|
|
218
|
+
remaining piece of legacy branding, and shipping a backwards-compat shim
|
|
219
|
+
just kept the old name visible in error messages and docs forever.
|
|
863
220
|
|
|
864
|
-
|
|
221
|
+
### From `@bloomneo/appkit@1.5.1` โ `1.5.2`
|
|
865
222
|
|
|
866
|
-
|
|
223
|
+
Same env var rename as above. Source code (imports + module API) is
|
|
224
|
+
unchanged. The breaking change is **only** the env var prefix.
|
|
867
225
|
|
|
868
|
-
|
|
226
|
+
---
|
|
869
227
|
|
|
870
|
-
|
|
871
|
-
- npm install @voilajsx/appkit
|
|
872
|
-
+ npm install @bloomneo/appkit
|
|
873
|
-
```
|
|
228
|
+
## ๐ Resources
|
|
874
229
|
|
|
875
|
-
|
|
876
|
-
-
|
|
877
|
-
|
|
878
|
-
|
|
230
|
+
- **[`AGENTS.md`](./AGENTS.md)** โ agent-facing rules and conventions
|
|
231
|
+
- **[`llms.txt`](./llms.txt)** โ full machine-readable API reference
|
|
232
|
+
- **[`examples/`](./examples)** โ one minimal example per module
|
|
233
|
+
- **[`cookbook/`](./cookbook)** โ composed recipes (auth + crud, multi-tenant, file upload, real-time)
|
|
234
|
+
- **[`CHANGELOG.md`](./CHANGELOG.md)** โ release history
|
|
235
|
+
- **[Per-module READMEs on GitHub](https://github.com/bloomneo/appkit/tree/main/src)** โ long-form human docs (not shipped in tarball)
|
|
236
|
+
- **Issues**: https://github.com/bloomneo/appkit/issues
|
|
879
237
|
|
|
880
|
-
|
|
238
|
+
---
|
|
881
239
|
|
|
882
240
|
## ๐ License
|
|
883
241
|
|
|
884
|
-
MIT ยฉ [
|
|
885
|
-
details.
|
|
242
|
+
MIT ยฉ [Krishna Teja GS](https://github.com/ktvoilacode)
|
|
886
243
|
|
|
887
244
|
---
|
|
888
245
|
|
|
889
246
|
<p align="center">
|
|
890
|
-
<strong>๐ Built for the AI-first future of
|
|
247
|
+
<strong>๐ Built for the AI-first future of backend development</strong><br>
|
|
891
248
|
<strong>Where enterprise applications are generated, not written</strong><br><br>
|
|
892
|
-
<a href="https://github.com/bloomneo/appkit">โญ Star
|
|
249
|
+
<a href="https://github.com/bloomneo/appkit">โญ Star on GitHub</a>
|
|
893
250
|
</p>
|
|
894
|
-
|
|
895
|
-
---
|
|
896
|
-
|
|
897
|
-
### **๐ Tags**
|
|
898
|
-
|
|
899
|
-
`nodejs` `typescript` `framework` `ai-ready` `enterprise` `multi-tenant` `saas`
|
|
900
|
-
`microservices` `jwt-authentication` `zero-config` `production-ready`
|
|
901
|
-
`agentic-ai` `llm-optimized` `progressive-scaling` `real-time` `websocket`
|
|
902
|
-
`pub-sub` `developer-experience`
|