@riktajs/core 0.1.0 â 0.2.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/README.md +128 -9
- package/dist/core/constants.d.ts +4 -0
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +5 -1
- package/dist/core/constants.js.map +1 -1
- package/dist/core/decorators/controller.decorator.d.ts.map +1 -1
- package/dist/core/decorators/controller.decorator.js +1 -0
- package/dist/core/decorators/controller.decorator.js.map +1 -1
- package/dist/core/decorators/param.decorator.d.ts +111 -11
- package/dist/core/decorators/param.decorator.d.ts.map +1 -1
- package/dist/core/decorators/param.decorator.js +87 -8
- package/dist/core/decorators/param.decorator.js.map +1 -1
- package/dist/core/exceptions/index.d.ts +1 -0
- package/dist/core/exceptions/index.d.ts.map +1 -1
- package/dist/core/exceptions/index.js +4 -1
- package/dist/core/exceptions/index.js.map +1 -1
- package/dist/core/exceptions/validation.exception.d.ts +60 -0
- package/dist/core/exceptions/validation.exception.d.ts.map +1 -0
- package/dist/core/exceptions/validation.exception.js +71 -0
- package/dist/core/exceptions/validation.exception.js.map +1 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/router/router.d.ts +1 -1
- package/dist/core/router/router.d.ts.map +1 -1
- package/dist/core/router/router.js +24 -5
- package/dist/core/router/router.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ A modern TypeScript backend framework with zero-config autowiring, powered by Fa
|
|
|
9
9
|
- ð **Single DI decorator** - `@Autowired()` for everything
|
|
10
10
|
- ð **Hybrid Lifecycle** - Interface hooks + EventBus
|
|
11
11
|
- ðĄïļ **Exception Handling** - Built-in filters with standardized JSON responses
|
|
12
|
+
- â
**Zod Validation** - Native type-safe validation with automatic type inference
|
|
12
13
|
- ⥠**Fastify under the hood** - Maximum performance
|
|
13
14
|
- ð **Type-safe** - Full TypeScript support
|
|
14
15
|
- ðŠķ **Zero config** - Just decorate and run
|
|
@@ -43,7 +44,7 @@ export class AppController {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
// No modules - just create and run!
|
|
46
|
-
const app = await Rikta.create({ port: 3000 });
|
|
47
|
+
const app = await Rikta.create({ port: 3000, autowired: [__dirname] });
|
|
47
48
|
await app.listen();
|
|
48
49
|
```
|
|
49
50
|
|
|
@@ -75,7 +76,7 @@ const app = await Rikta.create({
|
|
|
75
76
|
prefix: '/api/v1', // Global prefix
|
|
76
77
|
|
|
77
78
|
// Auto-discovery paths (default: ['./**'] - scans all files)
|
|
78
|
-
autowired: ['./src/controllers', './src/services'],
|
|
79
|
+
autowired: [path.resolve('./src/controllers'), path.resolve('./src/services')],
|
|
79
80
|
|
|
80
81
|
// Optional: explicit controller list (skips auto-discovery)
|
|
81
82
|
controllers: [UserController, AppController],
|
|
@@ -98,16 +99,11 @@ Rikta automatically scans and imports files to discover `@Controller` and `@Inje
|
|
|
98
99
|
```typescript
|
|
99
100
|
// Scan specific directories
|
|
100
101
|
await Rikta.create({
|
|
101
|
-
autowired: ['./src/controllers'
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// Scan with glob patterns
|
|
105
|
-
await Rikta.create({
|
|
106
|
-
autowired: ['./src/**/*.controller.ts', './src/**/*.service.ts']
|
|
102
|
+
autowired: [path.resolve('./src/controllers')]
|
|
107
103
|
});
|
|
108
104
|
|
|
109
105
|
// Default: scans current directory recursively
|
|
110
|
-
await Rikta.create({ port: 3000 });
|
|
106
|
+
await Rikta.create({ port: 3000, autowired: [path.resolve('.')] });
|
|
111
107
|
```
|
|
112
108
|
|
|
113
109
|
## ð Lifecycle Hooks
|
|
@@ -185,6 +181,129 @@ class UserController {
|
|
|
185
181
|
|
|
186
182
|
See [Exception Handling Documentation](./src/core/exceptions/README.md) for full details.
|
|
187
183
|
|
|
184
|
+
## â
Zod Validation
|
|
185
|
+
|
|
186
|
+
Rikta has **native Zod integration** for type-safe request validation. Define schemas once and get both runtime validation and TypeScript type inference automatically.
|
|
187
|
+
|
|
188
|
+
### Basic Usage
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import { Controller, Post, Body, Query, z } from '@riktajs/core';
|
|
192
|
+
|
|
193
|
+
// Define your schema
|
|
194
|
+
const CreateUserSchema = z.object({
|
|
195
|
+
name: z.string().min(1, 'Name is required'),
|
|
196
|
+
email: z.string().email('Invalid email format'),
|
|
197
|
+
age: z.number().int().positive().optional(),
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Type is automatically inferred!
|
|
201
|
+
type CreateUser = z.infer<typeof CreateUserSchema>;
|
|
202
|
+
|
|
203
|
+
@Controller('/users')
|
|
204
|
+
class UserController {
|
|
205
|
+
@Post()
|
|
206
|
+
create(@Body(CreateUserSchema) data: CreateUser) {
|
|
207
|
+
// data is fully typed as { name: string; email: string; age?: number }
|
|
208
|
+
// Validation happens automatically before this method is called
|
|
209
|
+
return { success: true, user: data };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Validation Error Response
|
|
215
|
+
|
|
216
|
+
When validation fails, Rikta automatically returns a structured 400 response:
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"statusCode": 400,
|
|
221
|
+
"message": "Validation failed for body",
|
|
222
|
+
"error": "Validation Error",
|
|
223
|
+
"timestamp": "2024-01-15T10:30:00.000Z",
|
|
224
|
+
"path": "/users",
|
|
225
|
+
"details": {
|
|
226
|
+
"errors": [
|
|
227
|
+
{ "path": ["email"], "message": "Invalid email format", "code": "invalid_string" },
|
|
228
|
+
{ "path": ["name"], "message": "Name is required", "code": "too_small" }
|
|
229
|
+
],
|
|
230
|
+
"errorCount": 2
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### All Decorators Support Zod
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
import { z, Controller, Get, Post, Body, Query, Param, Headers } from '@riktajs/core';
|
|
239
|
+
|
|
240
|
+
// Query validation with coercion
|
|
241
|
+
const PaginationSchema = z.object({
|
|
242
|
+
page: z.coerce.number().int().positive().default(1),
|
|
243
|
+
limit: z.coerce.number().int().max(100).default(10),
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Route params validation
|
|
247
|
+
const IdSchema = z.object({
|
|
248
|
+
id: z.string().uuid('Invalid UUID format'),
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Headers validation
|
|
252
|
+
const AuthSchema = z.object({
|
|
253
|
+
authorization: z.string().startsWith('Bearer '),
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
@Controller('/items')
|
|
257
|
+
class ItemController {
|
|
258
|
+
@Get()
|
|
259
|
+
list(@Query(PaginationSchema) query: z.infer<typeof PaginationSchema>) {
|
|
260
|
+
// query.page and query.limit are numbers (coerced from string)
|
|
261
|
+
return { page: query.page, limit: query.limit };
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@Get('/:id')
|
|
265
|
+
findOne(
|
|
266
|
+
@Param(IdSchema) params: z.infer<typeof IdSchema>,
|
|
267
|
+
@Headers(AuthSchema) headers: z.infer<typeof AuthSchema>
|
|
268
|
+
) {
|
|
269
|
+
return { id: params.id };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Zod Transformations
|
|
275
|
+
|
|
276
|
+
Zod's transform feature works seamlessly:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
const DateSchema = z.object({
|
|
280
|
+
date: z.string().transform(val => new Date(val)),
|
|
281
|
+
tags: z.string().transform(val => val.split(',')),
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
@Post('/events')
|
|
285
|
+
create(@Body(DateSchema) data: z.infer<typeof DateSchema>) {
|
|
286
|
+
// data.date is a Date object
|
|
287
|
+
// data.tags is string[]
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Backward Compatibility
|
|
292
|
+
|
|
293
|
+
Existing code without Zod schemas continues to work:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// These still work as before
|
|
297
|
+
@Get('/:id')
|
|
298
|
+
findOne(@Param('id') id: string) { ... }
|
|
299
|
+
|
|
300
|
+
@Post()
|
|
301
|
+
create(@Body() data: unknown) { ... }
|
|
302
|
+
|
|
303
|
+
@Get()
|
|
304
|
+
list(@Query('page') page: string) { ... }
|
|
305
|
+
```
|
|
306
|
+
|
|
188
307
|
## ð Project Structure
|
|
189
308
|
|
|
190
309
|
```
|
package/dist/core/constants.d.ts
CHANGED
|
@@ -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"}
|
package/dist/core/constants.js
CHANGED
|
@@ -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,
|
|
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,
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
61
|
-
|
|
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:
|
|
66
|
-
|
|
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:
|
|
71
|
-
|
|
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;
|
|
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"}
|
|
@@ -4,69 +4,148 @@ exports.Context = exports.Ctx = exports.Reply = exports.Res = exports.Request =
|
|
|
4
4
|
require("reflect-metadata");
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Type guard to check if a value is a Zod schema
|
|
8
|
+
* Uses duck typing to detect Zod schemas without importing the full library
|
|
9
|
+
*/
|
|
10
|
+
function isZodType(value) {
|
|
11
|
+
return (value !== null &&
|
|
12
|
+
typeof value === 'object' &&
|
|
13
|
+
'_def' in value &&
|
|
14
|
+
'safeParse' in value &&
|
|
15
|
+
typeof value.safeParse === 'function');
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates a type-safe parameter decorator factory with Zod schema support
|
|
19
|
+
*
|
|
20
|
+
* Supports three overloads:
|
|
21
|
+
* 1. @Decorator() - Inject the full value
|
|
22
|
+
* 2. @Decorator('key') - Inject a specific property by key
|
|
23
|
+
* 3. @Decorator(zodSchema) - Inject with validation and type inference
|
|
8
24
|
*/
|
|
9
25
|
function createParamDecorator(type) {
|
|
10
|
-
|
|
26
|
+
function decorator(keyOrSchema) {
|
|
11
27
|
return (target, propertyKey, parameterIndex) => {
|
|
12
28
|
if (propertyKey === undefined)
|
|
13
29
|
return;
|
|
14
30
|
// Get existing params or initialize empty array
|
|
15
31
|
const existingParams = Reflect.getMetadata(constants_1.PARAM_METADATA, target.constructor, propertyKey) ?? [];
|
|
16
|
-
//
|
|
17
|
-
|
|
32
|
+
// Determine if we have a key string or a Zod schema
|
|
33
|
+
const isSchema = isZodType(keyOrSchema);
|
|
34
|
+
// Build metadata object
|
|
35
|
+
const metadata = {
|
|
18
36
|
index: parameterIndex,
|
|
19
37
|
type,
|
|
20
|
-
key,
|
|
21
|
-
|
|
38
|
+
key: isSchema ? undefined : keyOrSchema,
|
|
39
|
+
zodSchema: isSchema ? keyOrSchema : undefined,
|
|
40
|
+
};
|
|
41
|
+
// Add this param
|
|
42
|
+
existingParams.push(metadata);
|
|
22
43
|
// Store updated params
|
|
23
44
|
Reflect.defineMetadata(constants_1.PARAM_METADATA, existingParams, target.constructor, propertyKey);
|
|
24
45
|
};
|
|
25
|
-
}
|
|
46
|
+
}
|
|
47
|
+
return decorator;
|
|
26
48
|
}
|
|
27
49
|
/**
|
|
28
50
|
* @Body() decorator - Injects the request body
|
|
29
51
|
*
|
|
52
|
+
* Supports three modes:
|
|
53
|
+
* 1. `@Body()` - Inject the entire request body
|
|
54
|
+
* 2. `@Body('propertyName')` - Inject a specific property from the body
|
|
55
|
+
* 3. `@Body(zodSchema)` - Validate and inject with type inference
|
|
56
|
+
*
|
|
30
57
|
* @example
|
|
31
58
|
* ```typescript
|
|
59
|
+
* // Inject entire body (untyped)
|
|
32
60
|
* @Post('/users')
|
|
33
|
-
* createUser(@Body(
|
|
61
|
+
* createUser(@Body() data: unknown) { return data; }
|
|
34
62
|
*
|
|
63
|
+
* // Inject specific property
|
|
35
64
|
* @Post('/users')
|
|
36
65
|
* createUser(@Body('name') name: string) { return { name }; }
|
|
66
|
+
*
|
|
67
|
+
* // Validate with Zod schema (type-safe!)
|
|
68
|
+
* const CreateUserSchema = z.object({ name: z.string(), email: z.string().email() });
|
|
69
|
+
* @Post('/users')
|
|
70
|
+
* createUser(@Body(CreateUserSchema) data: z.infer<typeof CreateUserSchema>) {
|
|
71
|
+
* // data is fully typed as { name: string; email: string }
|
|
72
|
+
* return data;
|
|
73
|
+
* }
|
|
37
74
|
* ```
|
|
38
75
|
*/
|
|
39
76
|
exports.Body = createParamDecorator(constants_1.ParamType.BODY);
|
|
40
77
|
/**
|
|
41
78
|
* @Query() decorator - Injects query parameters
|
|
42
79
|
*
|
|
80
|
+
* Supports three modes:
|
|
81
|
+
* 1. `@Query()` - Inject all query parameters
|
|
82
|
+
* 2. `@Query('paramName')` - Inject a specific query parameter
|
|
83
|
+
* 3. `@Query(zodSchema)` - Validate and inject with type inference
|
|
84
|
+
*
|
|
43
85
|
* @example
|
|
44
86
|
* ```typescript
|
|
87
|
+
* // Inject specific query param
|
|
45
88
|
* @Get('/users')
|
|
46
89
|
* getUsers(@Query('page') page: string) { return { page }; }
|
|
47
90
|
*
|
|
91
|
+
* // Inject all query params
|
|
48
92
|
* @Get('/users')
|
|
49
93
|
* getUsers(@Query() query: Record<string, unknown>) { return query; }
|
|
94
|
+
*
|
|
95
|
+
* // Validate with Zod schema
|
|
96
|
+
* const PaginationSchema = z.object({ page: z.coerce.number(), limit: z.coerce.number() });
|
|
97
|
+
* @Get('/users')
|
|
98
|
+
* getUsers(@Query(PaginationSchema) query: z.infer<typeof PaginationSchema>) {
|
|
99
|
+
* // query is { page: number; limit: number }
|
|
100
|
+
* return query;
|
|
101
|
+
* }
|
|
50
102
|
* ```
|
|
51
103
|
*/
|
|
52
104
|
exports.Query = createParamDecorator(constants_1.ParamType.QUERY);
|
|
53
105
|
/**
|
|
54
106
|
* @Param() decorator - Injects route parameters
|
|
55
107
|
*
|
|
108
|
+
* Supports three modes:
|
|
109
|
+
* 1. `@Param()` - Inject all route parameters
|
|
110
|
+
* 2. `@Param('paramName')` - Inject a specific route parameter
|
|
111
|
+
* 3. `@Param(zodSchema)` - Validate and inject with type inference
|
|
112
|
+
*
|
|
56
113
|
* @example
|
|
57
114
|
* ```typescript
|
|
115
|
+
* // Inject specific param
|
|
58
116
|
* @Get('/users/:id')
|
|
59
117
|
* getUser(@Param('id') id: string) { return { id }; }
|
|
118
|
+
*
|
|
119
|
+
* // Validate with Zod schema
|
|
120
|
+
* const IdSchema = z.object({ id: z.string().uuid() });
|
|
121
|
+
* @Get('/users/:id')
|
|
122
|
+
* getUser(@Param(IdSchema) params: z.infer<typeof IdSchema>) {
|
|
123
|
+
* // params.id is validated as UUID
|
|
124
|
+
* return params;
|
|
125
|
+
* }
|
|
60
126
|
* ```
|
|
61
127
|
*/
|
|
62
128
|
exports.Param = createParamDecorator(constants_1.ParamType.PARAM);
|
|
63
129
|
/**
|
|
64
130
|
* @Headers() decorator - Injects request headers
|
|
65
131
|
*
|
|
132
|
+
* Supports three modes:
|
|
133
|
+
* 1. `@Headers()` - Inject all headers
|
|
134
|
+
* 2. `@Headers('headerName')` - Inject a specific header
|
|
135
|
+
* 3. `@Headers(zodSchema)` - Validate and inject with type inference
|
|
136
|
+
*
|
|
66
137
|
* @example
|
|
67
138
|
* ```typescript
|
|
139
|
+
* // Inject specific header
|
|
68
140
|
* @Get('/protected')
|
|
69
141
|
* getData(@Headers('authorization') auth: string) { return { auth }; }
|
|
142
|
+
*
|
|
143
|
+
* // Validate with Zod schema
|
|
144
|
+
* const AuthHeadersSchema = z.object({ authorization: z.string().startsWith('Bearer ') });
|
|
145
|
+
* @Get('/protected')
|
|
146
|
+
* getData(@Headers(AuthHeadersSchema) headers: z.infer<typeof AuthHeadersSchema>) {
|
|
147
|
+
* return headers;
|
|
148
|
+
* }
|
|
70
149
|
* ```
|
|
71
150
|
*/
|
|
72
151
|
exports.Headers = createParamDecorator(constants_1.ParamType.HEADERS);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"param.decorator.js","sourceRoot":"","sources":["../../../src/core/decorators/param.decorator.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;
|
|
1
|
+
{"version":3,"file":"param.decorator.js","sourceRoot":"","sources":["../../../src/core/decorators/param.decorator.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAE1B,4CAAyD;AAazD;;;GAGG;AACH,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,CACL,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,MAAM,IAAI,KAAK;QACf,WAAW,IAAI,KAAK;QACpB,OAAQ,KAAgC,CAAC,SAAS,KAAK,UAAU,CAClE,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAAC,IAAe;IAK3C,SAAS,SAAS,CAAI,WAAiC;QACrD,OAAO,CAAC,MAAc,EAAE,WAAwC,EAAE,cAAsB,EAAE,EAAE;YAC1F,IAAI,WAAW,KAAK,SAAS;gBAAE,OAAO;YAEtC,gDAAgD;YAChD,MAAM,cAAc,GAClB,OAAO,CAAC,WAAW,CAAC,0BAAc,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;YAE7E,oDAAoD;YACpD,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;YAExC,wBAAwB;YACxB,MAAM,QAAQ,GAAkB;gBAC9B,KAAK,EAAE,cAAc;gBACrB,IAAI;gBACJ,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW;gBACvC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;aAC9C,CAAC;YAEF,iBAAiB;YACjB,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAE9B,uBAAuB;YACvB,OAAO,CAAC,cAAc,CAAC,0BAAc,EAAE,cAAc,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAC1F,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACU,QAAA,IAAI,GAAG,oBAAoB,CAAC,qBAAS,CAAC,IAAI,CAAC,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACU,QAAA,KAAK,GAAG,oBAAoB,CAAC,qBAAS,CAAC,KAAK,CAAC,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACU,QAAA,KAAK,GAAG,oBAAoB,CAAC,qBAAS,CAAC,KAAK,CAAC,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACU,QAAA,OAAO,GAAG,oBAAoB,CAAC,qBAAS,CAAC,OAAO,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,GAAG,GAAG,oBAAoB,CAAC,qBAAS,CAAC,OAAO,CAAC,CAAC;AAC9C,QAAA,OAAO,GAAG,WAAG,CAAC;AAE3B;;GAEG;AACU,QAAA,GAAG,GAAG,oBAAoB,CAAC,qBAAS,CAAC,KAAK,CAAC,CAAC;AAC5C,QAAA,KAAK,GAAG,WAAG,CAAC;AAEzB;;GAEG;AACU,QAAA,GAAG,GAAG,oBAAoB,CAAC,qBAAS,CAAC,OAAO,CAAC,CAAC;AAC9C,QAAA,OAAO,GAAG,WAAG,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { HttpException, HttpExceptionBody, HttpExceptionResponse } from './http-exception';
|
|
2
|
+
export { ValidationException, ValidationErrorDetails } from './validation.exception';
|
|
2
3
|
export { BadRequestException, UnauthorizedException, ForbiddenException, NotFoundException, MethodNotAllowedException, NotAcceptableException, RequestTimeoutException, ConflictException, GoneException, PayloadTooLargeException, UnsupportedMediaTypeException, UnprocessableEntityException, TooManyRequestsException, InternalServerErrorException, NotImplementedException, BadGatewayException, ServiceUnavailableException, GatewayTimeoutException, } from './exceptions';
|
|
3
4
|
export { ExceptionFilter, ExceptionContext, ErrorResponse, GlobalExceptionFilter, GlobalExceptionFilterOptions, createExceptionHandler, } from './exception-filter';
|
|
4
5
|
export { Catch, CatchMetadata, CATCH_METADATA, getCatchMetadata } from './catch.decorator';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/exceptions/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG3F,OAAO,EAEL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,EAExB,4BAA4B,EAC5B,uBAAuB,EACvB,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/exceptions/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG3F,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGrF,OAAO,EAEL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,EAExB,4BAA4B,EAC5B,uBAAuB,EACvB,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCatchMetadata = exports.CATCH_METADATA = exports.Catch = exports.createExceptionHandler = exports.GlobalExceptionFilter = exports.GatewayTimeoutException = exports.ServiceUnavailableException = exports.BadGatewayException = exports.NotImplementedException = exports.InternalServerErrorException = exports.TooManyRequestsException = exports.UnprocessableEntityException = exports.UnsupportedMediaTypeException = exports.PayloadTooLargeException = exports.GoneException = exports.ConflictException = exports.RequestTimeoutException = exports.NotAcceptableException = exports.MethodNotAllowedException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.HttpException = void 0;
|
|
3
|
+
exports.getCatchMetadata = exports.CATCH_METADATA = exports.Catch = exports.createExceptionHandler = exports.GlobalExceptionFilter = exports.GatewayTimeoutException = exports.ServiceUnavailableException = exports.BadGatewayException = exports.NotImplementedException = exports.InternalServerErrorException = exports.TooManyRequestsException = exports.UnprocessableEntityException = exports.UnsupportedMediaTypeException = exports.PayloadTooLargeException = exports.GoneException = exports.ConflictException = exports.RequestTimeoutException = exports.NotAcceptableException = exports.MethodNotAllowedException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.ValidationException = exports.HttpException = void 0;
|
|
4
4
|
// HTTP Exception
|
|
5
5
|
var http_exception_1 = require("./http-exception");
|
|
6
6
|
Object.defineProperty(exports, "HttpException", { enumerable: true, get: function () { return http_exception_1.HttpException; } });
|
|
7
|
+
// Validation Exception (Zod)
|
|
8
|
+
var validation_exception_1 = require("./validation.exception");
|
|
9
|
+
Object.defineProperty(exports, "ValidationException", { enumerable: true, get: function () { return validation_exception_1.ValidationException; } });
|
|
7
10
|
// Specific Exceptions
|
|
8
11
|
var exceptions_1 = require("./exceptions");
|
|
9
12
|
// 4xx Client Errors
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/exceptions/index.ts"],"names":[],"mappings":";;;AAAA,iBAAiB;AACjB,mDAA2F;AAAlF,+GAAA,aAAa,OAAA;AAEtB,sBAAsB;AACtB,2CAqBsB;AApBpB,oBAAoB;AACpB,iHAAA,mBAAmB,OAAA;AACnB,mHAAA,qBAAqB,OAAA;AACrB,gHAAA,kBAAkB,OAAA;AAClB,+GAAA,iBAAiB,OAAA;AACjB,uHAAA,yBAAyB,OAAA;AACzB,oHAAA,sBAAsB,OAAA;AACtB,qHAAA,uBAAuB,OAAA;AACvB,+GAAA,iBAAiB,OAAA;AACjB,2GAAA,aAAa,OAAA;AACb,sHAAA,wBAAwB,OAAA;AACxB,2HAAA,6BAA6B,OAAA;AAC7B,0HAAA,4BAA4B,OAAA;AAC5B,sHAAA,wBAAwB,OAAA;AACxB,oBAAoB;AACpB,0HAAA,4BAA4B,OAAA;AAC5B,qHAAA,uBAAuB,OAAA;AACvB,iHAAA,mBAAmB,OAAA;AACnB,yHAAA,2BAA2B,OAAA;AAC3B,qHAAA,uBAAuB,OAAA;AAGzB,mBAAmB;AACnB,uDAO4B;AAH1B,yHAAA,qBAAqB,OAAA;AAErB,0HAAA,sBAAsB,OAAA;AAGxB,kBAAkB;AAClB,qDAA2F;AAAlF,wGAAA,KAAK,OAAA;AAAiB,iHAAA,cAAc,OAAA;AAAE,mHAAA,gBAAgB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/exceptions/index.ts"],"names":[],"mappings":";;;AAAA,iBAAiB;AACjB,mDAA2F;AAAlF,+GAAA,aAAa,OAAA;AAEtB,6BAA6B;AAC7B,+DAAqF;AAA5E,2HAAA,mBAAmB,OAAA;AAE5B,sBAAsB;AACtB,2CAqBsB;AApBpB,oBAAoB;AACpB,iHAAA,mBAAmB,OAAA;AACnB,mHAAA,qBAAqB,OAAA;AACrB,gHAAA,kBAAkB,OAAA;AAClB,+GAAA,iBAAiB,OAAA;AACjB,uHAAA,yBAAyB,OAAA;AACzB,oHAAA,sBAAsB,OAAA;AACtB,qHAAA,uBAAuB,OAAA;AACvB,+GAAA,iBAAiB,OAAA;AACjB,2GAAA,aAAa,OAAA;AACb,sHAAA,wBAAwB,OAAA;AACxB,2HAAA,6BAA6B,OAAA;AAC7B,0HAAA,4BAA4B,OAAA;AAC5B,sHAAA,wBAAwB,OAAA;AACxB,oBAAoB;AACpB,0HAAA,4BAA4B,OAAA;AAC5B,qHAAA,uBAAuB,OAAA;AACvB,iHAAA,mBAAmB,OAAA;AACnB,yHAAA,2BAA2B,OAAA;AAC3B,qHAAA,uBAAuB,OAAA;AAGzB,mBAAmB;AACnB,uDAO4B;AAH1B,yHAAA,qBAAqB,OAAA;AAErB,0HAAA,sBAAsB,OAAA;AAGxB,kBAAkB;AAClB,qDAA2F;AAAlF,wGAAA,KAAK,OAAA;AAAiB,iHAAA,cAAc,OAAA;AAAE,mHAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { ZodError } from 'zod';
|
|
2
|
+
import { HttpException } from './http-exception';
|
|
3
|
+
/**
|
|
4
|
+
* Structured validation error details
|
|
5
|
+
*/
|
|
6
|
+
export interface ValidationErrorDetails {
|
|
7
|
+
/** The field path where the error occurred */
|
|
8
|
+
path: (string | number)[];
|
|
9
|
+
/** Human-readable error message */
|
|
10
|
+
message: string;
|
|
11
|
+
/** Zod error code */
|
|
12
|
+
code: string;
|
|
13
|
+
/** Expected type/value (if applicable) */
|
|
14
|
+
expected?: string;
|
|
15
|
+
/** Received type/value (if applicable) */
|
|
16
|
+
received?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Validation Exception
|
|
20
|
+
*
|
|
21
|
+
* Thrown when request validation fails using Zod schemas.
|
|
22
|
+
* Provides detailed error information for each validation issue.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* // The framework throws this automatically when @Body(schema) validation fails
|
|
27
|
+
* // But you can also throw it manually:
|
|
28
|
+
*
|
|
29
|
+
* const result = MySchema.safeParse(data);
|
|
30
|
+
* if (!result.success) {
|
|
31
|
+
* throw new ValidationException(result.error);
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class ValidationException extends HttpException {
|
|
36
|
+
/**
|
|
37
|
+
* The original Zod error object
|
|
38
|
+
*/
|
|
39
|
+
readonly zodError: ZodError;
|
|
40
|
+
/**
|
|
41
|
+
* Structured validation error details
|
|
42
|
+
*/
|
|
43
|
+
readonly errors: ValidationErrorDetails[];
|
|
44
|
+
constructor(zodError: ZodError, message?: string);
|
|
45
|
+
/**
|
|
46
|
+
* Get formatted errors for client response
|
|
47
|
+
*/
|
|
48
|
+
getValidationErrors(): ValidationErrorDetails[];
|
|
49
|
+
/**
|
|
50
|
+
* Get the flattened Zod error format
|
|
51
|
+
*/
|
|
52
|
+
getFlattenedErrors(): import("zod").typeToFlattenedError<any, string>;
|
|
53
|
+
/**
|
|
54
|
+
* Get the formatted Zod error
|
|
55
|
+
*/
|
|
56
|
+
getFormattedErrors(): {
|
|
57
|
+
_errors: string[];
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=validation.exception.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.exception.d.ts","sourceRoot":"","sources":["../../../src/core/exceptions/validation.exception.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,KAAK,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,mBAAoB,SAAQ,aAAa;IACpD;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,sBAAsB,EAAE,CAAC;gBAE9B,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,MAA4B;IA0BrE;;OAEG;IACH,mBAAmB,IAAI,sBAAsB,EAAE;IAI/C;;OAEG;IACH,kBAAkB;IAIlB;;OAEG;IACH,kBAAkB;;;CAGnB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationException = void 0;
|
|
4
|
+
const http_exception_1 = require("./http-exception");
|
|
5
|
+
/**
|
|
6
|
+
* Validation Exception
|
|
7
|
+
*
|
|
8
|
+
* Thrown when request validation fails using Zod schemas.
|
|
9
|
+
* Provides detailed error information for each validation issue.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // The framework throws this automatically when @Body(schema) validation fails
|
|
14
|
+
* // But you can also throw it manually:
|
|
15
|
+
*
|
|
16
|
+
* const result = MySchema.safeParse(data);
|
|
17
|
+
* if (!result.success) {
|
|
18
|
+
* throw new ValidationException(result.error);
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
class ValidationException extends http_exception_1.HttpException {
|
|
23
|
+
/**
|
|
24
|
+
* The original Zod error object
|
|
25
|
+
*/
|
|
26
|
+
zodError;
|
|
27
|
+
/**
|
|
28
|
+
* Structured validation error details
|
|
29
|
+
*/
|
|
30
|
+
errors;
|
|
31
|
+
constructor(zodError, message = 'Validation failed') {
|
|
32
|
+
// Transform Zod issues to structured format
|
|
33
|
+
const errors = zodError.issues.map((issue) => ({
|
|
34
|
+
path: issue.path,
|
|
35
|
+
message: issue.message,
|
|
36
|
+
code: issue.code,
|
|
37
|
+
...(('expected' in issue) ? { expected: String(issue.expected) } : {}),
|
|
38
|
+
...(('received' in issue) ? { received: String(issue.received) } : {}),
|
|
39
|
+
}));
|
|
40
|
+
super({
|
|
41
|
+
message,
|
|
42
|
+
error: 'Validation Error',
|
|
43
|
+
details: {
|
|
44
|
+
errors,
|
|
45
|
+
errorCount: errors.length,
|
|
46
|
+
},
|
|
47
|
+
}, 400);
|
|
48
|
+
this.zodError = zodError;
|
|
49
|
+
this.errors = errors;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get formatted errors for client response
|
|
53
|
+
*/
|
|
54
|
+
getValidationErrors() {
|
|
55
|
+
return this.errors;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the flattened Zod error format
|
|
59
|
+
*/
|
|
60
|
+
getFlattenedErrors() {
|
|
61
|
+
return this.zodError.flatten();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the formatted Zod error
|
|
65
|
+
*/
|
|
66
|
+
getFormattedErrors() {
|
|
67
|
+
return this.zodError.format();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.ValidationException = ValidationException;
|
|
71
|
+
//# sourceMappingURL=validation.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.exception.js","sourceRoot":"","sources":["../../../src/core/exceptions/validation.exception.ts"],"names":[],"mappings":";;;AACA,qDAAiD;AAkBjD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,mBAAoB,SAAQ,8BAAa;IACpD;;OAEG;IACM,QAAQ,CAAW;IAE5B;;OAEG;IACM,MAAM,CAA2B;IAE1C,YAAY,QAAkB,EAAE,UAAkB,mBAAmB;QACnE,4CAA4C;QAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAe,EAA0B,EAAE,CAAC,CAAC;YAC/E,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,GAAG,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvE,CAAC,CAAC,CAAC;QAEJ,KAAK,CACH;YACE,OAAO;YACP,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE;gBACP,MAAM;gBACN,UAAU,EAAE,MAAM,CAAC,MAAM;aAC1B;SACF,EACD,GAAG,CACJ,CAAC;QAEF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAChC,CAAC;CACF;AAzDD,kDAyDC"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -8,4 +8,6 @@ export * from './router/router';
|
|
|
8
8
|
export * from './application';
|
|
9
9
|
export * from './decorators';
|
|
10
10
|
export * from './exceptions';
|
|
11
|
+
export { z } from 'zod';
|
|
12
|
+
export type { ZodType, ZodSchema, ZodError, ZodIssue, infer as ZodInfer } from 'zod';
|
|
11
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAK7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,KAAK,CAAC"}
|
package/dist/core/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.z = void 0;
|
|
17
18
|
// Core exports
|
|
18
19
|
__exportStar(require("./types"), exports);
|
|
19
20
|
__exportStar(require("./constants"), exports);
|
|
@@ -25,4 +26,9 @@ __exportStar(require("./router/router"), exports);
|
|
|
25
26
|
__exportStar(require("./application"), exports);
|
|
26
27
|
__exportStar(require("./decorators"), exports);
|
|
27
28
|
__exportStar(require("./exceptions"), exports);
|
|
29
|
+
// Re-export Zod for convenience
|
|
30
|
+
// This allows users to import everything from '@riktajs/core':
|
|
31
|
+
// import { z, Body, Controller } from '@riktajs/core';
|
|
32
|
+
var zod_1 = require("zod");
|
|
33
|
+
Object.defineProperty(exports, "z", { enumerable: true, get: function () { return zod_1.z; } });
|
|
28
34
|
//# sourceMappingURL=index.js.map
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,eAAe;AACf,0CAAwB;AACxB,8CAA4B;AAC5B,8CAA4B;AAC5B,6CAA2B;AAC3B,8CAA4B;AAC5B,8CAA4B;AAC5B,kDAAgC;AAChC,gDAA8B;AAC9B,+CAA6B;AAC7B,+CAA6B;AAE7B,gCAAgC;AAChC,+DAA+D;AAC/D,uDAAuD;AACvD,2BAAwB;AAAf,wFAAA,CAAC,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/core/router/router.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAQnD,OAAO,EAAE,WAAW,EAAiC,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/core/router/router.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAQnD,OAAO,EAAE,WAAW,EAAiC,MAAM,UAAU,CAAC;AAItE;;;;;;;GAOG;AACH,qBAAa,MAAM;IAEf,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAFZ,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,SAAS,EACpB,YAAY,GAAE,MAAW;IAG5C;;OAEG;IACH,kBAAkB,CAAC,eAAe,EAAE,WAAW,GAAG,IAAI;IAuBtD;;OAEG;IACH,OAAO,CAAC,aAAa;IA+DrB;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACH,OAAO,CAAC,aAAa;IAmBrB;;OAEG;IACH,OAAO,CAAC,YAAY;CA6DrB"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Router = void 0;
|
|
4
4
|
require("reflect-metadata");
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
|
+
const validation_exception_1 = require("../exceptions/validation.exception");
|
|
6
7
|
/**
|
|
7
8
|
* Router class
|
|
8
9
|
*
|
|
@@ -115,26 +116,32 @@ class Router {
|
|
|
115
116
|
return args;
|
|
116
117
|
}
|
|
117
118
|
/**
|
|
118
|
-
* Resolve a single parameter
|
|
119
|
+
* Resolve a single parameter with optional Zod validation
|
|
119
120
|
*/
|
|
120
121
|
resolveParam(param, context) {
|
|
122
|
+
// Get raw value based on parameter type
|
|
123
|
+
let rawValue;
|
|
121
124
|
switch (param.type) {
|
|
122
125
|
case constants_1.ParamType.BODY:
|
|
123
|
-
|
|
126
|
+
rawValue = param.key
|
|
124
127
|
? context.body?.[param.key]
|
|
125
128
|
: context.body;
|
|
129
|
+
break;
|
|
126
130
|
case constants_1.ParamType.QUERY:
|
|
127
|
-
|
|
131
|
+
rawValue = param.key
|
|
128
132
|
? context.query[param.key]
|
|
129
133
|
: context.query;
|
|
134
|
+
break;
|
|
130
135
|
case constants_1.ParamType.PARAM:
|
|
131
|
-
|
|
136
|
+
rawValue = param.key
|
|
132
137
|
? context.params[param.key]
|
|
133
138
|
: context.params;
|
|
139
|
+
break;
|
|
134
140
|
case constants_1.ParamType.HEADERS:
|
|
135
|
-
|
|
141
|
+
rawValue = param.key
|
|
136
142
|
? context.request.headers[param.key.toLowerCase()]
|
|
137
143
|
: context.request.headers;
|
|
144
|
+
break;
|
|
138
145
|
case constants_1.ParamType.REQUEST:
|
|
139
146
|
return context.request;
|
|
140
147
|
case constants_1.ParamType.REPLY:
|
|
@@ -144,6 +151,18 @@ class Router {
|
|
|
144
151
|
default:
|
|
145
152
|
return undefined;
|
|
146
153
|
}
|
|
154
|
+
// If a Zod schema is provided, validate the raw value
|
|
155
|
+
if (param.zodSchema) {
|
|
156
|
+
const result = param.zodSchema.safeParse(rawValue);
|
|
157
|
+
if (!result.success) {
|
|
158
|
+
// Throw ValidationException with Zod error details
|
|
159
|
+
throw new validation_exception_1.ValidationException(result.error, `Validation failed for ${param.type}${param.key ? ` (${param.key})` : ''}`);
|
|
160
|
+
}
|
|
161
|
+
// Return the validated and transformed data
|
|
162
|
+
return result.data;
|
|
163
|
+
}
|
|
164
|
+
// No schema provided, return raw value (backward compatible)
|
|
165
|
+
return rawValue;
|
|
147
166
|
}
|
|
148
167
|
}
|
|
149
168
|
exports.Router = Router;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/core/router/router.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAG1B,4CAMsB;
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/core/router/router.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAG1B,4CAMsB;AAGtB,6EAAyE;AAEzE;;;;;;;GAOG;AACH,MAAa,MAAM;IAEE;IACA;IACA;IAHnB,YACmB,MAAuB,EACvB,SAAoB,EACpB,eAAuB,EAAE;QAFzB,WAAM,GAAN,MAAM,CAAiB;QACvB,cAAS,GAAT,SAAS,CAAW;QACpB,iBAAY,GAAZ,YAAY,CAAa;IACzC,CAAC;IAEJ;;OAEG;IACH,kBAAkB,CAAC,eAA4B;QAC7C,0BAA0B;QAC1B,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,+BAAmB,EAAE,eAAe,CAAC,CAAC;QACjF,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,GAAG,eAAe,CAAC,IAAI,wCAAwC;gBAC/D,iCAAiC,CAClC,CAAC;QACJ,CAAC;QAED,6CAA6C;QAC7C,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAEnE,sBAAsB;QACtB,MAAM,MAAM,GACV,OAAO,CAAC,WAAW,CAAC,2BAAe,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC;QAE9D,sBAAsB;QACtB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,kBAAkB,EAAE,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED;;OAEG;IACK,aAAa,CACnB,eAA4B,EAC5B,kBAA2B,EAC3B,gBAAwB,EACxB,KAAsB;QAEtB,kBAAkB;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE9D,yBAAyB;QACzB,MAAM,OAAO,GAAI,kBAAwD,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC7F,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,WAAW,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,iBAAiB,eAAe,CAAC,IAAI,EAAE,CAC5E,CAAC;QACJ,CAAC;QAED,yBAAyB;QACzB,MAAM,UAAU,GACd,OAAO,CAAC,WAAW,CAAC,0BAAc,EAAE,eAAe,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAEhF,8BAA8B;QAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,8BAAkB,EAAE,eAAe,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAE/F,2BAA2B;QAC3B,MAAM,YAAY,GAAG,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;YAC1E,IAAI,CAAC;gBACH,sBAAsB;gBACtB,MAAM,OAAO,GAAiB;oBAC5B,OAAO;oBACP,KAAK;oBACL,MAAM,EAAE,OAAO,CAAC,MAAgC;oBAChD,KAAK,EAAE,OAAO,CAAC,KAAgC;oBAC/C,IAAI,EAAE,OAAO,CAAC,IAAI;iBACnB,CAAC;gBAEF,qBAAqB;gBACrB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAErD,mBAAmB;gBACnB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;gBAE7D,+BAA+B;gBAC/B,IAAI,UAAU,EAAE,CAAC;oBACf,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC3B,CAAC;gBAED,4CAA4C;gBAC5C,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,+BAA+B;gBAC/B,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC,CAAC;QAEF,wBAAwB;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,EAAsE,CAAC;QAC9G,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAE5C,yBAAyB;QACzB,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,gBAAwB,EAAE,SAAiB;QAC3D,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,gBAAgB,EAAE,SAAS,CAAC;aAC3D,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,6BAA6B;QAC7B,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;IAC3C,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,UAA2B,EAAE,OAAqB;QACtE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,0BAA0B;QAC1B,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAEjE,gDAAgD;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,GAAc,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEhE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,KAAoB,EAAE,OAAqB;QAC9D,wCAAwC;QACxC,IAAI,QAAiB,CAAC;QAEtB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,qBAAS,CAAC,IAAI;gBACjB,QAAQ,GAAG,KAAK,CAAC,GAAG;oBAClB,CAAC,CAAE,OAAO,CAAC,IAAgC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC;oBACxD,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBACjB,MAAM;YAER,KAAK,qBAAS,CAAC,KAAK;gBAClB,QAAQ,GAAG,KAAK,CAAC,GAAG;oBAClB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;oBAC1B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;gBAClB,MAAM;YAER,KAAK,qBAAS,CAAC,KAAK;gBAClB,QAAQ,GAAG,KAAK,CAAC,GAAG;oBAClB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;oBAC3B,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;gBACnB,MAAM;YAER,KAAK,qBAAS,CAAC,OAAO;gBACpB,QAAQ,GAAG,KAAK,CAAC,GAAG;oBAClB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;oBAClD,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;gBAC5B,MAAM;YAER,KAAK,qBAAS,CAAC,OAAO;gBACpB,OAAO,OAAO,CAAC,OAAO,CAAC;YAEzB,KAAK,qBAAS,CAAC,KAAK;gBAClB,OAAO,OAAO,CAAC,KAAK,CAAC;YAEvB,KAAK,qBAAS,CAAC,OAAO;gBACpB,OAAO,OAAO,CAAC;YAEjB;gBACE,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,sDAAsD;QACtD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAEnD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,mDAAmD;gBACnD,MAAM,IAAI,0CAAmB,CAC3B,MAAM,CAAC,KAAK,EACZ,yBAAyB,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3E,CAAC;YACJ,CAAC;YAED,4CAA4C;YAC5C,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,6DAA6D;QAC7D,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AArMD,wBAqMC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riktajs/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A fast and modern TypeScript backend framework with zero-config autowiring, powered by Fastify",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"fast-glob": "^3.3.2",
|
|
33
33
|
"fastify": "^5.1.0",
|
|
34
|
-
"reflect-metadata": "^0.2.2"
|
|
34
|
+
"reflect-metadata": "^0.2.2",
|
|
35
|
+
"zod": "^3.25.76"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@types/node": "^22.10.2",
|