nestjs-api-forge 1.0.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.
- package/README.md +221 -0
- package/dist/api-forge.module.d.ts +11 -0
- package/dist/api-forge.module.js +70 -0
- package/dist/api-forge.module.js.map +1 -0
- package/dist/decorators/api-response.decorator.d.ts +6 -0
- package/dist/decorators/api-response.decorator.js +19 -0
- package/dist/decorators/api-response.decorator.js.map +1 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +18 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/dto/api-response.dto.d.ts +7 -0
- package/dist/dto/api-response.dto.js +37 -0
- package/dist/dto/api-response.dto.js.map +1 -0
- package/dist/dto/index.d.ts +1 -0
- package/dist/dto/index.js +18 -0
- package/dist/dto/index.js.map +1 -0
- package/dist/exceptions/api.exception.d.ts +34 -0
- package/dist/exceptions/api.exception.js +67 -0
- package/dist/exceptions/api.exception.js.map +1 -0
- package/dist/exceptions/index.d.ts +2 -0
- package/dist/exceptions/index.js +19 -0
- package/dist/exceptions/index.js.map +1 -0
- package/dist/exceptions/validation.exception.d.ts +6 -0
- package/dist/exceptions/validation.exception.js +19 -0
- package/dist/exceptions/validation.exception.js.map +1 -0
- package/dist/filters/global-exception.filter.d.ts +12 -0
- package/dist/filters/global-exception.filter.js +93 -0
- package/dist/filters/global-exception.filter.js.map +1 -0
- package/dist/filters/index.d.ts +1 -0
- package/dist/filters/index.js +18 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/interceptors/index.d.ts +1 -0
- package/dist/interceptors/index.js +18 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/response.interceptor.d.ts +11 -0
- package/dist/interceptors/response.interceptor.js +52 -0
- package/dist/interceptors/response.interceptor.js.map +1 -0
- package/dist/interfaces/api-response.interface.d.ts +36 -0
- package/dist/interfaces/api-response.interface.js +3 -0
- package/dist/interfaces/api-response.interface.js.map +1 -0
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/index.js +18 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/utils/error-code.util.d.ts +3 -0
- package/dist/utils/error-code.util.js +37 -0
- package/dist/utils/error-code.util.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# nestjs-api-forge
|
|
2
|
+
|
|
3
|
+
Standardized API response formatting, structured error handling, and exception filters for [NestJS](https://nestjs.com/) applications.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Uniform success response** envelope wrapping all handler return values
|
|
8
|
+
- **Structured error responses** with `code`, `message`, and optional `details` array
|
|
9
|
+
- **Global exception filter** that handles `HttpException`, `ValidationPipe` errors, and unexpected exceptions
|
|
10
|
+
- **Built-in typed exceptions** (`NotFoundException`, `UnauthorizedException`, `ValidationException`, etc.)
|
|
11
|
+
- **`@ForgeMessage`** decorator to override per-route success messages
|
|
12
|
+
- **`@ForgeRawResponse`** decorator to opt a route out of wrapping
|
|
13
|
+
- **`ApiForgeModule.forRoot()`** for one-line global registration
|
|
14
|
+
- **`ApiForgeModule.forRootAsync()`** for config-service-driven options
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install nestjs-api-forge
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
### 1. Register globally (`app.module.ts`)
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { Module } from '@nestjs/common';
|
|
32
|
+
import { ApiForgeModule } from 'nestjs-api-forge';
|
|
33
|
+
|
|
34
|
+
@Module({
|
|
35
|
+
imports: [
|
|
36
|
+
ApiForgeModule.forRoot({
|
|
37
|
+
version: '1.0',
|
|
38
|
+
defaultSuccessMessage: 'OK',
|
|
39
|
+
includePath: true,
|
|
40
|
+
includeTimestamp: true,
|
|
41
|
+
}),
|
|
42
|
+
],
|
|
43
|
+
})
|
|
44
|
+
export class AppModule {}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Every route in your application will now return a standardized response automatically.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Response Formats
|
|
52
|
+
|
|
53
|
+
### Success
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"success": true,
|
|
58
|
+
"statusCode": 200,
|
|
59
|
+
"message": "Request successful",
|
|
60
|
+
"data": { "id": 1, "name": "Alice" },
|
|
61
|
+
"meta": {
|
|
62
|
+
"timestamp": "2026-05-02T10:00:00.000Z",
|
|
63
|
+
"path": "/api/users/1",
|
|
64
|
+
"version": "1.0"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Error
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"success": false,
|
|
74
|
+
"statusCode": 404,
|
|
75
|
+
"message": "User not found",
|
|
76
|
+
"error": {
|
|
77
|
+
"code": "NOT_FOUND"
|
|
78
|
+
},
|
|
79
|
+
"meta": {
|
|
80
|
+
"timestamp": "2026-05-02T10:00:00.000Z",
|
|
81
|
+
"path": "/api/users/99",
|
|
82
|
+
"version": "1.0"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Validation Error (from `ValidationPipe`)
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"success": false,
|
|
92
|
+
"statusCode": 400,
|
|
93
|
+
"message": "Validation failed",
|
|
94
|
+
"error": {
|
|
95
|
+
"code": "VALIDATION_ERROR",
|
|
96
|
+
"details": [
|
|
97
|
+
{ "field": "email", "message": "must be an email" },
|
|
98
|
+
{ "field": "password", "message": "must be longer than 8 characters" }
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
"meta": {
|
|
102
|
+
"timestamp": "2026-05-02T10:00:00.000Z",
|
|
103
|
+
"path": "/api/auth/register"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## API Reference
|
|
111
|
+
|
|
112
|
+
### `ApiForgeModule.forRoot(options?)`
|
|
113
|
+
|
|
114
|
+
| Option | Type | Default | Description |
|
|
115
|
+
|---|---|---|---|
|
|
116
|
+
| `includePath` | `boolean` | `true` | Include request path in `meta` |
|
|
117
|
+
| `includeTimestamp` | `boolean` | `true` | Include ISO timestamp in `meta` |
|
|
118
|
+
| `version` | `string` | `undefined` | API version string added to `meta` |
|
|
119
|
+
| `defaultSuccessMessage` | `string` | `'Request successful'` | Default success message |
|
|
120
|
+
|
|
121
|
+
### Decorators
|
|
122
|
+
|
|
123
|
+
| Decorator | Scope | Description |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| `@ApiForge(options?)` | Controller / Method | Apply filter + interceptor to a single controller or method |
|
|
126
|
+
| `@ForgeMessage(msg)` | Controller / Method | Override the success message for that route |
|
|
127
|
+
| `@ForgeRawResponse()` | Controller / Method | Skip response wrapping; return handler value as-is |
|
|
128
|
+
|
|
129
|
+
### Built-in Exceptions
|
|
130
|
+
|
|
131
|
+
All exceptions extend `ApiException` which extends NestJS's `HttpException`.
|
|
132
|
+
|
|
133
|
+
| Class | Status | Code |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| `BadRequestException` | 400 | `BAD_REQUEST` |
|
|
136
|
+
| `UnauthorizedException` | 401 | `UNAUTHORIZED` |
|
|
137
|
+
| `ForbiddenException` | 403 | `FORBIDDEN` |
|
|
138
|
+
| `NotFoundException` | 404 | `NOT_FOUND` |
|
|
139
|
+
| `ConflictException` | 409 | `CONFLICT` |
|
|
140
|
+
| `UnprocessableEntityException` | 422 | `UNPROCESSABLE_ENTITY` |
|
|
141
|
+
| `TooManyRequestsException` | 429 | `TOO_MANY_REQUESTS` |
|
|
142
|
+
| `InternalServerException` | 500 | `INTERNAL_SERVER_ERROR` |
|
|
143
|
+
| `ServiceUnavailableException` | 503 | `SERVICE_UNAVAILABLE` |
|
|
144
|
+
| `ValidationException` | 400 | `VALIDATION_ERROR` |
|
|
145
|
+
|
|
146
|
+
### `ApiResponseDto` (manual usage)
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { ApiResponseDto } from 'nestjs-api-forge';
|
|
150
|
+
|
|
151
|
+
ApiResponseDto.success(data, 'User fetched', 200, { path: '/users/1' });
|
|
152
|
+
ApiResponseDto.created(data, 'User created');
|
|
153
|
+
ApiResponseDto.noContent('Deleted');
|
|
154
|
+
ApiResponseDto.error('Not found', 404, { code: 'NOT_FOUND' });
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Usage Examples
|
|
160
|
+
|
|
161
|
+
### Controller with custom message
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import { Controller, Get, Param } from '@nestjs/common';
|
|
165
|
+
import { ForgeMessage, NotFoundException } from 'nestjs-api-forge';
|
|
166
|
+
|
|
167
|
+
@Controller('users')
|
|
168
|
+
export class UsersController {
|
|
169
|
+
@Get(':id')
|
|
170
|
+
@ForgeMessage('User fetched successfully')
|
|
171
|
+
findOne(@Param('id') id: string) {
|
|
172
|
+
const user = this.usersService.findById(+id);
|
|
173
|
+
if (!user) throw new NotFoundException('User');
|
|
174
|
+
return user;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Skip wrapping for a specific route
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
@Get('health')
|
|
183
|
+
@ForgeRawResponse()
|
|
184
|
+
healthCheck() {
|
|
185
|
+
return { status: 'ok' };
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Async module registration (with ConfigService)
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
ApiForgeModule.forRootAsync({
|
|
193
|
+
imports: [ConfigModule],
|
|
194
|
+
inject: [ConfigService],
|
|
195
|
+
useFactory: (config: ConfigService) => ({
|
|
196
|
+
version: config.get('API_VERSION'),
|
|
197
|
+
defaultSuccessMessage: config.get('DEFAULT_SUCCESS_MSG'),
|
|
198
|
+
}),
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Use with `ValidationPipe`
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// main.ts
|
|
206
|
+
app.useGlobalPipes(
|
|
207
|
+
new ValidationPipe({
|
|
208
|
+
whitelist: true,
|
|
209
|
+
forbidNonWhitelisted: true,
|
|
210
|
+
transform: true,
|
|
211
|
+
}),
|
|
212
|
+
);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The exception filter automatically parses `ValidationPipe` error arrays and formats them into `error.details`.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { ForgeOptions } from './interfaces/api-response.interface';
|
|
3
|
+
export declare const FORGE_OPTIONS = "FORGE_OPTIONS";
|
|
4
|
+
export declare class ApiForgeModule {
|
|
5
|
+
static forRoot(options?: ForgeOptions): DynamicModule;
|
|
6
|
+
static forRootAsync(asyncOptions: {
|
|
7
|
+
useFactory: (...args: any[]) => ForgeOptions | Promise<ForgeOptions>;
|
|
8
|
+
inject?: any[];
|
|
9
|
+
imports?: any[];
|
|
10
|
+
}): DynamicModule;
|
|
11
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var ApiForgeModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ApiForgeModule = exports.FORGE_OPTIONS = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const core_1 = require("@nestjs/core");
|
|
13
|
+
const global_exception_filter_1 = require("./filters/global-exception.filter");
|
|
14
|
+
const response_interceptor_1 = require("./interceptors/response.interceptor");
|
|
15
|
+
exports.FORGE_OPTIONS = 'FORGE_OPTIONS';
|
|
16
|
+
let ApiForgeModule = ApiForgeModule_1 = class ApiForgeModule {
|
|
17
|
+
static forRoot(options = {}) {
|
|
18
|
+
const optionsProvider = {
|
|
19
|
+
provide: exports.FORGE_OPTIONS,
|
|
20
|
+
useValue: options,
|
|
21
|
+
};
|
|
22
|
+
const exceptionFilterProvider = {
|
|
23
|
+
provide: core_1.APP_FILTER,
|
|
24
|
+
useFactory: () => new global_exception_filter_1.ForgeExceptionFilter(options),
|
|
25
|
+
};
|
|
26
|
+
const responseInterceptorProvider = {
|
|
27
|
+
provide: core_1.APP_INTERCEPTOR,
|
|
28
|
+
useFactory: (reflector) => new response_interceptor_1.ForgeResponseInterceptor(reflector, options),
|
|
29
|
+
inject: [core_1.Reflector],
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
module: ApiForgeModule_1,
|
|
33
|
+
providers: [
|
|
34
|
+
optionsProvider,
|
|
35
|
+
exceptionFilterProvider,
|
|
36
|
+
responseInterceptorProvider,
|
|
37
|
+
],
|
|
38
|
+
exports: [exports.FORGE_OPTIONS],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
static forRootAsync(asyncOptions) {
|
|
42
|
+
const exceptionFilterProvider = {
|
|
43
|
+
provide: core_1.APP_FILTER,
|
|
44
|
+
useFactory: async (...args) => {
|
|
45
|
+
const options = await asyncOptions.useFactory(...args);
|
|
46
|
+
return new global_exception_filter_1.ForgeExceptionFilter(options);
|
|
47
|
+
},
|
|
48
|
+
inject: asyncOptions.inject ?? [],
|
|
49
|
+
};
|
|
50
|
+
const responseInterceptorProvider = {
|
|
51
|
+
provide: core_1.APP_INTERCEPTOR,
|
|
52
|
+
useFactory: async (reflector, ...args) => {
|
|
53
|
+
const options = await asyncOptions.useFactory(...args);
|
|
54
|
+
return new response_interceptor_1.ForgeResponseInterceptor(reflector, options);
|
|
55
|
+
},
|
|
56
|
+
inject: [core_1.Reflector, ...(asyncOptions.inject ?? [])],
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
module: ApiForgeModule_1,
|
|
60
|
+
imports: asyncOptions.imports ?? [],
|
|
61
|
+
providers: [exceptionFilterProvider, responseInterceptorProvider],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
exports.ApiForgeModule = ApiForgeModule;
|
|
66
|
+
exports.ApiForgeModule = ApiForgeModule = ApiForgeModule_1 = __decorate([
|
|
67
|
+
(0, common_1.Global)(),
|
|
68
|
+
(0, common_1.Module)({})
|
|
69
|
+
], ApiForgeModule);
|
|
70
|
+
//# sourceMappingURL=api-forge.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-forge.module.js","sourceRoot":"","sources":["../src/api-forge.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAyE;AACzE,uCAAsE;AACtE,+EAAyE;AACzE,8EAA+E;AAGlE,QAAA,aAAa,GAAG,eAAe,CAAC;AAItC,IAAM,cAAc,sBAApB,MAAM,cAAc;IAKzB,MAAM,CAAC,OAAO,CAAC,UAAwB,EAAE;QACvC,MAAM,eAAe,GAAa;YAChC,OAAO,EAAE,qBAAa;YACtB,QAAQ,EAAE,OAAO;SAClB,CAAC;QAEF,MAAM,uBAAuB,GAAa;YACxC,OAAO,EAAE,iBAAU;YACnB,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,8CAAoB,CAAC,OAAO,CAAC;SACpD,CAAC;QAEF,MAAM,2BAA2B,GAAa;YAC5C,OAAO,EAAE,sBAAe;YACxB,UAAU,EAAE,CAAC,SAAoB,EAAE,EAAE,CACnC,IAAI,+CAAwB,CAAC,SAAS,EAAE,OAAO,CAAC;YAClD,MAAM,EAAE,CAAC,gBAAS,CAAC;SACpB,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,SAAS,EAAE;gBACT,eAAe;gBACf,uBAAuB;gBACvB,2BAA2B;aAC5B;YACD,OAAO,EAAE,CAAC,qBAAa,CAAC;SACzB,CAAC;IACJ,CAAC;IAKD,MAAM,CAAC,YAAY,CAAC,YAInB;QACC,MAAM,uBAAuB,GAAa;YACxC,OAAO,EAAE,iBAAU;YACnB,UAAU,EAAE,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;gBACnC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;gBACvD,OAAO,IAAI,8CAAoB,CAAC,OAAO,CAAC,CAAC;YAC3C,CAAC;YACD,MAAM,EAAE,YAAY,CAAC,MAAM,IAAI,EAAE;SAClC,CAAC;QAEF,MAAM,2BAA2B,GAAa;YAC5C,OAAO,EAAE,sBAAe;YACxB,UAAU,EAAE,KAAK,EAAE,SAAoB,EAAE,GAAG,IAAW,EAAE,EAAE;gBACzD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;gBACvD,OAAO,IAAI,+CAAwB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC1D,CAAC;YACD,MAAM,EAAE,CAAC,gBAAS,EAAE,GAAG,CAAC,YAAY,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;SACpD,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,OAAO,EAAE,YAAY,CAAC,OAAO,IAAI,EAAE;YACnC,SAAS,EAAE,CAAC,uBAAuB,EAAE,2BAA2B,CAAC;SAClE,CAAC;IACJ,CAAC;CACF,CAAA;AAlEY,wCAAc;yBAAd,cAAc;IAF1B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,cAAc,CAkE1B"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ForgeOptions } from '../interfaces/api-response.interface';
|
|
2
|
+
export declare const FORGE_MESSAGE_KEY = "forge:response_message";
|
|
3
|
+
export declare const FORGE_RAW_RESPONSE_KEY = "forge:raw_response";
|
|
4
|
+
export declare const ForgeMessage: (message: string) => import("@nestjs/common").CustomDecorator<string>;
|
|
5
|
+
export declare const ForgeRawResponse: () => import("@nestjs/common").CustomDecorator<string>;
|
|
6
|
+
export declare function ApiForge(options?: ForgeOptions): <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ForgeRawResponse = exports.ForgeMessage = exports.FORGE_RAW_RESPONSE_KEY = exports.FORGE_MESSAGE_KEY = void 0;
|
|
4
|
+
exports.ApiForge = ApiForge;
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const core_1 = require("@nestjs/core");
|
|
7
|
+
const response_interceptor_1 = require("../interceptors/response.interceptor");
|
|
8
|
+
const global_exception_filter_1 = require("../filters/global-exception.filter");
|
|
9
|
+
exports.FORGE_MESSAGE_KEY = 'forge:response_message';
|
|
10
|
+
exports.FORGE_RAW_RESPONSE_KEY = 'forge:raw_response';
|
|
11
|
+
const ForgeMessage = (message) => (0, common_1.SetMetadata)(exports.FORGE_MESSAGE_KEY, message);
|
|
12
|
+
exports.ForgeMessage = ForgeMessage;
|
|
13
|
+
const ForgeRawResponse = () => (0, common_1.SetMetadata)(exports.FORGE_RAW_RESPONSE_KEY, true);
|
|
14
|
+
exports.ForgeRawResponse = ForgeRawResponse;
|
|
15
|
+
function ApiForge(options = {}) {
|
|
16
|
+
const reflector = new core_1.Reflector();
|
|
17
|
+
return (0, common_1.applyDecorators)((0, common_1.UseInterceptors)(new response_interceptor_1.ForgeResponseInterceptor(reflector, options)), (0, common_1.UseFilters)(new global_exception_filter_1.ForgeExceptionFilter(options)));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=api-response.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-response.decorator.js","sourceRoot":"","sources":["../../src/decorators/api-response.decorator.ts"],"names":[],"mappings":";;;AAoBA,4BAMC;AA1BD,2CAA2F;AAC3F,uCAAyC;AACzC,+EAAgF;AAChF,gFAA0E;AAG7D,QAAA,iBAAiB,GAAG,wBAAwB,CAAC;AAC7C,QAAA,sBAAsB,GAAG,oBAAoB,CAAC;AAGpD,MAAM,YAAY,GAAG,CAAC,OAAe,EAAE,EAAE,CAC9C,IAAA,oBAAW,EAAC,yBAAiB,EAAE,OAAO,CAAC,CAAC;AAD7B,QAAA,YAAY,gBACiB;AAGnC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CAAC,IAAA,oBAAW,EAAC,8BAAsB,EAAE,IAAI,CAAC,CAAC;AAAnE,QAAA,gBAAgB,oBAAmD;AAMhF,SAAgB,QAAQ,CAAC,UAAwB,EAAE;IACjD,MAAM,SAAS,GAAG,IAAI,gBAAS,EAAE,CAAC;IAClC,OAAO,IAAA,wBAAe,EACpB,IAAA,wBAAe,EAAC,IAAI,+CAAwB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,EACjE,IAAA,mBAAU,EAAC,IAAI,8CAAoB,CAAC,OAAO,CAAC,CAAC,CAC9C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './api-response.decorator';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./api-response.decorator"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAyC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ApiErrorPayload, ApiMeta, ApiSuccessResponse, ApiErrorResponse } from '../interfaces/api-response.interface';
|
|
2
|
+
export declare class ApiResponseDto {
|
|
3
|
+
static success<T>(data: T, message?: string, statusCode?: number, meta?: Partial<ApiMeta>): ApiSuccessResponse<T>;
|
|
4
|
+
static created<T>(data: T, message?: string, meta?: Partial<ApiMeta>): ApiSuccessResponse<T>;
|
|
5
|
+
static noContent(message?: string, meta?: Partial<ApiMeta>): ApiSuccessResponse<null>;
|
|
6
|
+
static error(message: string, statusCode: number, error: ApiErrorPayload, meta?: Partial<ApiMeta>): ApiErrorResponse;
|
|
7
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiResponseDto = void 0;
|
|
4
|
+
class ApiResponseDto {
|
|
5
|
+
static success(data, message = 'Request successful', statusCode = 200, meta = {}) {
|
|
6
|
+
return {
|
|
7
|
+
success: true,
|
|
8
|
+
statusCode,
|
|
9
|
+
message,
|
|
10
|
+
data,
|
|
11
|
+
meta: {
|
|
12
|
+
timestamp: new Date().toISOString(),
|
|
13
|
+
...meta,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
static created(data, message = 'Resource created successfully', meta = {}) {
|
|
18
|
+
return ApiResponseDto.success(data, message, 201, meta);
|
|
19
|
+
}
|
|
20
|
+
static noContent(message = 'No content', meta = {}) {
|
|
21
|
+
return ApiResponseDto.success(null, message, 204, meta);
|
|
22
|
+
}
|
|
23
|
+
static error(message, statusCode, error, meta = {}) {
|
|
24
|
+
return {
|
|
25
|
+
success: false,
|
|
26
|
+
statusCode,
|
|
27
|
+
message,
|
|
28
|
+
error,
|
|
29
|
+
meta: {
|
|
30
|
+
timestamp: new Date().toISOString(),
|
|
31
|
+
...meta,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.ApiResponseDto = ApiResponseDto;
|
|
37
|
+
//# sourceMappingURL=api-response.dto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-response.dto.js","sourceRoot":"","sources":["../../src/dto/api-response.dto.ts"],"names":[],"mappings":";;;AAOA,MAAa,cAAc;IACzB,MAAM,CAAC,OAAO,CACZ,IAAO,EACP,OAAO,GAAG,oBAAoB,EAC9B,UAAU,GAAG,GAAG,EAChB,OAAyB,EAAE;QAE3B,OAAO;YACL,OAAO,EAAE,IAAI;YACb,UAAU;YACV,OAAO;YACP,IAAI;YACJ,IAAI,EAAE;gBACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,GAAG,IAAI;aACR;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,OAAO,CACZ,IAAO,EACP,OAAO,GAAG,+BAA+B,EACzC,OAAyB,EAAE;QAE3B,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,SAAS,CACd,OAAO,GAAG,YAAY,EACtB,OAAyB,EAAE;QAE3B,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,KAAK,CACV,OAAe,EACf,UAAkB,EAClB,KAAsB,EACtB,OAAyB,EAAE;QAE3B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,UAAU;YACV,OAAO;YACP,KAAK;YACL,IAAI,EAAE;gBACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,GAAG,IAAI;aACR;SACF,CAAC;IACJ,CAAC;CACF;AAnDD,wCAmDC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './api-response.dto';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./api-response.dto"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dto/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { HttpException, HttpStatus } from '@nestjs/common';
|
|
2
|
+
import { ApiErrorDetail } from '../interfaces/api-response.interface';
|
|
3
|
+
export declare class ApiException extends HttpException {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
readonly details?: ApiErrorDetail[] | undefined;
|
|
6
|
+
constructor(message: string, statusCode: HttpStatus, code: string, details?: ApiErrorDetail[] | undefined);
|
|
7
|
+
}
|
|
8
|
+
export declare class BadRequestException extends ApiException {
|
|
9
|
+
constructor(message?: string, details?: ApiErrorDetail[]);
|
|
10
|
+
}
|
|
11
|
+
export declare class UnauthorizedException extends ApiException {
|
|
12
|
+
constructor(message?: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class ForbiddenException extends ApiException {
|
|
15
|
+
constructor(message?: string);
|
|
16
|
+
}
|
|
17
|
+
export declare class NotFoundException extends ApiException {
|
|
18
|
+
constructor(resource?: string);
|
|
19
|
+
}
|
|
20
|
+
export declare class ConflictException extends ApiException {
|
|
21
|
+
constructor(message?: string);
|
|
22
|
+
}
|
|
23
|
+
export declare class UnprocessableEntityException extends ApiException {
|
|
24
|
+
constructor(message?: string, details?: ApiErrorDetail[]);
|
|
25
|
+
}
|
|
26
|
+
export declare class TooManyRequestsException extends ApiException {
|
|
27
|
+
constructor(message?: string);
|
|
28
|
+
}
|
|
29
|
+
export declare class InternalServerException extends ApiException {
|
|
30
|
+
constructor(message?: string);
|
|
31
|
+
}
|
|
32
|
+
export declare class ServiceUnavailableException extends ApiException {
|
|
33
|
+
constructor(message?: string);
|
|
34
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServiceUnavailableException = exports.InternalServerException = exports.TooManyRequestsException = exports.UnprocessableEntityException = exports.ConflictException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.ApiException = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class ApiException extends common_1.HttpException {
|
|
6
|
+
constructor(message, statusCode, code, details) {
|
|
7
|
+
super({ message, code, details }, statusCode);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.details = details;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.ApiException = ApiException;
|
|
13
|
+
class BadRequestException extends ApiException {
|
|
14
|
+
constructor(message = 'Bad request', details) {
|
|
15
|
+
super(message, common_1.HttpStatus.BAD_REQUEST, 'BAD_REQUEST', details);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.BadRequestException = BadRequestException;
|
|
19
|
+
class UnauthorizedException extends ApiException {
|
|
20
|
+
constructor(message = 'Unauthorized') {
|
|
21
|
+
super(message, common_1.HttpStatus.UNAUTHORIZED, 'UNAUTHORIZED');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.UnauthorizedException = UnauthorizedException;
|
|
25
|
+
class ForbiddenException extends ApiException {
|
|
26
|
+
constructor(message = 'Forbidden resource') {
|
|
27
|
+
super(message, common_1.HttpStatus.FORBIDDEN, 'FORBIDDEN');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.ForbiddenException = ForbiddenException;
|
|
31
|
+
class NotFoundException extends ApiException {
|
|
32
|
+
constructor(resource = 'Resource') {
|
|
33
|
+
super(`${resource} not found`, common_1.HttpStatus.NOT_FOUND, 'NOT_FOUND');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.NotFoundException = NotFoundException;
|
|
37
|
+
class ConflictException extends ApiException {
|
|
38
|
+
constructor(message = 'Resource already exists') {
|
|
39
|
+
super(message, common_1.HttpStatus.CONFLICT, 'CONFLICT');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.ConflictException = ConflictException;
|
|
43
|
+
class UnprocessableEntityException extends ApiException {
|
|
44
|
+
constructor(message = 'Unprocessable entity', details) {
|
|
45
|
+
super(message, common_1.HttpStatus.UNPROCESSABLE_ENTITY, 'UNPROCESSABLE_ENTITY', details);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.UnprocessableEntityException = UnprocessableEntityException;
|
|
49
|
+
class TooManyRequestsException extends ApiException {
|
|
50
|
+
constructor(message = 'Too many requests') {
|
|
51
|
+
super(message, common_1.HttpStatus.TOO_MANY_REQUESTS, 'TOO_MANY_REQUESTS');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.TooManyRequestsException = TooManyRequestsException;
|
|
55
|
+
class InternalServerException extends ApiException {
|
|
56
|
+
constructor(message = 'Internal server error') {
|
|
57
|
+
super(message, common_1.HttpStatus.INTERNAL_SERVER_ERROR, 'INTERNAL_SERVER_ERROR');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.InternalServerException = InternalServerException;
|
|
61
|
+
class ServiceUnavailableException extends ApiException {
|
|
62
|
+
constructor(message = 'Service unavailable') {
|
|
63
|
+
super(message, common_1.HttpStatus.SERVICE_UNAVAILABLE, 'SERVICE_UNAVAILABLE');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.ServiceUnavailableException = ServiceUnavailableException;
|
|
67
|
+
//# sourceMappingURL=api.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.exception.js","sourceRoot":"","sources":["../../src/exceptions/api.exception.ts"],"names":[],"mappings":";;;AAAA,2CAA2D;AAG3D,MAAa,YAAa,SAAQ,sBAAa;IAC7C,YACE,OAAe,EACf,UAAsB,EACN,IAAY,EACZ,OAA0B;QAE1C,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;QAH9B,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAmB;IAG5C,CAAC;CACF;AATD,oCASC;AAED,MAAa,mBAAoB,SAAQ,YAAY;IACnD,YAAY,OAAO,GAAG,aAAa,EAAE,OAA0B;QAC7D,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,WAAW,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC;CACF;AAJD,kDAIC;AAED,MAAa,qBAAsB,SAAQ,YAAY;IACrD,YAAY,OAAO,GAAG,cAAc;QAClC,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC1D,CAAC;CACF;AAJD,sDAIC;AAED,MAAa,kBAAmB,SAAQ,YAAY;IAClD,YAAY,OAAO,GAAG,oBAAoB;QACxC,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpD,CAAC;CACF;AAJD,gDAIC;AAED,MAAa,iBAAkB,SAAQ,YAAY;IACjD,YAAY,QAAQ,GAAG,UAAU;QAC/B,KAAK,CAAC,GAAG,QAAQ,YAAY,EAAE,mBAAU,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpE,CAAC;CACF;AAJD,8CAIC;AAED,MAAa,iBAAkB,SAAQ,YAAY;IACjD,YAAY,OAAO,GAAG,yBAAyB;QAC7C,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;CACF;AAJD,8CAIC;AAED,MAAa,4BAA6B,SAAQ,YAAY;IAC5D,YAAY,OAAO,GAAG,sBAAsB,EAAE,OAA0B;QACtE,KAAK,CACH,OAAO,EACP,mBAAU,CAAC,oBAAoB,EAC/B,sBAAsB,EACtB,OAAO,CACR,CAAC;IACJ,CAAC;CACF;AATD,oEASC;AAED,MAAa,wBAAyB,SAAQ,YAAY;IACxD,YAAY,OAAO,GAAG,mBAAmB;QACvC,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;IACpE,CAAC;CACF;AAJD,4DAIC;AAED,MAAa,uBAAwB,SAAQ,YAAY;IACvD,YAAY,OAAO,GAAG,uBAAuB;QAC3C,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,qBAAqB,EAAE,uBAAuB,CAAC,CAAC;IAC5E,CAAC;CACF;AAJD,0DAIC;AAED,MAAa,2BAA4B,SAAQ,YAAY;IAC3D,YAAY,OAAO,GAAG,qBAAqB;QACzC,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC;IACxE,CAAC;CACF;AAJD,kEAIC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./api.exception"), exports);
|
|
18
|
+
__exportStar(require("./validation.exception"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exceptions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kDAAgC;AAChC,yDAAuC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ApiException } from './api.exception';
|
|
2
|
+
import { ApiErrorDetail } from '../interfaces/api-response.interface';
|
|
3
|
+
export declare class ValidationException extends ApiException {
|
|
4
|
+
constructor(details: ApiErrorDetail[]);
|
|
5
|
+
static fromConstraints(constraints: Record<string, Record<string, string>>): ValidationException;
|
|
6
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationException = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const api_exception_1 = require("./api.exception");
|
|
6
|
+
class ValidationException extends api_exception_1.ApiException {
|
|
7
|
+
constructor(details) {
|
|
8
|
+
super('Validation failed', common_1.HttpStatus.BAD_REQUEST, 'VALIDATION_ERROR', details);
|
|
9
|
+
}
|
|
10
|
+
static fromConstraints(constraints) {
|
|
11
|
+
const details = Object.entries(constraints).map(([field, messages]) => ({
|
|
12
|
+
field,
|
|
13
|
+
message: Object.values(messages).join(', '),
|
|
14
|
+
}));
|
|
15
|
+
return new ValidationException(details);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.ValidationException = ValidationException;
|
|
19
|
+
//# sourceMappingURL=validation.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.exception.js","sourceRoot":"","sources":["../../src/exceptions/validation.exception.ts"],"names":[],"mappings":";;;AAAA,2CAA4C;AAC5C,mDAA+C;AAG/C,MAAa,mBAAoB,SAAQ,4BAAY;IACnD,YAAY,OAAyB;QACnC,KAAK,CAAC,mBAAmB,EAAE,mBAAU,CAAC,WAAW,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,CAAC,eAAe,CACpB,WAAmD;QAEnD,MAAM,OAAO,GAAqB,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAC/D,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;YACtB,KAAK;YACL,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;SAC5C,CAAC,CACH,CAAC;QACF,OAAO,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;CACF;AAhBD,kDAgBC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ArgumentsHost, ExceptionFilter } from '@nestjs/common';
|
|
2
|
+
import { ForgeOptions } from '../interfaces/api-response.interface';
|
|
3
|
+
export declare class ForgeExceptionFilter implements ExceptionFilter {
|
|
4
|
+
private readonly options;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
constructor(options?: ForgeOptions);
|
|
7
|
+
catch(exception: unknown, host: ArgumentsHost): void;
|
|
8
|
+
private buildMeta;
|
|
9
|
+
private buildErrorResponse;
|
|
10
|
+
private extractHttpExceptionMessage;
|
|
11
|
+
private extractValidationDetails;
|
|
12
|
+
}
|