@riktajs/core 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +96 -161
  2. package/dist/core/constants.d.ts +4 -0
  3. package/dist/core/constants.d.ts.map +1 -1
  4. package/dist/core/constants.js +5 -1
  5. package/dist/core/constants.js.map +1 -1
  6. package/dist/core/decorators/controller.decorator.d.ts.map +1 -1
  7. package/dist/core/decorators/controller.decorator.js +1 -0
  8. package/dist/core/decorators/controller.decorator.js.map +1 -1
  9. package/dist/core/decorators/param.decorator.d.ts +111 -11
  10. package/dist/core/decorators/param.decorator.d.ts.map +1 -1
  11. package/dist/core/decorators/param.decorator.js +87 -8
  12. package/dist/core/decorators/param.decorator.js.map +1 -1
  13. package/dist/core/exceptions/index.d.ts +1 -0
  14. package/dist/core/exceptions/index.d.ts.map +1 -1
  15. package/dist/core/exceptions/index.js +4 -1
  16. package/dist/core/exceptions/index.js.map +1 -1
  17. package/dist/core/exceptions/validation.exception.d.ts +60 -0
  18. package/dist/core/exceptions/validation.exception.d.ts.map +1 -0
  19. package/dist/core/exceptions/validation.exception.js +71 -0
  20. package/dist/core/exceptions/validation.exception.js.map +1 -0
  21. package/dist/core/guards/can-activate.interface.d.ts +77 -0
  22. package/dist/core/guards/can-activate.interface.d.ts.map +1 -0
  23. package/dist/core/guards/can-activate.interface.js +3 -0
  24. package/dist/core/guards/can-activate.interface.js.map +1 -0
  25. package/dist/core/guards/execution-context.d.ts +72 -0
  26. package/dist/core/guards/execution-context.d.ts.map +1 -0
  27. package/dist/core/guards/execution-context.js +37 -0
  28. package/dist/core/guards/execution-context.js.map +1 -0
  29. package/dist/core/guards/index.d.ts +4 -0
  30. package/dist/core/guards/index.d.ts.map +1 -0
  31. package/dist/core/guards/index.js +10 -0
  32. package/dist/core/guards/index.js.map +1 -0
  33. package/dist/core/guards/use-guards.decorator.d.ts +82 -0
  34. package/dist/core/guards/use-guards.decorator.d.ts.map +1 -0
  35. package/dist/core/guards/use-guards.decorator.js +104 -0
  36. package/dist/core/guards/use-guards.decorator.js.map +1 -0
  37. package/dist/core/index.d.ts +3 -0
  38. package/dist/core/index.d.ts.map +1 -1
  39. package/dist/core/index.js +7 -0
  40. package/dist/core/index.js.map +1 -1
  41. package/dist/core/router/router.d.ts +9 -1
  42. package/dist/core/router/router.d.ts.map +1 -1
  43. package/dist/core/router/router.js +68 -5
  44. package/dist/core/router/router.js.map +1 -1
  45. package/package.json +3 -2
package/README.md CHANGED
@@ -1,205 +1,140 @@
1
- # 🔧 Rikta Framework
1
+ # 🧭 Rikta
2
2
 
3
- A modern TypeScript backend framework with zero-config autowiring, powered by Fastify.
3
+ > **The Zero-Config TypeScript Framework for Modern Backends.**
4
+
5
+ Build scalable APIs with the power of Fastify and the elegance of decorators. No modules. No boilerplate. Just code.
4
6
 
