balda-js 0.0.1 → 0.0.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/lib/cli.d.ts +6 -0
- package/lib/cli.js +929 -0
- package/lib/cli.js.map +1 -0
- package/lib/index.cjs +3384 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +1492 -0
- package/lib/index.d.ts +1492 -0
- package/lib/index.js +3327 -0
- package/lib/index.js.map +1 -0
- package/package.json +1 -1
- package/.husky/pre-commit +0 -19
- package/.nvmrc +0 -1
- package/docs/README.md +0 -135
- package/docs/blog/authors.yml +0 -6
- package/docs/blog/tags.yml +0 -4
- package/docs/cli.md +0 -109
- package/docs/docs/core-concepts/controllers.md +0 -393
- package/docs/docs/core-concepts/middleware.md +0 -302
- package/docs/docs/core-concepts/request-response.md +0 -486
- package/docs/docs/core-concepts/routing.md +0 -388
- package/docs/docs/core-concepts/server.md +0 -332
- package/docs/docs/cron/overview.md +0 -70
- package/docs/docs/examples/rest-api.md +0 -595
- package/docs/docs/getting-started/configuration.md +0 -168
- package/docs/docs/getting-started/installation.md +0 -125
- package/docs/docs/getting-started/quick-start.md +0 -273
- package/docs/docs/intro.md +0 -46
- package/docs/docs/plugins/cookie.md +0 -424
- package/docs/docs/plugins/cors.md +0 -295
- package/docs/docs/plugins/file.md +0 -382
- package/docs/docs/plugins/helmet.md +0 -388
- package/docs/docs/plugins/json.md +0 -338
- package/docs/docs/plugins/log.md +0 -592
- package/docs/docs/plugins/overview.md +0 -390
- package/docs/docs/plugins/rate-limiter.md +0 -347
- package/docs/docs/plugins/static.md +0 -352
- package/docs/docs/plugins/swagger.md +0 -411
- package/docs/docs/plugins/urlencoded.md +0 -76
- package/docs/docs/testing/examples.md +0 -384
- package/docs/docs/testing/mock-server.md +0 -311
- package/docs/docs/testing/overview.md +0 -76
- package/docs/docusaurus.config.ts +0 -144
- package/docs/intro.md +0 -78
- package/docs/package.json +0 -46
- package/docs/sidebars.ts +0 -72
- package/docs/static/.nojekyll +0 -0
- package/docs/static/img/docusaurus-social-card.jpg +0 -0
- package/docs/static/img/docusaurus.png +0 -0
- package/docs/static/img/favicon.ico +0 -0
- package/docs/static/img/logo.svg +0 -1
- package/docs/static/img/undraw_docusaurus_mountain.svg +0 -37
- package/docs/static/img/undraw_docusaurus_react.svg +0 -170
- package/docs/static/img/undraw_docusaurus_tree.svg +0 -40
- package/docs/tsconfig.json +0 -8
- package/speed_test.sh +0 -3
- package/test/benchmark/index.ts +0 -17
- package/test/cli/cli.ts +0 -7
- package/test/commands/test.ts +0 -42
- package/test/controllers/file_upload.ts +0 -29
- package/test/controllers/urlencoded.ts +0 -13
- package/test/controllers/users.ts +0 -111
- package/test/cron/index.ts +0 -6
- package/test/cron/test_cron.ts +0 -8
- package/test/cron/test_cron_imported.ts +0 -8
- package/test/native_env.ts +0 -16
- package/test/resources/test.txt +0 -1
- package/test/server/index.ts +0 -3
- package/test/server/instance.ts +0 -63
- package/test/suite/upload.test.ts +0 -23
- package/test/suite/urlencoded.test.ts +0 -23
- package/test/suite/users.test.ts +0 -76
- package/todo.md +0 -9
- package/tsconfig.json +0 -24
- package/vitest.config.ts +0 -17
@@ -1,302 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 4
|
3
|
-
---
|
4
|
-
|
5
|
-
# Middleware
|
6
|
-
|
7
|
-
Middleware in Balda.js are functions that have access to the request object, response object, and the next middleware function in the application's request-response cycle. They can execute code, modify the request and response objects, end the request-response cycle, and call the next middleware function.
|
8
|
-
|
9
|
-
## Basic Middleware
|
10
|
-
|
11
|
-
### Function Signature
|
12
|
-
|
13
|
-
```typescript
|
14
|
-
type Middleware = (
|
15
|
-
req: Request,
|
16
|
-
res: Response,
|
17
|
-
next: NextFunction
|
18
|
-
) => void | Promise<void>;
|
19
|
-
```
|
20
|
-
|
21
|
-
### Simple Middleware Example
|
22
|
-
|
23
|
-
```typescript
|
24
|
-
const logger = (req, res, next) => {
|
25
|
-
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
|
26
|
-
next();
|
27
|
-
};
|
28
|
-
|
29
|
-
const auth = (req, res, next) => {
|
30
|
-
const token = req.headers.authorization;
|
31
|
-
|
32
|
-
if (!token) {
|
33
|
-
return res.unauthorized({ error: 'Authentication required' });
|
34
|
-
}
|
35
|
-
|
36
|
-
// Verify token logic here
|
37
|
-
req.user = { id: 1, name: 'John' };
|
38
|
-
next();
|
39
|
-
};
|
40
|
-
```
|
41
|
-
|
42
|
-
## Middleware Application
|
43
|
-
|
44
|
-
### Global Middleware
|
45
|
-
|
46
|
-
Apply middleware to all routes:
|
47
|
-
|
48
|
-
```typescript
|
49
|
-
import { Server } from 'balda-js';
|
50
|
-
|
51
|
-
const server = new Server({ port: 3000 });
|
52
|
-
|
53
|
-
// Apply to all routes
|
54
|
-
server.use(logger);
|
55
|
-
server.use(cors);
|
56
|
-
|
57
|
-
// Multiple middleware
|
58
|
-
server.use(
|
59
|
-
(req, res, next) => {
|
60
|
-
req.startTime = Date.now();
|
61
|
-
next();
|
62
|
-
},
|
63
|
-
(req, res, next) => {
|
64
|
-
res.on('finish', () => {
|
65
|
-
const duration = Date.now() - req.startTime;
|
66
|
-
console.log(`${req.method} ${req.url} - ${duration}ms`);
|
67
|
-
});
|
68
|
-
next();
|
69
|
-
}
|
70
|
-
);
|
71
|
-
```
|
72
|
-
|
73
|
-
### Controller-Level Middleware
|
74
|
-
|
75
|
-
Apply middleware to all routes in a controller:
|
76
|
-
|
77
|
-
```typescript
|
78
|
-
import { controller, get, middleware } from 'balda-js';
|
79
|
-
|
80
|
-
@controller('/users')
|
81
|
-
@middleware(authMiddleware)
|
82
|
-
export class UsersController {
|
83
|
-
@get('/')
|
84
|
-
async getAllUsers(req, res) {
|
85
|
-
// This route will use authMiddleware
|
86
|
-
res.json({ users: [] });
|
87
|
-
}
|
88
|
-
|
89
|
-
@get('/public')
|
90
|
-
@middleware(publicMiddleware) // Override controller middleware
|
91
|
-
async getPublicUsers(req, res) {
|
92
|
-
// This route will use publicMiddleware instead
|
93
|
-
res.json({ users: [] });
|
94
|
-
}
|
95
|
-
}
|
96
|
-
```
|
97
|
-
|
98
|
-
### Route-Level Middleware
|
99
|
-
|
100
|
-
Apply middleware to specific routes:
|
101
|
-
|
102
|
-
```typescript
|
103
|
-
@get('/admin/users', { middleware: [authMiddleware, adminMiddleware] })
|
104
|
-
async getAdminUsers(req, res) {
|
105
|
-
res.json({ users: [] });
|
106
|
-
}
|
107
|
-
```
|
108
|
-
|
109
|
-
## Common Middleware Patterns
|
110
|
-
|
111
|
-
### Authentication Middleware
|
112
|
-
|
113
|
-
```typescript
|
114
|
-
const authMiddleware = async (req, res, next) => {
|
115
|
-
const token = req.headers.authorization?.replace('Bearer ', '');
|
116
|
-
|
117
|
-
if (!token) {
|
118
|
-
return res.unauthorized({ error: 'Authentication token required' });
|
119
|
-
}
|
120
|
-
|
121
|
-
try {
|
122
|
-
// Verify JWT token
|
123
|
-
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
124
|
-
req.user = decoded;
|
125
|
-
next();
|
126
|
-
} catch (error) {
|
127
|
-
return res.unauthorized({ error: 'Invalid authentication token' });
|
128
|
-
}
|
129
|
-
};
|
130
|
-
```
|
131
|
-
|
132
|
-
### Role-Based Authorization
|
133
|
-
|
134
|
-
```typescript
|
135
|
-
const requireRole = (role) => {
|
136
|
-
return (req, res, next) => {
|
137
|
-
if (!req.user) {
|
138
|
-
return res.unauthorized({ error: 'Authentication required' });
|
139
|
-
}
|
140
|
-
|
141
|
-
if (req.user.role !== role) {
|
142
|
-
return res.forbidden({ error: 'Insufficient permissions' });
|
143
|
-
}
|
144
|
-
|
145
|
-
next();
|
146
|
-
};
|
147
|
-
};
|
148
|
-
|
149
|
-
// Usage
|
150
|
-
@get('/admin', { middleware: [authMiddleware, requireRole('admin')] })
|
151
|
-
async getAdminPanel(req, res) {
|
152
|
-
res.json({ admin: true });
|
153
|
-
}
|
154
|
-
```
|
155
|
-
|
156
|
-
### Request Logging
|
157
|
-
|
158
|
-
```typescript
|
159
|
-
const requestLogger = (req, res, next) => {
|
160
|
-
const start = Date.now();
|
161
|
-
|
162
|
-
res.on('finish', () => {
|
163
|
-
const duration = Date.now() - start;
|
164
|
-
console.log(`${req.method} ${req.url} ${res.statusCode} - ${duration}ms`);
|
165
|
-
});
|
166
|
-
|
167
|
-
next();
|
168
|
-
};
|
169
|
-
```
|
170
|
-
|
171
|
-
### Error Handling Middleware
|
172
|
-
|
173
|
-
```typescript
|
174
|
-
const errorHandler = (req, res, next, error) => {
|
175
|
-
console.error('Error:', error);
|
176
|
-
|
177
|
-
if (error.name === 'ValidationError') {
|
178
|
-
return res.badRequest({ error: error.message });
|
179
|
-
}
|
180
|
-
|
181
|
-
if (error.name === 'UnauthorizedError') {
|
182
|
-
return res.unauthorized({ error: 'Authentication required' });
|
183
|
-
}
|
184
|
-
|
185
|
-
res.internalServerError({ error: 'Internal server error' });
|
186
|
-
};
|
187
|
-
|
188
|
-
server.setErrorHandler(errorHandler);
|
189
|
-
```
|
190
|
-
|
191
|
-
### CORS Middleware
|
192
|
-
|
193
|
-
```typescript
|
194
|
-
const corsMiddleware = (req, res, next) => {
|
195
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
196
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
197
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
198
|
-
|
199
|
-
if (req.method === 'OPTIONS') {
|
200
|
-
res.status(200).end();
|
201
|
-
return;
|
202
|
-
}
|
203
|
-
|
204
|
-
next();
|
205
|
-
};
|
206
|
-
```
|
207
|
-
|
208
|
-
### Rate Limiting
|
209
|
-
|
210
|
-
```typescript
|
211
|
-
const rateLimit = (windowMs = 15 * 60 * 1000, max = 100) => {
|
212
|
-
const requests = new Map();
|
213
|
-
|
214
|
-
return (req, res, next) => {
|
215
|
-
const ip = req.ip;
|
216
|
-
const now = Date.now();
|
217
|
-
|
218
|
-
if (!requests.has(ip)) {
|
219
|
-
requests.set(ip, { count: 0, resetTime: now + windowMs });
|
220
|
-
}
|
221
|
-
|
222
|
-
const record = requests.get(ip);
|
223
|
-
|
224
|
-
if (now > record.resetTime) {
|
225
|
-
record.count = 0;
|
226
|
-
record.resetTime = now + windowMs;
|
227
|
-
}
|
228
|
-
|
229
|
-
if (record.count >= max) {
|
230
|
-
return res.tooManyRequests({ error: 'Too many requests' });
|
231
|
-
}
|
232
|
-
|
233
|
-
record.count++;
|
234
|
-
next();
|
235
|
-
};
|
236
|
-
};
|
237
|
-
```
|
238
|
-
|
239
|
-
## Middleware Order
|
240
|
-
|
241
|
-
The order of middleware matters. Middleware are executed in the order they are applied:
|
242
|
-
|
243
|
-
```typescript
|
244
|
-
// 1. Global middleware (applied first)
|
245
|
-
server.use(logger);
|
246
|
-
server.use(cors);
|
247
|
-
|
248
|
-
// 2. Controller middleware
|
249
|
-
@controller('/users')
|
250
|
-
@middleware(authMiddleware) // Applied to all routes in controller
|
251
|
-
|
252
|
-
// 3. Route middleware (applied last)
|
253
|
-
@get('/admin', { middleware: [adminMiddleware] })
|
254
|
-
async getAdmin(req, res) {
|
255
|
-
// Execution order: logger -> cors -> authMiddleware -> adminMiddleware -> handler
|
256
|
-
}
|
257
|
-
```
|
258
|
-
|
259
|
-
## Async Middleware
|
260
|
-
|
261
|
-
Middleware can be async functions:
|
262
|
-
|
263
|
-
```typescript
|
264
|
-
const asyncAuthMiddleware = async (req, res, next) => {
|
265
|
-
try {
|
266
|
-
const token = req.headers.authorization?.replace('Bearer ', '');
|
267
|
-
|
268
|
-
if (!token) {
|
269
|
-
return res.unauthorized({ error: 'Authentication required' });
|
270
|
-
}
|
271
|
-
|
272
|
-
// Async operation
|
273
|
-
const user = await verifyToken(token);
|
274
|
-
req.user = user;
|
275
|
-
next();
|
276
|
-
} catch (error) {
|
277
|
-
return res.unauthorized({ error: 'Invalid token' });
|
278
|
-
}
|
279
|
-
};
|
280
|
-
```
|
281
|
-
|
282
|
-
## Conditional Middleware
|
283
|
-
|
284
|
-
Apply middleware conditionally:
|
285
|
-
|
286
|
-
```typescript
|
287
|
-
const conditionalAuth = (req, res, next) => {
|
288
|
-
// Skip auth for public routes
|
289
|
-
if (req.path.startsWith('/public')) {
|
290
|
-
return next();
|
291
|
-
}
|
292
|
-
|
293
|
-
// Apply auth for protected routes
|
294
|
-
const token = req.headers.authorization;
|
295
|
-
if (!token) {
|
296
|
-
return res.unauthorized({ error: 'Authentication required' });
|
297
|
-
}
|
298
|
-
|
299
|
-
req.user = { id: 1 };
|
300
|
-
next();
|
301
|
-
};
|
302
|
-
```
|