@dangao/bun-server 1.1.2 → 1.1.4

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.
@@ -0,0 +1,569 @@
1
+ # Extension System
2
+
3
+ Bun Server Framework provides multiple extension methods, allowing you to flexibly extend application functionality based on your needs. This document introduces all supported extension methods and their use cases.
4
+
5
+ ## Extension Methods Overview
6
+
7
+ Bun Server supports the following extension methods:
8
+
9
+ 1. **Middleware** - Handle request/response flow
10
+ 2. **Application Extension** - Register global services and features
11
+ 3. **Module** - Organize functional modules with import/export support
12
+ 4. **Custom Decorators** - Extend controller and route functionality
13
+
14
+ ## 1. Middleware
15
+
16
+ Middleware is the core mechanism for handling HTTP request/response flow, allowing you to execute custom logic before and after request processing.
17
+
18
+ ### Global Middleware
19
+
20
+ Register global middleware via `app.use()`, and all requests will pass through these middleware.
21
+
22
+ ```typescript
23
+ import { Application, createLoggerMiddleware, createCorsMiddleware } from '@dangao/bun-server';
24
+
25
+ const app = new Application({ port: 3000 });
26
+
27
+ // Register global middleware
28
+ app.use(createLoggerMiddleware({ prefix: '[App]' }));
29
+ app.use(createCorsMiddleware({ origin: '*' }));
30
+
31
+ // Custom middleware
32
+ app.use(async (ctx, next) => {
33
+ // Pre-request processing
34
+ const start = Date.now();
35
+
36
+ // Call next middleware or route handler
37
+ const response = await next();
38
+
39
+ // Post-request processing
40
+ const duration = Date.now() - start;
41
+ console.log(`Request took ${duration}ms`);
42
+
43
+ return response;
44
+ });
45
+ ```
46
+
47
+ ### Controller-Level Middleware
48
+
49
+ Use the `@UseMiddleware()` decorator to apply middleware at the controller class or method level.
50
+
51
+ ```typescript
52
+ import { Controller, GET, UseMiddleware } from '@dangao/bun-server';
53
+
54
+ // Controller-level middleware
55
+ @Controller('/api')
56
+ @UseMiddleware(authMiddleware)
57
+ class ApiController {
58
+ @GET('/public')
59
+ public publicEndpoint() {
60
+ return { message: 'Public data' };
61
+ }
62
+
63
+ // Method-level middleware
64
+ @GET('/admin')
65
+ @UseMiddleware(adminOnlyMiddleware)
66
+ public adminEndpoint() {
67
+ return { message: 'Admin data' };
68
+ }
69
+ }
70
+ ```
71
+
72
+ ### Built-in Middleware
73
+
74
+ The framework provides several built-in middleware:
75
+
76
+ ```typescript
77
+ import {
78
+ createLoggerMiddleware, // Request logging
79
+ createRequestLoggingMiddleware, // Detailed request logging
80
+ createCorsMiddleware, // CORS support
81
+ createErrorHandlingMiddleware, // Error handling
82
+ createFileUploadMiddleware, // File upload
83
+ createStaticFileMiddleware, // Static file serving
84
+ } from '@dangao/bun-server';
85
+
86
+ app.use(createLoggerMiddleware({ prefix: '[App]' }));
87
+ app.use(createCorsMiddleware({ origin: 'https://example.com' }));
88
+ app.use(createStaticFileMiddleware({ root: './public', prefix: '/assets' }));
89
+ ```
90
+
91
+ ### Recommended Usage
92
+
93
+ - ✅ **Global Middleware**: Logging, error handling, CORS, request tracing
94
+ - ✅ **Controller-Level Middleware**: Authentication, authorization, rate limiting
95
+ - ✅ **Method-Level Middleware**: Specific business logic validation
96
+
97
+ ## 2. Application Extension
98
+
99
+ Application extensions are used to register global services and features, such as logging systems, configuration management, etc.
100
+
101
+ ### Using Extensions
102
+
103
+ ```typescript
104
+ import { Application, LoggerExtension, SwaggerExtension, LogLevel } from '@dangao/bun-server';
105
+
106
+ const app = new Application({ port: 3000 });
107
+
108
+ // Register Logger extension
109
+ app.registerExtension(
110
+ new LoggerExtension({
111
+ prefix: 'MyApp',
112
+ level: LogLevel.DEBUG,
113
+ })
114
+ );
115
+
116
+ // Register Swagger extension
117
+ app.registerExtension(
118
+ new SwaggerExtension({
119
+ info: {
120
+ title: 'My API',
121
+ version: '1.0.0',
122
+ },
123
+ servers: [{ url: 'http://localhost:3000' }],
124
+ })
125
+ );
126
+ ```
127
+
128
+ ### Creating Custom Extensions
129
+
130
+ ```typescript
131
+ import { Container } from '@dangao/bun-server';
132
+ import type { ApplicationExtension } from '@dangao/bun-server';
133
+
134
+ class MyExtension implements ApplicationExtension {
135
+ public register(container: Container): void {
136
+ // Register services to container
137
+ container.registerInstance('MY_SERVICE', {
138
+ doSomething: () => console.log('Hello from extension'),
139
+ });
140
+ }
141
+ }
142
+
143
+ app.registerExtension(new MyExtension());
144
+ ```
145
+
146
+ ### Recommended Usage
147
+
148
+ - ✅ **Global Service Registration**: Logging, configuration, database connections
149
+ - ✅ **Feature Module Initialization**: Swagger, monitoring, caching
150
+ - ✅ **Third-Party Integration**: Authentication services, message queues
151
+
152
+ ## 3. Module
153
+
154
+ The module system provides a more structured way to organize code, supporting dependency injection, service exports, and module imports.
155
+
156
+ ### Basic Module
157
+
158
+ ```typescript
159
+ import { Module, Injectable, Controller, GET } from '@dangao/bun-server';
160
+
161
+ @Injectable()
162
+ class UserService {
163
+ public findAll() {
164
+ return [{ id: '1', name: 'Alice' }];
165
+ }
166
+ }
167
+
168
+ @Controller('/api/users')
169
+ class UserController {
170
+ public constructor(private readonly userService: UserService) {}
171
+
172
+ @GET('/')
173
+ public list() {
174
+ return this.userService.findAll();
175
+ }
176
+ }
177
+
178
+ @Module({
179
+ controllers: [UserController],
180
+ providers: [UserService],
181
+ exports: [UserService], // Export for use by other modules
182
+ })
183
+ class UserModule {}
184
+ ```
185
+
186
+ ### Module Imports
187
+
188
+ ```typescript
189
+ import { Module } from '@dangao/bun-server';
190
+ import { UserModule } from './user.module';
191
+ import { OrderModule } from './order.module';
192
+
193
+ @Module({
194
+ imports: [UserModule, OrderModule], // Import other modules
195
+ controllers: [AppController],
196
+ providers: [AppService],
197
+ })
198
+ class AppModule {}
199
+ ```
200
+
201
+ ### Official Modules
202
+
203
+ The framework provides official modules that can be imported via `imports`:
204
+
205
+ #### LoggerModule
206
+
207
+ ```typescript
208
+ import { LoggerModule, LogLevel, Module } from '@dangao/bun-server';
209
+
210
+ // Configure Logger module
211
+ LoggerModule.forRoot({
212
+ logger: {
213
+ prefix: 'MyApp',
214
+ level: LogLevel.DEBUG,
215
+ },
216
+ enableRequestLogging: true,
217
+ requestLoggingPrefix: '[MyApp]',
218
+ });
219
+
220
+ @Module({
221
+ imports: [LoggerModule], // Import Logger module
222
+ controllers: [UserController],
223
+ providers: [UserService],
224
+ })
225
+ class AppModule {}
226
+ ```
227
+
228
+ #### SwaggerModule
229
+
230
+ ```typescript
231
+ import { SwaggerModule, Module } from '@dangao/bun-server';
232
+
233
+ // Configure Swagger module
234
+ SwaggerModule.forRoot({
235
+ info: {
236
+ title: 'My API',
237
+ version: '1.0.0',
238
+ description: 'API documentation',
239
+ },
240
+ servers: [{ url: 'http://localhost:3000' }],
241
+ uiPath: '/swagger',
242
+ jsonPath: '/swagger.json',
243
+ enableUI: true,
244
+ });
245
+
246
+ @Module({
247
+ imports: [SwaggerModule], // Import Swagger module
248
+ controllers: [UserController],
249
+ providers: [UserService],
250
+ })
251
+ class AppModule {}
252
+ ```
253
+
254
+ #### SecurityModule (Recommended)
255
+
256
+ SecurityModule is a unified security module, designed following Spring Security architecture, supporting multiple authentication methods:
257
+
258
+ ```typescript
259
+ import { SecurityModule, Module, Auth } from '@dangao/bun-server';
260
+
261
+ // Configure security module
262
+ SecurityModule.forRoot({
263
+ jwt: {
264
+ secret: 'your-secret-key',
265
+ accessTokenExpiresIn: 3600,
266
+ refreshTokenExpiresIn: 86400 * 7,
267
+ },
268
+ oauth2Clients: [
269
+ {
270
+ clientId: 'my-client',
271
+ clientSecret: 'my-secret',
272
+ redirectUris: ['http://localhost:3000/callback'],
273
+ grantTypes: ['authorization_code', 'refresh_token'],
274
+ },
275
+ ],
276
+ enableOAuth2Endpoints: true,
277
+ excludePaths: ['/api/public'],
278
+ defaultAuthRequired: false, // Default no auth required, controlled by @Auth() decorator
279
+ });
280
+
281
+ @Module({
282
+ imports: [SecurityModule], // Import security module
283
+ controllers: [UserController],
284
+ providers: [UserService],
285
+ })
286
+ class AppModule {}
287
+
288
+ // Use @Auth() decorator to control access
289
+ @Controller('/api/users')
290
+ class UserController {
291
+ @GET('/me')
292
+ @Auth() // Requires authentication
293
+ public getMe() {
294
+ return { user: 'current user' };
295
+ }
296
+
297
+ @GET('/admin')
298
+ @Auth({ roles: ['admin'] }) // Requires admin role
299
+ public getAdmin() {
300
+ return { message: 'admin only' };
301
+ }
302
+ }
303
+ ```
304
+
305
+ **SecurityModule Architecture Features**:
306
+ - **Core Abstraction**: `AuthenticationManager` manages authentication flow
307
+ - **Authentication Providers**: Supports multiple auth methods (JWT, OAuth2, etc.)
308
+ - **Access Decision**: `AccessDecisionManager` handles authorization decisions
309
+ - **Security Context**: `SecurityContext` manages current authentication state
310
+ - **Extensible**: Can customize authentication providers and access decision managers
311
+
312
+ #### ConfigModule (Configuration Management)
313
+
314
+ ConfigModule provides centralized configuration management, and exposes type-safe access via `ConfigService`:
315
+
316
+ ```typescript
317
+ import {
318
+ ConfigModule,
319
+ ConfigService,
320
+ CONFIG_SERVICE_TOKEN,
321
+ Module,
322
+ } from '@dangao/bun-server';
323
+
324
+ // Configure module
325
+ ConfigModule.forRoot({
326
+ defaultConfig: {
327
+ app: {
328
+ port: Number(process.env.PORT ?? 3000),
329
+ name: 'MyApp',
330
+ },
331
+ logger: {
332
+ prefix: 'MyApp',
333
+ level: 'debug',
334
+ },
335
+ },
336
+ load(env) {
337
+ // Load config from environment variables (optional)
338
+ return {
339
+ app: {
340
+ port: env.APP_PORT ? Number(env.APP_PORT) : undefined,
341
+ },
342
+ };
343
+ },
344
+ validate(config) {
345
+ if (!config.app?.name) {
346
+ throw new Error('app.name is required');
347
+ }
348
+ },
349
+ });
350
+
351
+ @Module({
352
+ imports: [ConfigModule],
353
+ controllers: [UserController],
354
+ })
355
+ class AppModule {}
356
+
357
+ // Inject ConfigService in business code
358
+ @Controller('/api')
359
+ class UserController {
360
+ public constructor(
361
+ @Inject(CONFIG_SERVICE_TOKEN)
362
+ private readonly config: ConfigService,
363
+ ) {}
364
+
365
+ @GET('/info')
366
+ public info() {
367
+ const appName = this.config.get<string>('app.name', 'MyApp');
368
+ const port = this.config.get<number>('app.port', 3000);
369
+ return { appName, port };
370
+ }
371
+ }
372
+ ```
373
+
374
+ **ConfigModule Highlights**:
375
+
376
+ - **Centralized configuration**: Supports default config + environment-based loading (`defaultConfig` + `load(env)`)
377
+ - **Type-safe access**: Use `ConfigService.get/getRequired` with dot-path keys (e.g. `app.port`)
378
+ - **Validation hook**: `validate(config)` can integrate class-validator style validation
379
+ - **Non-intrusive**: Examples (`basic-app.ts` / `full-app.ts` / `multi-module-app.ts` / `auth-app.ts`) use `ConfigModule` to manage ports, logger prefixes, etc.
380
+
381
+ ### Complete Example
382
+
383
+ ```typescript
384
+ import {
385
+ Application,
386
+ Module,
387
+ LoggerModule,
388
+ SwaggerModule,
389
+ SecurityModule,
390
+ LogLevel,
391
+ Auth,
392
+ } from '@dangao/bun-server';
393
+
394
+ // Configure modules
395
+ LoggerModule.forRoot({
396
+ logger: { prefix: 'App', level: LogLevel.INFO },
397
+ enableRequestLogging: true,
398
+ });
399
+
400
+ SwaggerModule.forRoot({
401
+ info: { title: 'API', version: '1.0.0' },
402
+ uiPath: '/swagger',
403
+ });
404
+
405
+ SecurityModule.forRoot({
406
+ jwt: {
407
+ secret: 'your-secret-key',
408
+ accessTokenExpiresIn: 3600,
409
+ },
410
+ oauth2Clients: [
411
+ {
412
+ clientId: 'my-client',
413
+ clientSecret: 'my-secret',
414
+ redirectUris: ['http://localhost:3000/callback'],
415
+ grantTypes: ['authorization_code'],
416
+ },
417
+ ],
418
+ excludePaths: ['/api/public'],
419
+ });
420
+
421
+ // Application module
422
+ @Module({
423
+ imports: [LoggerModule, SwaggerModule, SecurityModule],
424
+ controllers: [UserController, OrderController],
425
+ providers: [UserService, OrderService],
426
+ })
427
+ class AppModule {}
428
+
429
+ // Register module
430
+ const app = new Application({ port: 3000 });
431
+ app.registerModule(AppModule);
432
+ app.listen();
433
+ ```
434
+
435
+ ### Recommended Usage
436
+
437
+ - ✅ **Business Modularization**: Split by domain (UserModule, OrderModule)
438
+ - ✅ **Feature Modules**: Use official modules (LoggerModule, SwaggerModule)
439
+ - ✅ **Service Sharing**: Export services via `exports` for use by other modules
440
+ - ✅ **Dependency Management**: Manage module dependencies via `imports`
441
+
442
+ ## 4. Custom Decorators
443
+
444
+ You can create custom decorators to extend controller and route functionality.
445
+
446
+ ### Creating Decorators
447
+
448
+ ```typescript
449
+ import 'reflect-metadata';
450
+
451
+ // Cache decorator
452
+ export function Cache(ttl: number) {
453
+ return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
454
+ const originalMethod = descriptor.value;
455
+ const cache = new Map();
456
+
457
+ descriptor.value = async function (...args: any[]) {
458
+ const key = JSON.stringify(args);
459
+ if (cache.has(key)) {
460
+ return cache.get(key);
461
+ }
462
+ const result = await originalMethod.apply(this, args);
463
+ cache.set(key, result);
464
+ setTimeout(() => cache.delete(key), ttl);
465
+ return result;
466
+ };
467
+ };
468
+ }
469
+
470
+ // Using decorator
471
+ @Controller('/api')
472
+ class ApiController {
473
+ @GET('/data')
474
+ @Cache(60000) // Cache for 60 seconds
475
+ public getData() {
476
+ return { data: 'expensive computation' };
477
+ }
478
+ }
479
+ ```
480
+
481
+ ### Recommended Usage
482
+
483
+ - ✅ **Cross-Cutting Concerns**: Caching, logging, performance monitoring
484
+ - ✅ **Business Logic Enhancement**: Permission checks, data transformation
485
+ - ✅ **Code Reusability**: Encapsulate common functionality as decorators
486
+
487
+ ## Extension Methods Comparison
488
+
489
+ | Extension Method | Use Cases | Advantages | Disadvantages |
490
+ |-----------------|-----------|-----------|---------------|
491
+ | **Middleware** | Request/response processing flow | Flexible, composable, controllable execution order | Not suitable for registering global services |
492
+ | **Application Extension** | Global service registration, feature initialization | Unified management, clear lifecycle | Requires manual registration |
493
+ | **Module** | Code organization, dependency management | Structured, reusable, supports import/export | Requires understanding of module system |
494
+ | **Decorator** | Cross-cutting concerns, code enhancement | Declarative, easy to use | Relatively single functionality |
495
+
496
+ ## Recommended Practices
497
+
498
+ ### 1. Small Projects
499
+
500
+ Using middleware and extensions is sufficient:
501
+
502
+ ```typescript
503
+ const app = new Application({ port: 3000 });
504
+
505
+ // Register extensions
506
+ app.registerExtension(new LoggerExtension());
507
+ app.registerExtension(new SwaggerExtension({...}));
508
+
509
+ // Register middleware
510
+ app.use(createLoggerMiddleware());
511
+ app.use(createCorsMiddleware());
512
+
513
+ // Register controllers
514
+ app.registerController(UserController);
515
+ ```
516
+
517
+ ### 2. Medium Projects
518
+
519
+ Use the module system to organize code:
520
+
521
+ ```typescript
522
+ @Module({
523
+ imports: [LoggerModule, SwaggerModule],
524
+ controllers: [UserController, OrderController],
525
+ providers: [UserService, OrderService],
526
+ })
527
+ class AppModule {}
528
+
529
+ const app = new Application({ port: 3000 });
530
+ app.registerModule(AppModule);
531
+ ```
532
+
533
+ ### 3. Large Projects
534
+
535
+ Split modules by domain, use module imports:
536
+
537
+ ```typescript
538
+ // user.module.ts
539
+ @Module({
540
+ controllers: [UserController],
541
+ providers: [UserService],
542
+ exports: [UserService],
543
+ })
544
+ class UserModule {}
545
+
546
+ // order.module.ts
547
+ @Module({
548
+ imports: [UserModule], // Import UserModule to use UserService
549
+ controllers: [OrderController],
550
+ providers: [OrderService],
551
+ })
552
+ class OrderModule {}
553
+
554
+ // app.module.ts
555
+ @Module({
556
+ imports: [LoggerModule, SwaggerModule, UserModule, OrderModule],
557
+ })
558
+ class AppModule {}
559
+ ```
560
+
561
+ ## Summary
562
+
563
+ - **Middleware**: Handle request/response flow, suitable for logging, authentication, error handling
564
+ - **Application Extension**: Register global services, suitable for logging systems, configuration management
565
+ - **Module**: Organize code structure, suitable for business modularization and dependency management
566
+ - **Decorator**: Enhance code functionality, suitable for cross-cutting concerns
567
+
568
+ Choose the appropriate extension method based on project scale and requirements, or combine multiple methods.
569
+