5
- ## âœĻ Features
7
+ [![NPM Version](https://img.shields.io/npm/v/@riktajs/core)](https://www.npmjs.com/package/@riktajs/core)
8
+ [![License](https://img.shields.io/npm/l/@riktajs/core)](LICENSE)
6
9
 
7
- - ðŸŽŊ **Decorator-based routing** - `@Controller`, `@Get`, `@Post`, etc.
8
- - 💉 **Full Autowiring** - No modules needed, everything is auto-discovered
9
- - 🔌 **Single DI decorator** - `@Autowired()` for everything
10
- - 🔄 **Hybrid Lifecycle** - Interface hooks + EventBus
11
- - ðŸ›Ąïļ **Exception Handling** - Built-in filters with standardized JSON responses
12
- - ⚡ **Fastify under the hood** - Maximum performance
13
- - 🔒 **Type-safe** - Full TypeScript support
14
- - ðŸŠķ **Zero config** - Just decorate and run
10
+ ---
15
11
 
16
- ## ðŸ“Ķ Installation
12
+ ## ðŸĪ” Why Rikta?
13
+
14
+ Are you tired of **"Module Hell"** in NestJS? Do you miss the simplicity of Express but need the structure of a real framework?
15
+
16
+ **Rikta** is designed for developers who want to move fast without breaking things.
17
+
18
+ * 🚀 **Zero-Config Autowiring:** No `imports: []`, `exports: []`, or `providers: []` arrays. Just decorate your class, and it works.
19
+ * ⚡ **Fastify Powered:** Built on top of Fastify for maximum performance and low overhead.
20
+ * ðŸ›Ąïļ **Type-Safe by Default:** Native Zod integration for validation that infers your TypeScript types automatically.
21
+ * 🔄 **Hybrid Lifecycle:** Powerful hooks and an event bus for complex application flows.
22
+
23
+ Rikta is nordic for "guide". Let Rikta guide you to build better backends, faster.
24
+
25
+ ---
26
+
27
+ ## ⚡ Quick Start
28
+
29
+ ### 1. Install
17
30
 
18
31
  ```bash
19
- npm install
32
+ npm install @riktajs/core
20
33
  ```
21
34
 
22
- ## 🚀 Quick Start
35
+ ### 2. Create your App
36
+
37
+ No complex setup. Just one file is enough to start.
23
38
 
24
39
  ```typescript
25
- import { Rikta, Controller, Injectable, Get, Autowired } from '@rikta/core';
40
+ // main.ts
41
+ import { Rikta, Controller, Injectable, Get, Post, Body, Autowired, z } from '@riktajs/core';
26
42
 
43
+ // 1. Define a Service (Auto-discovered!)
27
44
  @Injectable()
28
- class GreetingService {
29
- getGreeting(): string {
30
- return 'Hello from Rikta!';
45
+ class UserService {
46
+ private users = [{ id: 1, name: 'Rikta User' }];
47
+
48
+ findAll() { return this.users; }
49
+
50
+ create(name: string) {
51
+ const user = { id: this.users.length + 1, name };
52
+ this.users.push(user);
53
+ return user;
31
54
  }
32
55
  }
33
56
 
34
- @Controller()
35
- export class AppController {
57
+ // 2. Define a Schema (Type-safe!)
58
+ const CreateUserSchema = z.object({
59
+ name: z.string().min(3)
60
+ });
61
+
62
+ // 3. Define a Controller (Auto-discovered!)
63
+ @Controller('/users')
64
+ export class UserController {
36
65
  @Autowired()
37
- private greetingService!: GreetingService;
66
+ private userService!: UserService; // Dependency Injection works like magic
38
67
 
39
- @Get('/')
40
- getHello() {
41
- return this.greetingService.getGreeting();
68
+ @Get()
69
+ getUsers() {
70
+ return this.userService.findAll();
71
+ }
72
+
73
+ @Post()
74
+ createUser(@Body(CreateUserSchema) body: z.infer<typeof CreateUserSchema>) {
75
+ // 'body' is fully typed here!
76
+ return this.userService.create(body.name);
42
77
  }
43
78
  }
44
79
 
45
- // No modules - just create and run!
46
- const app = await Rikta.create({ port: 3000 });
80
+ // 4. Run it!
81
+ const app = await Rikta.create({ port: 3000, autowired: [__dirname] });
47
82
  await app.listen();
83
+ console.log('🚀 Server running on http://localhost:3000');
48
84
  ```
49
85
 
50
- ## 📚 Documentation
51
-
52
- | Section | Description |
53
- |---------|-------------|
54
- | [Core Architecture](./src/core/README.md) | Framework internals |
55
- | [Dependency Injection](./src/core/container/README.md) | DI, tokens, autowiring |
56
- | [Lifecycle](./src/core/lifecycle/README.md) | Hooks, events, priority |
57
- | [Exception Handling](./src/core/exceptions/README.md) | Errors, filters, responses |
58
- | [Decorators](./src/core/decorators/README.md) | All decorators reference |
59
- | [Router](./src/core/router/README.md) | Routing and requests |
60
- | [Example](./example/README.md) | Working code example |
61
-
62
- ## 🏃 Running Example
63
-
64
- ```bash
65
- npm run example # Full-featured CRUD with lifecycle hooks
66
- ```
67
-
68
- ## ⚙ïļ Configuration
86
+ ---
69
87
 
70
- ```typescript
71
- const app = await Rikta.create({
72
- port: 3000, // Server port
73
- host: '0.0.0.0', // Server host
74
- logger: true, // Fastify logging
75
- prefix: '/api/v1', // Global prefix
76
-
77
- // Auto-discovery paths (default: ['./**'] - scans all files)
78
- autowired: ['./src/controllers', './src/services'],
79
-
80
- // Optional: explicit controller list (skips auto-discovery)
81
- controllers: [UserController, AppController],
82
-
83
- // Exception handling configuration
84
- exceptionFilter: {
85
- includeStack: process.env.NODE_ENV !== 'production',
86
- logErrors: true,
87
- },
88
-
89
- // Custom exception filters
90
- exceptionFilters: [ValidationExceptionFilter],
91
- });
92
- ```
88
+ ## 📚 Documentation
93
89
 
94
- ### Auto-Discovery
90
+ Everything you need to build production-ready APIs.
95
91
 
96
- Rikta automatically scans and imports files to discover `@Controller` and `@Injectable` classes:
92
+ | Guide | Description |
93
+ |-------|-------------|
94
+ | [**Architecture**](./docs/guide/architecture.md) | How Rikta's auto-discovery works under the hood. |
95
+ | [**Dependency Injection**](./docs/guide/dependency-injection.md) | Using `@Autowired`, tokens, and scopes. |
96
+ | [**Routing**](./docs/guide/routing.md) | Controllers, methods, and parameter handling. |
97
+ | [**Validation**](./docs/guide/validation.md) | **New!** Type-safe validation with Zod. |
98
+ | [**Lifecycle**](./docs/guide/lifecycle.md) | Hooks (`OnProviderInit`) and the Event Bus. |
99
+ | [**Error Handling**](./docs/guide/error-handling.md) | Exception filters and standard JSON responses. |
97
100
 
98
- ```typescript
99
- // Scan specific directories
100
- await Rikta.create({
101
- autowired: ['./src/controllers', './src/services']
102
- });
101
+ ---
103
102
 
104
- // Scan with glob patterns
105
- await Rikta.create({
106
- autowired: ['./src/**/*.controller.ts', './src/**/*.service.ts']
107
- });
103
+ ## âœĻ Key Features
108
104
 
109
- // Default: scans current directory recursively
110
- await Rikta.create({ port: 3000 });
111
- ```
105
+ ### ðŸšŦ No Modules, Just Logic
106
+ Forget about `AppModule`, `UserModule`, `SharedModule`. Rikta scans your code and resolves dependencies automatically.
112
107
 
113
- ## 🔄 Lifecycle Hooks
108
+ ### ✅ Native Zod Validation
109
+ Don't duplicate your types. Define a Zod schema, and Rikta validates the request *and* gives you the TypeScript type.
114
110
 
115
111
  ```typescript
116
- @Injectable({ priority: 100 }) // Higher = initialized first
117
- class DatabaseService implements OnProviderInit, OnProviderDestroy {
118
- async onProviderInit() {
119
- await this.connect();
120
- }
121
-
122
- async onProviderDestroy() {
123
- await this.disconnect();
124
- }
125
- }
126
-
127
- // Or use @On() decorator for events
128
- @Injectable()
129
- class MonitoringService {
130
- @On('app:listen')
131
- onServerStart({ address }) {
132
- console.log(`Server at ${address}`);
133
- }
112
+ @Post()
113
+ create(@Body(UserSchema) user: z.infer<typeof UserSchema>) {
114
+ // If we get here, 'user' is valid and typed.
115
+ // If not, Rikta returns a 400 Bad Request automatically.
134
116
  }
135
117
  ```
136
118
 
137
- See [Lifecycle Documentation](./src/core/lifecycle/README.md) for full details.
138
-
139
- ## ðŸ›Ąïļ Exception Handling
119
+ ### 🔌 Powerful Dependency Injection
120
+ Support for Singleton (default) and Transient scopes, factory providers, and value tokens.
140
121
 
141
122
  ```typescript
142
- import {
143
- NotFoundException,
144
- BadRequestException,
145
- HttpException
146
- } from '@rikta/core';
147
-
148
- @Controller('/users')
149
- class UserController {
150
- @Get('/:id')
151
- async getUser(@Param('id') id: string) {
152
- const user = await this.userService.findById(id);
153
-
154
- if (!user) {
155
- throw new NotFoundException(`User ${id} not found`);
156
- }
157
-
158
- return user;
159
- }
160
-
161
- @Post()
162
- async create(@Body() data: CreateUserDto) {
163
- if (!data.email) {
164
- throw new BadRequestException({
165
- message: 'Validation failed',
166
- details: { email: 'Email is required' }
167
- });
168
- }
169
- }
170
- }
171
- ```
172
-
173
- **Standard JSON Response:**
174
- ```json
175
- {
176
- "statusCode": 404,
177
- "message": "User 123 not found",
178
- "error": "Not Found",
179
- "timestamp": "2024-01-15T10:30:00.000Z",
180
- "path": "/users/123"
123
+ @Injectable()
124
+ class AuthService {
125
+ constructor(
126
+ @Autowired(DB_CONFIG) private config: Config,
127
+ @Autowired() private logger: LoggerService
128
+ ) {}
181
129
  }
182
130
  ```
183
131
 
184
- **Available Exceptions:** `BadRequestException`, `UnauthorizedException`, `ForbiddenException`, `NotFoundException`, `ConflictException`, `UnprocessableEntityException`, `TooManyRequestsException`, `InternalServerErrorException`, `ServiceUnavailableException`, and more.
132
+ ---
185
133
 
186
- See [Exception Handling Documentation](./src/core/exceptions/README.md) for full details.
134
+ ## ðŸĪ Contributing
187
135
 
188
- ## 📁 Project Structure
189
-
190
- ```
191
- rikta/
192
- ├── src/core/
193
- │ ├── container/ # Dependency Injection
194
- │ ├── decorators/ # All decorators
195
- │ ├── exceptions/ # Error handling & filters
196
- │ ├── lifecycle/ # Hooks & EventBus
197
- │ ├── router/ # Route handling
198
- │ ├── registry.ts # Auto-discovery registry
199
- │ └── application.ts # Bootstrap
200
- └── example/ # Full-featured example
201
- ```
136
+ We love contributions! Please check our [Contributing Guide](CONTRIBUTING.md) (Coming Soon) and join our community.
202
137
 
203
- ## 📜 License
138
+ ## 📄 License
204
139
 
205
- MIT
140
+ Rikta is [MIT licensed](LICENSE).
@@ -38,6 +38,10 @@ export declare const HEADERS_METADATA: unique symbol;
38
38
  * Key for storing @Inject() metadata on constructor parameters
39
39
  */
40
40
  export declare const INJECT_METADATA: unique symbol;
41
+ /**
42
+ * Key for storing Zod validation schema on parameters
43
+ */
44
+ export declare const ZOD_SCHEMA_METADATA: unique symbol;
41
45
  /**
42
46
  * Key for storing @Autowired() property injection metadata
43
47
  */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,gBAAgB,eAA6B,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,eAA8B,CAAC;AAE7D;;GAEG;AACH,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,gBAAgB,eAA6B,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,eAA8B,CAAC;AAE7D;;GAEG;AACH,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC"}
@@ -3,7 +3,7 @@
3
3
  // Metadata Keys for Reflect API
4
4
  // ============================================================================
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DEFAULT_CONFIG = exports.ParamType = exports.PROVIDER_METADATA = exports.AUTOWIRED_METADATA = exports.INJECT_METADATA = exports.HEADERS_METADATA = exports.HTTP_CODE_METADATA = exports.MIDDLEWARE_METADATA = exports.INTERCEPTORS_METADATA = exports.GUARDS_METADATA = exports.PARAM_METADATA = exports.INJECTABLE_METADATA = exports.ROUTES_METADATA = exports.CONTROLLER_METADATA = void 0;
6
+ exports.DEFAULT_CONFIG = exports.ParamType = exports.PROVIDER_METADATA = exports.AUTOWIRED_METADATA = exports.ZOD_SCHEMA_METADATA = exports.INJECT_METADATA = exports.HEADERS_METADATA = exports.HTTP_CODE_METADATA = exports.MIDDLEWARE_METADATA = exports.INTERCEPTORS_METADATA = exports.GUARDS_METADATA = exports.PARAM_METADATA = exports.INJECTABLE_METADATA = exports.ROUTES_METADATA = exports.CONTROLLER_METADATA = void 0;
7
7
  /**
8
8
  * Key for storing controller metadata (prefix, routes)
9
9
  */
@@ -44,6 +44,10 @@ exports.HEADERS_METADATA = Symbol('headers:metadata');
44
44
  * Key for storing @Inject() metadata on constructor parameters
45
45
  */
46
46
  exports.INJECT_METADATA = Symbol('inject:metadata');
47
+ /**
48
+ * Key for storing Zod validation schema on parameters
49
+ */
50
+ exports.ZOD_SCHEMA_METADATA = Symbol('zod:schema:metadata');
47
51
  /**
48
52
  * Key for storing @Autowired() property injection metadata
49
53
  */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;;;AAE/E;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEvD;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,qBAAqB,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAErE;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE3D;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE7D;;GAEG;AACH,IAAY,SAQX;AARD,WAAY,SAAS;IACnB,0BAAa,CAAA;IACb,4BAAe,CAAA;IACf,4BAAe,CAAA;IACf,gCAAmB,CAAA;IACnB,gCAAmB,CAAA;IACnB,4BAAe,CAAA;IACf,gCAAmB,CAAA;AACrB,CAAC,EARW,SAAS,yBAAT,SAAS,QAQpB;AAED;;GAEG;AACU,QAAA,cAAc,GAAG;IAC5B,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,EAAE;CACF,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;;;AAE/E;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEvD;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,qBAAqB,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAErE;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE3D;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE7D;;GAEG;AACH,IAAY,SAQX;AARD,WAAY,SAAS;IACnB,0BAAa,CAAA;IACb,4BAAe,CAAA;IACf,4BAAe,CAAA;IACf,gCAAmB,CAAA;IACnB,gCAAmB,CAAA;IACnB,4BAAe,CAAA;IACf,gCAAmB,CAAA;AACrB,CAAC,EARW,SAAS,yBAAT,SAAS,QAQpB;AAED;;GAEG;AACU,QAAA,cAAc,GAAG;IAC5B,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,EAAE;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"controller.decorator.d.ts","sourceRoot":"","sources":["../../../src/core/decorators/controller.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAK1B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,UAAU,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,cAAc,CAuBvF"}
1
+ {"version":3,"file":"controller.decorator.d.ts","sourceRoot":"","sources":["../../../src/core/decorators/controller.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAK1B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,UAAU,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,cAAc,CAwBvF"}
@@ -42,6 +42,7 @@ function Controller(prefixOrOptions) {
42
42
  // Mark as injectable
43
43
  Reflect.defineMetadata(constants_1.INJECTABLE_METADATA, { scope: 'singleton' }, target);
44
44
  // Register in DI container
45
+ console.log(`ïŋ― Controller registered: ${target.name} (prefix: '${normalizedPrefix}')`);
45
46
  container_1.container.register(target, { scope: 'singleton' });
46
47
  // Auto-register in global registry for discovery
47
48
  registry_1.registry.registerController(target);
@@ -1 +1 @@
1
- {"version":3,"file":"controller.decorator.js","sourceRoot":"","sources":["../../../src/core/decorators/controller.decorator.ts"],"names":[],"mappings":";;AAoCA,gCAuBC;AA3DD,4BAA0B;AAC1B,4CAAwE;AACxE,sDAAmD;AACnD,0CAAuC;AAUvC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,SAAgB,UAAU,CAAC,eAA4C;IACrE,OAAO,CAAC,MAAgB,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,OAAO,eAAe,KAAK,QAAQ;YAChD,CAAC,CAAC,eAAe;YACjB,CAAC,CAAC,eAAe,EAAE,MAAM,IAAI,EAAE,CAAC;QAElC,0DAA0D;QAC1D,MAAM,gBAAgB,GAAG,MAAM;YAC7B,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC;YAClD,CAAC,CAAC,EAAE,CAAC;QAEP,4BAA4B;QAC5B,OAAO,CAAC,cAAc,CAAC,+BAAmB,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,MAAM,CAAC,CAAC;QAElF,qBAAqB;QACrB,OAAO,CAAC,cAAc,CAAC,+BAAmB,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;QAE5E,2BAA2B;QAC3B,qBAAS,CAAC,QAAQ,CAAC,MAA6C,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAE1F,iDAAiD;QACjD,mBAAQ,CAAC,kBAAkB,CAAC,MAA6C,CAAC,CAAC;IAC7E,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"controller.decorator.js","sourceRoot":"","sources":["../../../src/core/decorators/controller.decorator.ts"],"names":[],"mappings":";;AAoCA,gCAwBC;AA5DD,4BAA0B;AAC1B,4CAAwE;AACxE,sDAAmD;AACnD,0CAAuC;AAUvC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,SAAgB,UAAU,CAAC,eAA4C;IACrE,OAAO,CAAC,MAAgB,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,OAAO,eAAe,KAAK,QAAQ;YAChD,CAAC,CAAC,eAAe;YACjB,CAAC,CAAC,eAAe,EAAE,MAAM,IAAI,EAAE,CAAC;QAElC,0DAA0D;QAC1D,MAAM,gBAAgB,GAAG,MAAM;YAC7B,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC;YAClD,CAAC,CAAC,EAAE,CAAC;QAEP,4BAA4B;QAC5B,OAAO,CAAC,cAAc,CAAC,+BAAmB,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,MAAM,CAAC,CAAC;QAElF,qBAAqB;QACrB,OAAO,CAAC,cAAc,CAAC,+BAAmB,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;QAE5E,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,IAAI,cAAc,gBAAgB,IAAI,CAAC,CAAC;QACvF,qBAAS,CAAC,QAAQ,CAAC,MAA6C,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAE1F,iDAAiD;QACjD,mBAAQ,CAAC,kBAAkB,CAAC,MAA6C,CAAC,CAAC;IAC7E,CAAC,CAAC;AACJ,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import 'reflect-metadata';
2
+ import type { ZodType } from 'zod';
2
3
  import { ParamType } from '../constants';
3
4
  /**
4
5
  * Parameter metadata structure
@@ -7,66 +8,165 @@ export interface ParamMetadata {
7
8
  index: number;
8
9
  type: ParamType;
9
10
  key?: string;
11
+ /** Optional Zod schema for validation and type inference */
12
+ zodSchema?: ZodType<unknown>;
10
13
  }
11
14
  /**
12
15
  * @Body() decorator - Injects the request body
13
16
  *
17
+ * Supports three modes:
18
+ * 1. `@Body()` - Inject the entire request body
19
+ * 2. `@Body('propertyName')` - Inject a specific property from the body
20
+ * 3. `@Body(zodSchema)` - Validate and inject with type inference
21
+ *
14
22
  * @example
15
23
  * ```typescript
24
+ * // Inject entire body (untyped)
16
25
  * @Post('/users')
17
- * createUser(@Body({ schema: CreateUserDto }) data) { return data; }
26
+ * createUser(@Body() data: unknown) { return data; }
18
27
  *
28
+ * // Inject specific property
19
29
  * @Post('/users')
20
30
  * createUser(@Body('name') name: string) { return { name }; }
31
+ *
32
+ * // Validate with Zod schema (type-safe!)
33
+ * const CreateUserSchema = z.object({ name: z.string(), email: z.string().email() });
34
+ * @Post('/users')
35
+ * createUser(@Body(CreateUserSchema) data: z.infer<typeof CreateUserSchema>) {
36
+ * // data is fully typed as { name: string; email: string }
37
+ * return data;
38
+ * }
21
39
  * ```
22
40
  */
23
- export declare const Body: (key?: string) => ParameterDecorator;
41
+ export declare const Body: {
42
+ (): ParameterDecorator;
43
+ (key: string): ParameterDecorator;
44
+ <T>(schema: ZodType<T>): ParameterDecorator;
45
+ };
24
46
  /**
25
47
  * @Query() decorator - Injects query parameters
26
48
  *
49
+ * Supports three modes:
50
+ * 1. `@Query()` - Inject all query parameters
51
+ * 2. `@Query('paramName')` - Inject a specific query parameter
52
+ * 3. `@Query(zodSchema)` - Validate and inject with type inference
53
+ *
27
54
  * @example
28
55
  * ```typescript
56
+ * // Inject specific query param
29
57
  * @Get('/users')
30
58
  * getUsers(@Query('page') page: string) { return { page }; }
31
59
  *
60
+ * // Inject all query params
32
61
  * @Get('/users')
33
62
  * getUsers(@Query() query: Record<string, unknown>) { return query; }
63
+ *
64
+ * // Validate with Zod schema
65
+ * const PaginationSchema = z.object({ page: z.coerce.number(), limit: z.coerce.number() });
66
+ * @Get('/users')
67
+ * getUsers(@Query(PaginationSchema) query: z.infer<typeof PaginationSchema>) {
68
+ * // query is { page: number; limit: number }
69
+ * return query;
70
+ * }
34
71
  * ```
35
72
  */
36
- export declare const Query: (key?: string) => ParameterDecorator;
73
+ export declare const Query: {
74
+ (): ParameterDecorator;
75
+ (key: string): ParameterDecorator;
76
+ <T>(schema: ZodType<T>): ParameterDecorator;
77
+ };
37
78
  /**
38
79
  * @Param() decorator - Injects route parameters
39
80
  *
81
+ * Supports three modes:
82
+ * 1. `@Param()` - Inject all route parameters
83
+ * 2. `@Param('paramName')` - Inject a specific route parameter
84
+ * 3. `@Param(zodSchema)` - Validate and inject with type inference
85
+ *
40
86
  * @example
41
87
  * ```typescript
88
+ * // Inject specific param
42
89
  * @Get('/users/:id')
43
90
  * getUser(@Param('id') id: string) { return { id }; }
91
+ *
92
+ * // Validate with Zod schema
93
+ * const IdSchema = z.object({ id: z.string().uuid() });
94
+ * @Get('/users/:id')
95
+ * getUser(@Param(IdSchema) params: z.infer<typeof IdSchema>) {
96
+ * // params.id is validated as UUID
97
+ * return params;
98
+ * }
44
99
  * ```
45
100
  */
46
- export declare const Param: (key?: string) => ParameterDecorator;
101
+ export declare const Param: {
102
+ (): ParameterDecorator;
103
+ (key: string): ParameterDecorator;
104
+ <T>(schema: ZodType<T>): ParameterDecorator;
105
+ };
47
106
  /**
48
107
  * @Headers() decorator - Injects request headers
49
108
  *
109
+ * Supports three modes:
110
+ * 1. `@Headers()` - Inject all headers
111
+ * 2. `@Headers('headerName')` - Inject a specific header
112
+ * 3. `@Headers(zodSchema)` - Validate and inject with type inference
113
+ *
50
114
  * @example
51
115
  * ```typescript
116
+ * // Inject specific header
52
117
  * @Get('/protected')
53
118
  * getData(@Headers('authorization') auth: string) { return { auth }; }
119
+ *
120
+ * // Validate with Zod schema
121
+ * const AuthHeadersSchema = z.object({ authorization: z.string().startsWith('Bearer ') });
122
+ * @Get('/protected')
123
+ * getData(@Headers(AuthHeadersSchema) headers: z.infer<typeof AuthHeadersSchema>) {
124
+ * return headers;
125
+ * }
54
126
  * ```
55
127
  */
56
- export declare const Headers: (key?: string) => ParameterDecorator;
128
+ export declare const Headers: {
129
+ (): ParameterDecorator;
130
+ (key: string): ParameterDecorator;
131
+ <T>(schema: ZodType<T>): ParameterDecorator;
132
+ };
57
133
  /**
58
134
  * @Req() decorator - Injects the raw Fastify request object
59
135
  */
60
- export declare const Req: (key?: string) => ParameterDecorator;
61
- export declare const Request: (key?: string) => ParameterDecorator;
136
+ export declare const Req: {
137
+ (): ParameterDecorator;
138
+ (key: string): ParameterDecorator;
139
+ <T>(schema: ZodType<T>): ParameterDecorator;
140
+ };
141
+ export declare const Request: {
142
+ (): ParameterDecorator;
143
+ (key: string): ParameterDecorator;
144
+ <T>(schema: ZodType<T>): ParameterDecorator;
145
+ };
62
146
  /**
63
147
  * @Res() decorator - Injects the raw Fastify reply object
64
148
  */
65
- export declare const Res: (key?: string) => ParameterDecorator;
66
- export declare const Reply: (key?: string) => ParameterDecorator;
149
+ export declare const Res: {
150
+ (): ParameterDecorator;
151
+ (key: string): ParameterDecorator;
152
+ <T>(schema: ZodType<T>): ParameterDecorator;
153
+ };
154
+ export declare const Reply: {
155
+ (): ParameterDecorator;
156
+ (key: string): ParameterDecorator;
157
+ <T>(schema: ZodType<T>): ParameterDecorator;
158
+ };
67
159
  /**
68
160
  * @Ctx() decorator - Injects the full route context
69
161
  */
70
- export declare const Ctx: (key?: string) => ParameterDecorator;
71
- export declare const Context: (key?: string) => ParameterDecorator;
162
+ export declare const Ctx: {
163
+ (): ParameterDecorator;
164
+ (key: string): ParameterDecorator;
165
+ <T>(schema: ZodType<T>): ParameterDecorator;
166
+ };
167
+ export declare const Context: {
168
+ (): ParameterDecorator;
169
+ (key: string): ParameterDecorator;
170
+ <T>(schema: ZodType<T>): ParameterDecorator;
171
+ };
72
172
  //# sourceMappingURL=param.decorator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"param.decorator.d.ts","sourceRoot":"","sources":["../../../src/core/decorators/param.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAkB,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA2BD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,IAAI,SAjCD,MAAM,KAAG,kBAiC+B,CAAC;AAEzD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,KAAK,SA/CF,MAAM,KAAG,kBA+CiC,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,KAAK,SA1DF,MAAM,KAAG,kBA0DiC,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,SArEJ,MAAM,KAAG,kBAqEqC,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,GAAG,SA1EA,MAAM,KAAG,kBA0EiC,CAAC;AAC3D,eAAO,MAAM,OAAO,SA3EJ,MAAM,KAAG,kBA2EC,CAAC;AAE3B;;GAEG;AACH,eAAO,MAAM,GAAG,SAhFA,MAAM,KAAG,kBAgF+B,CAAC;AACzD,eAAO,MAAM,KAAK,SAjFF,MAAM,KAAG,kBAiFD,CAAC;AAEzB;;GAEG;AACH,eAAO,MAAM,GAAG,SAtFA,MAAM,KAAG,kBAsFiC,CAAC;AAC3D,eAAO,MAAM,OAAO,SAvFJ,MAAM,KAAG,kBAuFC,CAAC"}
1
+ {"version":3,"file":"param.decorator.d.ts","sourceRoot":"","sources":["../../../src/core/decorators/param.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,EAAkB,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9B;AA2DD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,IAAI;QA5DO,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CA0DP,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,KAAK;QAzFM,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CAuFL,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,KAAK;QAlHM,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CAgHL,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,OAAO;QA1II,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CAwID,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,GAAG;QA/IQ,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CA6IL,CAAC;AAC3D,eAAO,MAAM,OAAO;QAhJI,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CA8IrC,CAAC;AAE3B;;GAEG;AACH,eAAO,MAAM,GAAG;QArJQ,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CAmJP,CAAC;AACzD,eAAO,MAAM,KAAK;QAtJM,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CAoJvC,CAAC;AAEzB;;GAEG;AACH,eAAO,MAAM,GAAG;QA3JQ,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CAyJL,CAAC;AAC3D,eAAO,MAAM,OAAO;QA5JI,kBAAkB;UAChB,MAAM,GAAG,kBAAkB;KAChC,CAAC,UAAU,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB;CA0JrC,CAAC"}