mini-nest 1.0.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.
- package/LICENSE +0 -0
- package/README.md +556 -0
- package/dist/aop/aopWrapper.d.ts +17 -0
- package/dist/aop/aopWrapper.d.ts.map +1 -0
- package/dist/aop/aopWrapper.js +112 -0
- package/dist/aop/aopWrapper.js.map +1 -0
- package/dist/cache/cacheManager.d.ts +11 -0
- package/dist/cache/cacheManager.d.ts.map +1 -0
- package/dist/cache/cacheManager.js +42 -0
- package/dist/cache/cacheManager.js.map +1 -0
- package/dist/circuitBreaker/circuitBreakerManager.d.ts +21 -0
- package/dist/circuitBreaker/circuitBreakerManager.d.ts.map +1 -0
- package/dist/circuitBreaker/circuitBreakerManager.js +60 -0
- package/dist/circuitBreaker/circuitBreakerManager.js.map +1 -0
- package/dist/circuitBreaker/circuitOpenError.d.ts +4 -0
- package/dist/circuitBreaker/circuitOpenError.d.ts.map +1 -0
- package/dist/circuitBreaker/circuitOpenError.js +11 -0
- package/dist/circuitBreaker/circuitOpenError.js.map +1 -0
- package/dist/container.js +33 -0
- package/dist/controller.js +10 -0
- package/dist/core/app/App.d.ts +31 -0
- package/dist/core/app/App.d.ts.map +1 -0
- package/dist/core/app/App.js +149 -0
- package/dist/core/app/App.js.map +1 -0
- package/dist/core/container/container.d.ts +16 -0
- package/dist/core/container/container.d.ts.map +1 -0
- package/dist/core/container/container.js +61 -0
- package/dist/core/container/container.js.map +1 -0
- package/dist/core/pipeline/ExecutionContext.d.ts +22 -0
- package/dist/core/pipeline/ExecutionContext.d.ts.map +1 -0
- package/dist/core/pipeline/ExecutionContext.js +31 -0
- package/dist/core/pipeline/ExecutionContext.js.map +1 -0
- package/dist/core/pipeline/RequestPipeline.d.ts +9 -0
- package/dist/core/pipeline/RequestPipeline.d.ts.map +1 -0
- package/dist/core/pipeline/RequestPipeline.js +83 -0
- package/dist/core/pipeline/RequestPipeline.js.map +1 -0
- package/dist/createMethodDecorator.js +22 -0
- package/dist/createParamDecorator.js +46 -0
- package/dist/decorators/Injectable.d.ts +3 -0
- package/dist/decorators/Injectable.d.ts.map +1 -0
- package/dist/decorators/Injectable.js +10 -0
- package/dist/decorators/Injectable.js.map +1 -0
- package/dist/decorators/UseGuard.d.ts +6 -0
- package/dist/decorators/UseGuard.d.ts.map +1 -0
- package/dist/decorators/UseGuard.js +20 -0
- package/dist/decorators/UseGuard.js.map +1 -0
- package/dist/decorators/UseInterceptor.d.ts +5 -0
- package/dist/decorators/UseInterceptor.d.ts.map +1 -0
- package/dist/decorators/UseInterceptor.js +15 -0
- package/dist/decorators/UseInterceptor.js.map +1 -0
- package/dist/decorators/aop/Cache.d.ts +6 -0
- package/dist/decorators/aop/Cache.d.ts.map +1 -0
- package/dist/decorators/aop/Cache.js +13 -0
- package/dist/decorators/aop/Cache.js.map +1 -0
- package/dist/decorators/aop/CircuitBreaker.d.ts +6 -0
- package/dist/decorators/aop/CircuitBreaker.d.ts.map +1 -0
- package/dist/decorators/aop/CircuitBreaker.js +10 -0
- package/dist/decorators/aop/CircuitBreaker.js.map +1 -0
- package/dist/decorators/aop/Retry.d.ts +2 -0
- package/dist/decorators/aop/Retry.d.ts.map +1 -0
- package/dist/decorators/aop/Retry.js +10 -0
- package/dist/decorators/aop/Retry.js.map +1 -0
- package/dist/decorators/aop/Timeout.d.ts +2 -0
- package/dist/decorators/aop/Timeout.d.ts.map +1 -0
- package/dist/decorators/aop/Timeout.js +10 -0
- package/dist/decorators/aop/Timeout.js.map +1 -0
- package/dist/decorators/http/Controller.d.ts +3 -0
- package/dist/decorators/http/Controller.d.ts.map +1 -0
- package/dist/decorators/http/Controller.js +11 -0
- package/dist/decorators/http/Controller.js.map +1 -0
- package/dist/decorators/http/CreateMethodDecorator.d.ts +8 -0
- package/dist/decorators/http/CreateMethodDecorator.d.ts.map +1 -0
- package/dist/decorators/http/CreateMethodDecorator.js +20 -0
- package/dist/decorators/http/CreateMethodDecorator.js.map +1 -0
- package/dist/decorators/http/CreateParamDecorator.d.ts +13 -0
- package/dist/decorators/http/CreateParamDecorator.d.ts.map +1 -0
- package/dist/decorators/http/CreateParamDecorator.js +57 -0
- package/dist/decorators/http/CreateParamDecorator.js.map +1 -0
- package/dist/decorators/index.d.ts +11 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +37 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators.js +1 -0
- package/dist/examples/User.example.js +12 -0
- package/dist/examples/container.example.js +31 -0
- package/dist/examples/container.example.mjs +42 -0
- package/dist/examples/controllers/LogController.js +33 -0
- package/dist/examples/controllers/UserController.js +68 -0
- package/dist/examples/createTestApp.js +23 -0
- package/dist/examples/interceptors/LoggerInterceptor.js +12 -0
- package/dist/examples/log.example.js +6 -0
- package/dist/examples/services/LoggerService.js +19 -0
- package/dist/examples/services/UserService.js +40 -0
- package/dist/exceptions/HTTPExceptions.d.ts +36 -0
- package/dist/exceptions/HTTPExceptions.d.ts.map +1 -0
- package/dist/exceptions/HTTPExceptions.js +62 -0
- package/dist/exceptions/HTTPExceptions.js.map +1 -0
- package/dist/exceptions/baseHTTPException.d.ts +16 -0
- package/dist/exceptions/baseHTTPException.d.ts.map +1 -0
- package/dist/exceptions/baseHTTPException.js +25 -0
- package/dist/exceptions/baseHTTPException.js.map +1 -0
- package/dist/exceptions/defaultExceptionFilter.d.ts +10 -0
- package/dist/exceptions/defaultExceptionFilter.d.ts.map +1 -0
- package/dist/exceptions/defaultExceptionFilter.js +65 -0
- package/dist/exceptions/defaultExceptionFilter.js.map +1 -0
- package/dist/exceptions/exceptionFilter.d.ts +6 -0
- package/dist/exceptions/exceptionFilter.d.ts.map +1 -0
- package/dist/exceptions/exceptionFilter.js +3 -0
- package/dist/exceptions/exceptionFilter.js.map +1 -0
- package/dist/exceptions/exceptionHandler.d.ts +12 -0
- package/dist/exceptions/exceptionHandler.d.ts.map +1 -0
- package/dist/exceptions/exceptionHandler.js +50 -0
- package/dist/exceptions/exceptionHandler.js.map +1 -0
- package/dist/exceptions/index.d.ts +6 -0
- package/dist/exceptions/index.d.ts.map +1 -0
- package/dist/exceptions/index.js +22 -0
- package/dist/exceptions/index.js.map +1 -0
- package/dist/guards/Guard.d.ts +5 -0
- package/dist/guards/Guard.d.ts.map +1 -0
- package/dist/guards/Guard.js +3 -0
- package/dist/guards/Guard.js.map +1 -0
- package/dist/guards/applyGuard.d.ts +5 -0
- package/dist/guards/applyGuard.d.ts.map +1 -0
- package/dist/guards/applyGuard.js +15 -0
- package/dist/guards/applyGuard.js.map +1 -0
- package/dist/http/HttpRequest.d.ts +52 -0
- package/dist/http/HttpRequest.d.ts.map +1 -0
- package/dist/http/HttpRequest.js +103 -0
- package/dist/http/HttpRequest.js.map +1 -0
- package/dist/http/HttpResponse.d.ts +20 -0
- package/dist/http/HttpResponse.d.ts.map +1 -0
- package/dist/http/HttpResponse.js +63 -0
- package/dist/http/HttpResponse.js.map +1 -0
- package/dist/http/adapters/expressAdapter.d.ts +17 -0
- package/dist/http/adapters/expressAdapter.d.ts.map +1 -0
- package/dist/http/adapters/expressAdapter.js +91 -0
- package/dist/http/adapters/expressAdapter.js.map +1 -0
- package/dist/http/adapters/fastifyAdapter.d.ts +17 -0
- package/dist/http/adapters/fastifyAdapter.d.ts.map +1 -0
- package/dist/http/adapters/fastifyAdapter.js +91 -0
- package/dist/http/adapters/fastifyAdapter.js.map +1 -0
- package/dist/http/adapters/httpAdapter.d.ts +14 -0
- package/dist/http/adapters/httpAdapter.d.ts.map +1 -0
- package/dist/http/adapters/httpAdapter.js +3 -0
- package/dist/http/adapters/httpAdapter.js.map +1 -0
- package/dist/http/client/httpClient.d.ts +51 -0
- package/dist/http/client/httpClient.d.ts.map +1 -0
- package/dist/http/client/httpClient.js +163 -0
- package/dist/http/client/httpClient.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/injectable.js +12 -0
- package/dist/interceptor.js +44 -0
- package/dist/interceptors/Interceptor.d.ts +4 -0
- package/dist/interceptors/Interceptor.d.ts.map +1 -0
- package/dist/interceptors/Interceptor.js +3 -0
- package/dist/interceptors/Interceptor.js.map +1 -0
- package/dist/interceptors/applyInterceptor.d.ts +5 -0
- package/dist/interceptors/applyInterceptor.d.ts.map +1 -0
- package/dist/interceptors/applyInterceptor.js +22 -0
- package/dist/interceptors/applyInterceptor.js.map +1 -0
- package/dist/lifecycle/lifecycle.d.ts +23 -0
- package/dist/lifecycle/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle/lifecycle.js +3 -0
- package/dist/lifecycle/lifecycle.js.map +1 -0
- package/dist/main.js +6 -0
- package/dist/metadata.js +83 -0
- package/dist/middleware/middleware.d.ts +14 -0
- package/dist/middleware/middleware.d.ts.map +1 -0
- package/dist/middleware/middleware.js +41 -0
- package/dist/middleware/middleware.js.map +1 -0
- package/dist/middleware/type.d.ts +4 -0
- package/dist/middleware/type.d.ts.map +1 -0
- package/dist/middleware/type.js +3 -0
- package/dist/middleware/type.js.map +1 -0
- package/dist/paramRegistry.js +4 -0
- package/dist/request/createMethodDecorator.js +22 -0
- package/dist/request/createParamDecorator.js +46 -0
- package/dist/request/interceptor.js +44 -0
- package/dist/request/metadata.js +83 -0
- package/dist/request/paramRegistry.js +4 -0
- package/dist/request/resolveHandlerArgument.js +108 -0
- package/dist/request/routeMatch.js +24 -0
- package/dist/request/routeRegistry.js +107 -0
- package/dist/request/utils/normalizePath.js +16 -0
- package/dist/request/validation/rule.js +44 -0
- package/dist/request/validation/validationErrorException.js +8 -0
- package/dist/resolveHandlerArgument.js +33 -0
- package/dist/routeMatch.js +24 -0
- package/dist/routeRegistry.js +108 -0
- package/dist/routes.js +1 -0
- package/dist/routing/metadata.d.ts +19 -0
- package/dist/routing/metadata.d.ts.map +1 -0
- package/dist/routing/metadata.js +65 -0
- package/dist/routing/metadata.js.map +1 -0
- package/dist/routing/metadataKeys.d.ts +22 -0
- package/dist/routing/metadataKeys.d.ts.map +1 -0
- package/dist/routing/metadataKeys.js +19 -0
- package/dist/routing/metadataKeys.js.map +1 -0
- package/dist/routing/paramTypes.d.ts +18 -0
- package/dist/routing/paramTypes.d.ts.map +1 -0
- package/dist/routing/paramTypes.js +3 -0
- package/dist/routing/paramTypes.js.map +1 -0
- package/dist/routing/routeRegistry.d.ts +31 -0
- package/dist/routing/routeRegistry.d.ts.map +1 -0
- package/dist/routing/routeRegistry.js +99 -0
- package/dist/routing/routeRegistry.js.map +1 -0
- package/dist/simulateRequest.js +52 -0
- package/dist/utils/decoratorCheck.d.ts +3 -0
- package/dist/utils/decoratorCheck.d.ts.map +1 -0
- package/dist/utils/decoratorCheck.js +37 -0
- package/dist/utils/decoratorCheck.js.map +1 -0
- package/dist/utils/log.d.ts +7 -0
- package/dist/utils/log.d.ts.map +1 -0
- package/dist/utils/log.js +20 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/metadataKey.d.ts +9 -0
- package/dist/utils/metadataKey.d.ts.map +1 -0
- package/dist/utils/metadataKey.js +28 -0
- package/dist/utils/metadataKey.js.map +1 -0
- package/dist/utils/normalizePath.js +16 -0
- package/dist/validation/resolveHandlerArgument.d.ts +10 -0
- package/dist/validation/resolveHandlerArgument.d.ts.map +1 -0
- package/dist/validation/resolveHandlerArgument.js +112 -0
- package/dist/validation/resolveHandlerArgument.js.map +1 -0
- package/dist/validation/rule.d.ts +35 -0
- package/dist/validation/rule.d.ts.map +1 -0
- package/dist/validation/rule.js +45 -0
- package/dist/validation/rule.js.map +1 -0
- package/dist/validation/validationErrorException.d.ts +6 -0
- package/dist/validation/validationErrorException.d.ts.map +1 -0
- package/dist/validation/validationErrorException.js +9 -0
- package/dist/validation/validationErrorException.js.map +1 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
File without changes
|
package/README.md
ADDED
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
# mini-nest
|
|
2
|
+
|
|
3
|
+
A lightweight, NestJS-inspired BFF (Backend-for-Frontend) framework for Node.js.
|
|
4
|
+
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
[]()
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
English | [中文](README-CN.md)
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- 🎯 **Decorator-based** - Familiar NestJS-style decorators
|
|
15
|
+
- 💉 **Dependency Injection** - Automatic constructor injection
|
|
16
|
+
- 🛡️ **Guards & Interceptors** - Request pipeline control
|
|
17
|
+
- ⚡ **AOP Decorators** - `@Cache`, `@Retry`, `@Timeout`, `@CircuitBreaker`
|
|
18
|
+
- 🔗 **HTTP Client** - Built-in client with `aggregate()` for BFF patterns
|
|
19
|
+
- 🌳 **Trie-based Routing** - Fast route matching with params
|
|
20
|
+
- 🔄 **Lifecycle Hooks** - `OnInit`, `OnDestroy`, etc.
|
|
21
|
+
- 📦 **Lightweight** - Minimal dependencies, ~65% Express performance, ~90% fastify performance
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Design Boundaries
|
|
25
|
+
|
|
26
|
+
mini-nest is intentionally lightweight. Here's what it **does** and **doesn't** do:
|
|
27
|
+
|
|
28
|
+
| Feature | Status | Notes |
|
|
29
|
+
|---------|--------|-------|
|
|
30
|
+
| Singleton DI | ✅ | No request-scope support yet |
|
|
31
|
+
| Static routing | ✅ | No regex/wildcard patterns |
|
|
32
|
+
| JSON API | ✅ | No streaming/multipart built-in |
|
|
33
|
+
| Single-tenant | ✅ | Multi-tenant needs manual handling |
|
|
34
|
+
| Decorator-based | ✅ | No runtime route registration |
|
|
35
|
+
|
|
36
|
+
**Best for:**
|
|
37
|
+
- BFF (Backend-for-Frontend) layers
|
|
38
|
+
- Small to medium APIs
|
|
39
|
+
- Teams familiar with NestJS patterns
|
|
40
|
+
- Projects prioritizing simplicity over features
|
|
41
|
+
|
|
42
|
+
**Not ideal for:**
|
|
43
|
+
- Large monoliths needing module isolation
|
|
44
|
+
- Real-time streaming applications
|
|
45
|
+
- Multi-tenant SaaS (without custom work)
|
|
46
|
+
- Projects requiring request-scoped DI
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install mini-nest
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import 'reflect-metadata';
|
|
58
|
+
import { createMiniNestApp, Controller, Get, Injectable, Param } from 'mini-nest';
|
|
59
|
+
|
|
60
|
+
@Injectable()
|
|
61
|
+
class UserService {
|
|
62
|
+
getUser(id: string) {
|
|
63
|
+
return { id, name: 'Alice' };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@Controller('/api/users')
|
|
68
|
+
class UserController {
|
|
69
|
+
constructor(private userService: UserService) {}
|
|
70
|
+
|
|
71
|
+
@Get('/:id')
|
|
72
|
+
getUser(@Param('id') id: string) {
|
|
73
|
+
return this.userService.getUser(id);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const app = createMiniNestApp({
|
|
78
|
+
port: 3000,
|
|
79
|
+
controllers: [UserController],
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
app.listen(() => console.log('Server running on http://localhost:3000'));
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Documentation
|
|
86
|
+
|
|
87
|
+
### Controllers & Routes
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { Controller, Get, Post, Put, Delete, Patch } from 'mini-nest';
|
|
91
|
+
|
|
92
|
+
@Controller('/api/users')
|
|
93
|
+
class UserController {
|
|
94
|
+
@Get('/')
|
|
95
|
+
findAll() {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@Get('/:id')
|
|
100
|
+
findOne(@Param('id') id: string) {
|
|
101
|
+
return { id };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@Post('/')
|
|
105
|
+
create(@Body() data: any) {
|
|
106
|
+
return data;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@Put('/:id')
|
|
110
|
+
update(@Param('id') id: string, @Body() data: any) {
|
|
111
|
+
return { id, ...data };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@Delete('/:id')
|
|
115
|
+
remove(@Param('id') id: string) {
|
|
116
|
+
return { deleted: id };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Parameter Decorators
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { Body, Query, Param, Header } from 'mini-nest';
|
|
125
|
+
|
|
126
|
+
@Controller('/api')
|
|
127
|
+
class ExampleController {
|
|
128
|
+
@Post('/search')
|
|
129
|
+
search(
|
|
130
|
+
@Body() body: any, // Full body
|
|
131
|
+
@Body('query') query: string, // Specific field
|
|
132
|
+
@Query('page') page: string, // Query param
|
|
133
|
+
@Param('id') id: string, // Route param
|
|
134
|
+
@Header('authorization') auth: string // Header
|
|
135
|
+
) {
|
|
136
|
+
return { body, query, page, id, auth };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Dependency Injection
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { Injectable } from 'mini-nest';
|
|
145
|
+
|
|
146
|
+
@Injectable()
|
|
147
|
+
class DatabaseService {
|
|
148
|
+
query(sql: string) {
|
|
149
|
+
return [{ id: 1 }];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@Injectable()
|
|
154
|
+
class UserRepository {
|
|
155
|
+
constructor(private db: DatabaseService) {}
|
|
156
|
+
|
|
157
|
+
findAll() {
|
|
158
|
+
return this.db.query('SELECT * FROM users');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@Injectable()
|
|
163
|
+
class UserService {
|
|
164
|
+
constructor(private repo: UserRepository) {}
|
|
165
|
+
|
|
166
|
+
getUsers() {
|
|
167
|
+
return this.repo.findAll();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Guards
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { Injectable, Guard, UseGuard, ExecutionContext } from 'mini-nest';
|
|
176
|
+
|
|
177
|
+
@Injectable()
|
|
178
|
+
class AuthGuard implements Guard {
|
|
179
|
+
canActivate(ctx: ExecutionContext): boolean {
|
|
180
|
+
const request = ctx.getRequest();
|
|
181
|
+
const token = request.header('authorization');
|
|
182
|
+
return token === 'Bearer valid-token';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@Controller('/api/admin')
|
|
187
|
+
class AdminController {
|
|
188
|
+
@Get('/dashboard')
|
|
189
|
+
@UseGuard([AuthGuard])
|
|
190
|
+
getDashboard() {
|
|
191
|
+
return { data: 'secret' };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Interceptors
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
import { Injectable, Interceptor, UseInterceptor } from 'mini-nest';
|
|
200
|
+
|
|
201
|
+
@Injectable()
|
|
202
|
+
class LoggingInterceptor implements Interceptor {
|
|
203
|
+
async intercept(next: () => Promise<unknown>) {
|
|
204
|
+
console.log('Before...');
|
|
205
|
+
const result = await next();
|
|
206
|
+
console.log('After...');
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@Injectable()
|
|
212
|
+
class TransformInterceptor implements Interceptor {
|
|
213
|
+
async intercept(next: () => Promise<unknown>) {
|
|
214
|
+
const result = await next();
|
|
215
|
+
return { data: result, timestamp: Date.now() };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
@Controller('/api')
|
|
220
|
+
@UseInterceptor(LoggingInterceptor)
|
|
221
|
+
class ApiController {
|
|
222
|
+
@Get('/data')
|
|
223
|
+
@UseInterceptor(TransformInterceptor)
|
|
224
|
+
getData() {
|
|
225
|
+
return { message: 'Hello' };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### AOP Decorators
|
|
231
|
+
|
|
232
|
+
#### @Cache
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { Cache } from 'mini-nest';
|
|
236
|
+
|
|
237
|
+
@Injectable()
|
|
238
|
+
class DataService {
|
|
239
|
+
@Cache({ ttl: 60 }) // Cache for 60 seconds
|
|
240
|
+
getExpensiveData() {
|
|
241
|
+
return computeExpensiveOperation();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@Cache({ ttl: 300, key: 'custom-key' })
|
|
245
|
+
getWithCustomKey() {
|
|
246
|
+
return data;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### @Retry
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { Retry } from 'mini-nest';
|
|
255
|
+
|
|
256
|
+
@Injectable()
|
|
257
|
+
class ExternalApiService {
|
|
258
|
+
@Retry(3) // Retry up to 3 times with exponential backoff
|
|
259
|
+
async fetchData() {
|
|
260
|
+
return await fetch('https://api.example.com/data');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
#### @Timeout
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
import { Timeout } from 'mini-nest';
|
|
269
|
+
|
|
270
|
+
@Injectable()
|
|
271
|
+
class SlowService {
|
|
272
|
+
@Timeout(5000) // Timeout after 5 seconds
|
|
273
|
+
async slowOperation() {
|
|
274
|
+
return await longRunningTask();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### @CircuitBreaker
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { CircuitBreaker } from 'mini-nest';
|
|
283
|
+
|
|
284
|
+
@Injectable()
|
|
285
|
+
class RiskyService {
|
|
286
|
+
@CircuitBreaker({
|
|
287
|
+
failureThreshold: 5, // Open after 5 failures
|
|
288
|
+
resetTimeout: 30000 // Try again after 30s
|
|
289
|
+
})
|
|
290
|
+
async callExternalService() {
|
|
291
|
+
return await externalApi.call();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### HttpClient
|
|
297
|
+
|
|
298
|
+
Built-in HTTP client with retry, timeout, and aggregation support:
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
import { Injectable, HttpClient } from 'mini-nest';
|
|
302
|
+
|
|
303
|
+
@Injectable()
|
|
304
|
+
class ApiService {
|
|
305
|
+
constructor(private http: HttpClient) {}
|
|
306
|
+
|
|
307
|
+
async getUser(id: string) {
|
|
308
|
+
const res = await this.http.get(`https://api.example.com/users/${id}`);
|
|
309
|
+
return res.data;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
async createUser(data: any) {
|
|
313
|
+
const res = await this.http.post('https://api.example.com/users', data);
|
|
314
|
+
return res.data;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### Aggregate (BFF Pattern)
|
|
320
|
+
|
|
321
|
+
Combine multiple API calls into a single response:
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
@Injectable()
|
|
325
|
+
class BffService {
|
|
326
|
+
constructor(private http: HttpClient) {}
|
|
327
|
+
|
|
328
|
+
async getUserProfile(userId: string) {
|
|
329
|
+
const { data, errors } = await this.http.aggregate({
|
|
330
|
+
baseUrl: 'https://api.example.com',
|
|
331
|
+
params: { id: userId },
|
|
332
|
+
sources: {
|
|
333
|
+
user: '/users/:id',
|
|
334
|
+
posts: '/users/:id/posts',
|
|
335
|
+
followers: '/users/:id/followers',
|
|
336
|
+
},
|
|
337
|
+
output: (sources) => ({
|
|
338
|
+
id: sources.user.id,
|
|
339
|
+
name: sources.user.name,
|
|
340
|
+
postCount: sources.posts.length,
|
|
341
|
+
followerCount: sources.followers.length,
|
|
342
|
+
}),
|
|
343
|
+
timeout: 5000,
|
|
344
|
+
partial: true, // Continue even if some requests fail
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
return data;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Lifecycle Hooks
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
import { Injectable, OnInit, OnDestroy } from 'mini-nest';
|
|
356
|
+
|
|
357
|
+
@Injectable()
|
|
358
|
+
class DatabaseService implements OnInit, OnDestroy {
|
|
359
|
+
private connection: any;
|
|
360
|
+
|
|
361
|
+
OnInit() {
|
|
362
|
+
console.log('Connecting to database...');
|
|
363
|
+
this.connection = createConnection();
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
OnDestroy() {
|
|
367
|
+
console.log('Closing database connection...');
|
|
368
|
+
this.connection.close();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Validation
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
import { Query, Body, rule } from 'mini-nest';
|
|
377
|
+
|
|
378
|
+
@Controller('/api')
|
|
379
|
+
class ValidationController {
|
|
380
|
+
@Get('/search')
|
|
381
|
+
search(
|
|
382
|
+
@Query({
|
|
383
|
+
key: 'page',
|
|
384
|
+
validator: rule().required().min(1)
|
|
385
|
+
})
|
|
386
|
+
page: number,
|
|
387
|
+
|
|
388
|
+
@Query({
|
|
389
|
+
key: 'email',
|
|
390
|
+
validator: rule().required().pattern(/^[\w-]+@[\w-]+\.\w+$/)
|
|
391
|
+
})
|
|
392
|
+
email: string
|
|
393
|
+
) {
|
|
394
|
+
return { page, email };
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
@Post('/users')
|
|
398
|
+
createUser(
|
|
399
|
+
@Body({
|
|
400
|
+
key: 'name',
|
|
401
|
+
validator: rule().required().minLength(2).maxLength(50)
|
|
402
|
+
})
|
|
403
|
+
name: string
|
|
404
|
+
) {
|
|
405
|
+
return { name };
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Exception Handling
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
import {
|
|
414
|
+
NotFoundException,
|
|
415
|
+
BadRequestException,
|
|
416
|
+
UnauthorizedException,
|
|
417
|
+
ForbiddenException,
|
|
418
|
+
InternalServerErrorException
|
|
419
|
+
} from 'mini-nest';
|
|
420
|
+
|
|
421
|
+
@Controller('/api/users')
|
|
422
|
+
class UserController {
|
|
423
|
+
@Get('/:id')
|
|
424
|
+
getUser(@Param('id') id: string) {
|
|
425
|
+
const user = findUser(id);
|
|
426
|
+
if (!user) {
|
|
427
|
+
throw new NotFoundException(`User ${id} not found`);
|
|
428
|
+
}
|
|
429
|
+
return user;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Custom exception filter:
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
import { ExceptionFilter, ExecutionContext } from 'mini-nest';
|
|
438
|
+
|
|
439
|
+
class CustomExceptionFilter implements ExceptionFilter {
|
|
440
|
+
canHandle(exception: unknown): boolean {
|
|
441
|
+
return exception instanceof CustomError;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
catch(exception: CustomError, context: ExecutionContext) {
|
|
445
|
+
const response = context.getResponse();
|
|
446
|
+
response.status(400).json({
|
|
447
|
+
error: 'CustomError',
|
|
448
|
+
message: exception.message,
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Configuration
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
const app = createMiniNestApp({
|
|
458
|
+
port: 3000,
|
|
459
|
+
adapter: 'express' | 'fastify',
|
|
460
|
+
controllers: [UserController, PostController],
|
|
461
|
+
https: { // Optional HTTPS
|
|
462
|
+
key: '/path/to/key.pem',
|
|
463
|
+
cert: '/path/to/cert.pem',
|
|
464
|
+
},
|
|
465
|
+
});
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
## Benchmark
|
|
469
|
+
|
|
470
|
+
Compared against Express and Fastify (10s, 100 connections):
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
| Framework | Requests | Relative |
|
|
474
|
+
|-----------|----------|----------|
|
|
475
|
+
| Fastify (raw) | 2,544,032 | 100% |
|
|
476
|
+
| mini-nest + Fastify | 2,290,571 | 90.0% |
|
|
477
|
+
| Express (raw) | 1,742,452 | 68.5% |
|
|
478
|
+
| mini-nest + Express | 1,739,737 | 68.4% |
|
|
479
|
+
|
|
480
|
+
mini-nest performs comparably to Express while providing:
|
|
481
|
+
- Dependency Injection
|
|
482
|
+
- Decorator-based routing
|
|
483
|
+
- AOP features (Cache, Retry, Timeout, CircuitBreaker)
|
|
484
|
+
- Guards & Interceptors
|
|
485
|
+
- Built-in HTTP client with aggregation
|
|
486
|
+
|
|
487
|
+
Run benchmarks locally:
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
npm run benchmark
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
## Project Structure
|
|
494
|
+
|
|
495
|
+
```
|
|
496
|
+
src/
|
|
497
|
+
├── core/
|
|
498
|
+
│ ├── app/ # Application bootstrap
|
|
499
|
+
│ ├── container/ # DI container
|
|
500
|
+
│ └── pipeline/ # Request pipeline
|
|
501
|
+
├── decorators/
|
|
502
|
+
│ ├── http/ # @Controller, @Get, @Post, etc.
|
|
503
|
+
│ └── aop/ # @Cache, @Retry, @Timeout, @CircuitBreaker
|
|
504
|
+
├── http/
|
|
505
|
+
│ ├── adapters/ # Express and Fastify adapter
|
|
506
|
+
│ └── client/ # HttpClient
|
|
507
|
+
├── guards/ # Guard system
|
|
508
|
+
├── interceptors/ # Interceptor system
|
|
509
|
+
├── exceptions/ # Exception handling
|
|
510
|
+
├── routing/ # Trie-based router
|
|
511
|
+
├── validation/ # Parameter validation
|
|
512
|
+
└── lifecycle/ # Lifecycle hooks
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
## Requirements
|
|
516
|
+
|
|
517
|
+
- Node.js 18+
|
|
518
|
+
- TypeScript 5.0+
|
|
519
|
+
- `experimentalDecorators: true`
|
|
520
|
+
- `emitDecoratorMetadata: true`
|
|
521
|
+
|
|
522
|
+
tsconfig.json:
|
|
523
|
+
|
|
524
|
+
```json
|
|
525
|
+
{
|
|
526
|
+
"compilerOptions": {
|
|
527
|
+
"target": "ES2020",
|
|
528
|
+
"module": "CommonJS",
|
|
529
|
+
"experimentalDecorators": true, //very important
|
|
530
|
+
"emitDecoratorMetadata": true, //very important
|
|
531
|
+
"esModuleInterop": true,
|
|
532
|
+
"strict": true
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
## Testing
|
|
538
|
+
|
|
539
|
+
```bash
|
|
540
|
+
# Run tests
|
|
541
|
+
npm test
|
|
542
|
+
|
|
543
|
+
# Run with coverage
|
|
544
|
+
npm run test:coverage
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
## Roadmap
|
|
548
|
+
|
|
549
|
+
- [ ] Module system (`@Module()`)
|
|
550
|
+
- [ ] WebSocket support
|
|
551
|
+
- [ ] OpenAPI/Swagger generation
|
|
552
|
+
- [ ] CLI tool
|
|
553
|
+
|
|
554
|
+
## License
|
|
555
|
+
|
|
556
|
+
MIT
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Constructor } from "../core/container/container";
|
|
2
|
+
import { CacheOptions } from "../decorators/aop/Cache";
|
|
3
|
+
import { CircuitBreakerOptions } from "../decorators/aop/CircuitBreaker";
|
|
4
|
+
export interface AOPContext {
|
|
5
|
+
target: Object;
|
|
6
|
+
method: Function;
|
|
7
|
+
args: any[];
|
|
8
|
+
methodName: string;
|
|
9
|
+
className: string;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
retry?: number;
|
|
12
|
+
cache?: CacheOptions;
|
|
13
|
+
circuitBreaker?: CircuitBreakerOptions;
|
|
14
|
+
}
|
|
15
|
+
export declare function wrapWithAOP<T extends object>(instance: T, token: Constructor<T>): T;
|
|
16
|
+
export declare function executeWithAOP(ctx: AOPContext): Promise<any>;
|
|
17
|
+
//# sourceMappingURL=aopWrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aopWrapper.d.ts","sourceRoot":"","sources":["../../src/aop/aopWrapper.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAGzE,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,cAAc,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAkCnF;AAID,wBAAsB,cAAc,CAAC,GAAG,EAAE,UAAU,gBA8DnD"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapWithAOP = wrapWithAOP;
|
|
4
|
+
exports.executeWithAOP = executeWithAOP;
|
|
5
|
+
const cacheManager_1 = require("../cache/cacheManager");
|
|
6
|
+
const circuitBreakerManager_1 = require("../circuitBreaker/circuitBreakerManager");
|
|
7
|
+
const circuitOpenError_1 = require("../circuitBreaker/circuitOpenError");
|
|
8
|
+
const metadataKeys_1 = require("../routing/metadataKeys");
|
|
9
|
+
function wrapWithAOP(instance, token) {
|
|
10
|
+
const proto = token.prototype;
|
|
11
|
+
return new Proxy(instance, {
|
|
12
|
+
get(target, prop, receiver) {
|
|
13
|
+
const original = Reflect.get(target, prop, receiver);
|
|
14
|
+
if (typeof original !== 'function') {
|
|
15
|
+
return original;
|
|
16
|
+
}
|
|
17
|
+
const propKey = String(prop);
|
|
18
|
+
const timeout = metadataKeys_1.TIMEOUT.get(proto, propKey);
|
|
19
|
+
const cache = metadataKeys_1.CACHE.get(proto, propKey);
|
|
20
|
+
const retry = metadataKeys_1.RETRY.get(proto, propKey);
|
|
21
|
+
const circuitBreaker = metadataKeys_1.CIRCUITBREAKER.get(proto, propKey);
|
|
22
|
+
if (timeout === undefined && cache === undefined && retry === undefined && circuitBreaker === undefined) {
|
|
23
|
+
return original.bind(target);
|
|
24
|
+
}
|
|
25
|
+
return async function (...args) {
|
|
26
|
+
return executeWithAOP({
|
|
27
|
+
target,
|
|
28
|
+
method: original,
|
|
29
|
+
args,
|
|
30
|
+
methodName: propKey,
|
|
31
|
+
className: token.name,
|
|
32
|
+
timeout,
|
|
33
|
+
cache,
|
|
34
|
+
retry,
|
|
35
|
+
circuitBreaker
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
async function executeWithAOP(ctx) {
|
|
42
|
+
const { target, method, args, timeout, className, methodName, retry, cache, circuitBreaker } = ctx;
|
|
43
|
+
const circuitKey = `${className}-${methodName}`;
|
|
44
|
+
if (circuitBreaker) {
|
|
45
|
+
const { failureThreshold = 5, resetTimeout = 30000 } = circuitBreaker;
|
|
46
|
+
const { allowed, reason } = circuitBreakerManager_1.circuitBreakerManager.canExecute(circuitKey, resetTimeout);
|
|
47
|
+
if (!allowed) {
|
|
48
|
+
throw new circuitOpenError_1.CircuitOpenError(reason);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const cacheKey = cache
|
|
52
|
+
? (cache.key ?? `${className}:${methodName}:${JSON.stringify(args)}`)
|
|
53
|
+
: null;
|
|
54
|
+
if (cacheKey && cacheManager_1.cacheManager.has(cacheKey)) {
|
|
55
|
+
return cacheManager_1.cacheManager.get(cacheKey);
|
|
56
|
+
}
|
|
57
|
+
//build execution function
|
|
58
|
+
const execute = async () => {
|
|
59
|
+
const promise = method.apply(target, args);
|
|
60
|
+
if (timeout === undefined) {
|
|
61
|
+
return promise;
|
|
62
|
+
}
|
|
63
|
+
return withTimeout(promise, timeout);
|
|
64
|
+
};
|
|
65
|
+
try {
|
|
66
|
+
const result = retry !== undefined ? await withRetry(execute, retry) : await execute();
|
|
67
|
+
if (circuitBreaker) {
|
|
68
|
+
circuitBreakerManager_1.circuitBreakerManager.recordSuccess(circuitKey);
|
|
69
|
+
}
|
|
70
|
+
if (cacheKey && cache) {
|
|
71
|
+
cacheManager_1.cacheManager.set(cacheKey, result, cache.ttl);
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (circuitBreaker) {
|
|
77
|
+
const { failureThreshold = 5 } = circuitBreaker;
|
|
78
|
+
circuitBreakerManager_1.circuitBreakerManager.recordFailure(circuitKey, failureThreshold);
|
|
79
|
+
}
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function withTimeout(promise, ms) {
|
|
84
|
+
return Promise.race([
|
|
85
|
+
promise,
|
|
86
|
+
new Promise((_, reject) => {
|
|
87
|
+
return setTimeout(() => reject(new Error(`Request timeout after ${ms}ms`)), ms);
|
|
88
|
+
})
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
function delay(ms) {
|
|
92
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
93
|
+
}
|
|
94
|
+
async function withRetry(fn, maxRetryTime) {
|
|
95
|
+
let lastError;
|
|
96
|
+
for (let attempt = 0; attempt <= maxRetryTime; attempt++) {
|
|
97
|
+
try {
|
|
98
|
+
return await fn();
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (!(error instanceof Error)) {
|
|
102
|
+
error = new Error(String(error));
|
|
103
|
+
}
|
|
104
|
+
lastError = error;
|
|
105
|
+
if (attempt < maxRetryTime) {
|
|
106
|
+
await delay(100 * Math.pow(2, attempt));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
throw lastError;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=aopWrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aopWrapper.js","sourceRoot":"","sources":["../../src/aop/aopWrapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare class CacheManager {
|
|
2
|
+
private cache;
|
|
3
|
+
get<T>(key: string | symbol): T | undefined;
|
|
4
|
+
set(key: string | symbol, value: any, ttlSeconds: number): void;
|
|
5
|
+
delete(key: string | symbol): void;
|
|
6
|
+
clear(): void;
|
|
7
|
+
has(key: string | symbol): boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const cacheManager: CacheManager;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=cacheManager.d.ts.map
|