nestjs-api-forge 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +246 -70
- package/dist/api-forge.module.js +15 -11
- package/dist/api-forge.module.js.map +1 -1
- package/dist/decorators/api-response.decorator.d.ts +4 -0
- package/dist/decorators/api-response.decorator.js +7 -1
- package/dist/decorators/api-response.decorator.js.map +1 -1
- package/dist/dto/api-response.dto.d.ts +1 -0
- package/dist/dto/api-response.dto.js +3 -0
- package/dist/dto/api-response.dto.js.map +1 -1
- package/dist/exceptions/api.exception.d.ts +9 -0
- package/dist/exceptions/api.exception.js +19 -1
- package/dist/exceptions/api.exception.js.map +1 -1
- package/dist/filters/global-exception.filter.d.ts +1 -0
- package/dist/filters/global-exception.filter.js +30 -5
- package/dist/filters/global-exception.filter.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interceptors/response.interceptor.d.ts +1 -0
- package/dist/interceptors/response.interceptor.js +45 -3
- package/dist/interceptors/response.interceptor.js.map +1 -1
- package/dist/interfaces/api-response.interface.d.ts +7 -0
- package/dist/pipes/forge-validation.pipe.d.ts +4 -0
- package/dist/pipes/forge-validation.pipe.js +34 -0
- package/dist/pipes/forge-validation.pipe.js.map +1 -0
- package/dist/pipes/index.d.ts +1 -0
- package/dist/pipes/index.js +18 -0
- package/dist/pipes/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +52 -52
package/README.md
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
# nestjs-api-forge
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/mirzasaikatahmmed/nestjs-api-forge/actions/workflows/publish.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/nestjs-api-forge)
|
|
5
|
+
[](https://www.npmjs.com/package/nestjs-api-forge)
|
|
6
|
+
[](https://github.com/mirzasaikatahmmed/nestjs-api-forge/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
Plug-and-play response envelope, exception filter, and error formatting for [NestJS](https://nestjs.com/) REST APIs — zero boilerplate, fully typed.
|
|
9
|
+
|
|
10
|
+
---
|
|
4
11
|
|
|
5
12
|
## Features
|
|
6
13
|
|
|
7
|
-
- **Uniform success
|
|
8
|
-
- **Structured error responses**
|
|
9
|
-
- **Global exception filter**
|
|
10
|
-
- **
|
|
11
|
-
-
|
|
12
|
-
- **`@
|
|
13
|
-
-
|
|
14
|
-
-
|
|
14
|
+
- **Uniform success envelope** — every handler response wrapped with `success`, `statusCode`, `message`, `data`, and `meta`
|
|
15
|
+
- **Structured error responses** — consistent `code`, `message`, and optional `details` array for all errors
|
|
16
|
+
- **Global exception filter** — handles `HttpException`, `ValidationPipe` errors, and unexpected exceptions
|
|
17
|
+
- **Paginated response helper** — `ApiResponseDto.paginated()` with full pagination meta
|
|
18
|
+
- **Built-in typed exceptions** — drop-in replacements for NestJS built-ins with structured error codes
|
|
19
|
+
- **`@ForgeMessage`** — override per-route success message
|
|
20
|
+
- **`@ForgeRawResponse`** — opt a route out of envelope wrapping
|
|
21
|
+
- **`@ForgeMeta`** — merge custom fields into `meta` per route or controller
|
|
22
|
+
- **`@ForgeDeprecated`** — mark a route as deprecated (adds `meta.deprecated` + `Deprecation` header)
|
|
23
|
+
- **`@ApiForge`** — apply filter + interceptor to a single controller without going global
|
|
24
|
+
- **`ForgeValidationPipe`** — drop-in `ValidationPipe` that throws structured `ValidationException` with typed field details
|
|
25
|
+
- **`ApiForgeModule.forRoot()`** — one-line global registration
|
|
26
|
+
- **`ApiForgeModule.forRootAsync()`** — config-service-driven async options
|
|
27
|
+
- **Correlation ID passthrough** — read `X-Request-ID` / `X-Correlation-ID` from requests, echo on responses
|
|
28
|
+
- **Response time** — optional `meta.responseTime` for every response
|
|
29
|
+
- **Request ID tracing** — optional auto-generated UUID `requestId` in every response `meta`
|
|
15
30
|
|
|
16
31
|
---
|
|
17
32
|
|
|
@@ -25,7 +40,7 @@ npm install nestjs-api-forge
|
|
|
25
40
|
|
|
26
41
|
## Quick Start
|
|
27
42
|
|
|
28
|
-
### 1. Register globally
|
|
43
|
+
### 1. Register globally in `app.module.ts`
|
|
29
44
|
|
|
30
45
|
```typescript
|
|
31
46
|
import { Module } from '@nestjs/common';
|
|
@@ -34,57 +49,70 @@ import { ApiForgeModule } from 'nestjs-api-forge';
|
|
|
34
49
|
@Module({
|
|
35
50
|
imports: [
|
|
36
51
|
ApiForgeModule.forRoot({
|
|
37
|
-
version: '1.0',
|
|
38
|
-
defaultSuccessMessage: '
|
|
52
|
+
version: '1.0.0',
|
|
53
|
+
defaultSuccessMessage: 'Request successful',
|
|
39
54
|
includePath: true,
|
|
40
55
|
includeTimestamp: true,
|
|
56
|
+
includeRequestId: true,
|
|
57
|
+
includeResponseTime: true,
|
|
58
|
+
correlationIdHeader: 'x-request-id',
|
|
41
59
|
}),
|
|
42
60
|
],
|
|
43
61
|
})
|
|
44
62
|
export class AppModule {}
|
|
45
63
|
```
|
|
46
64
|
|
|
47
|
-
|
|
65
|
+
### 2. Use `ForgeValidationPipe` in `main.ts`
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { ForgeValidationPipe } from 'nestjs-api-forge';
|
|
69
|
+
|
|
70
|
+
app.useGlobalPipes(new ForgeValidationPipe());
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`ForgeValidationPipe` extends NestJS `ValidationPipe` and throws a structured `ValidationException` with typed field-level details — no string parsing required.
|
|
48
74
|
|
|
49
75
|
---
|
|
50
76
|
|
|
51
|
-
## Response
|
|
77
|
+
## Response Shapes
|
|
52
78
|
|
|
53
|
-
### Success
|
|
79
|
+
### Success (`2xx`)
|
|
54
80
|
|
|
55
81
|
```json
|
|
56
82
|
{
|
|
57
83
|
"success": true,
|
|
58
84
|
"statusCode": 200,
|
|
59
|
-
"message": "
|
|
60
|
-
"data": { "id": 1, "name": "Alice" },
|
|
85
|
+
"message": "User fetched successfully",
|
|
86
|
+
"data": { "id": 1, "name": "Alice Johnson", "email": "alice@example.com" },
|
|
61
87
|
"meta": {
|
|
62
|
-
"timestamp": "2026-05-
|
|
88
|
+
"timestamp": "2026-05-15T10:00:00.000Z",
|
|
63
89
|
"path": "/api/users/1",
|
|
64
|
-
"version": "1.0"
|
|
90
|
+
"version": "1.0.0",
|
|
91
|
+
"requestId": "a3f2c1d0-84e5-4b6a-9123-abc123def456",
|
|
92
|
+
"responseTime": "4ms"
|
|
65
93
|
}
|
|
66
94
|
}
|
|
67
95
|
```
|
|
68
96
|
|
|
69
|
-
### Error
|
|
97
|
+
### Error (`4xx` / `5xx`)
|
|
70
98
|
|
|
71
99
|
```json
|
|
72
100
|
{
|
|
73
101
|
"success": false,
|
|
74
102
|
"statusCode": 404,
|
|
75
103
|
"message": "User not found",
|
|
76
|
-
"error": {
|
|
77
|
-
"code": "NOT_FOUND"
|
|
78
|
-
},
|
|
104
|
+
"error": { "code": "NOT_FOUND" },
|
|
79
105
|
"meta": {
|
|
80
|
-
"timestamp": "2026-05-
|
|
106
|
+
"timestamp": "2026-05-15T10:00:00.000Z",
|
|
81
107
|
"path": "/api/users/99",
|
|
82
|
-
"version": "1.0"
|
|
108
|
+
"version": "1.0.0",
|
|
109
|
+
"requestId": "b1e2f3a4-0000-4b5c-8d9e-fedcba987654",
|
|
110
|
+
"responseTime": "2ms"
|
|
83
111
|
}
|
|
84
112
|
}
|
|
85
113
|
```
|
|
86
114
|
|
|
87
|
-
### Validation Error
|
|
115
|
+
### Validation Error
|
|
88
116
|
|
|
89
117
|
```json
|
|
90
118
|
{
|
|
@@ -95,12 +123,49 @@ Every route in your application will now return a standardized response automati
|
|
|
95
123
|
"code": "VALIDATION_ERROR",
|
|
96
124
|
"details": [
|
|
97
125
|
{ "field": "email", "message": "must be an email" },
|
|
98
|
-
{ "field": "
|
|
126
|
+
{ "field": "address.zip", "message": "must be a string" }
|
|
99
127
|
]
|
|
100
128
|
},
|
|
129
|
+
"meta": { "timestamp": "2026-05-15T10:00:00.000Z", "path": "/api/users" }
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Paginated
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"success": true,
|
|
138
|
+
"statusCode": 200,
|
|
139
|
+
"message": "Users fetched successfully",
|
|
140
|
+
"data": [{ "id": 1, "name": "Alice Johnson" }],
|
|
141
|
+
"pagination": {
|
|
142
|
+
"total": 42,
|
|
143
|
+
"page": 2,
|
|
144
|
+
"limit": 10,
|
|
145
|
+
"totalPages": 5,
|
|
146
|
+
"hasNextPage": true,
|
|
147
|
+
"hasPrevPage": true
|
|
148
|
+
},
|
|
101
149
|
"meta": {
|
|
102
|
-
"timestamp": "2026-05-
|
|
103
|
-
"path": "/api/
|
|
150
|
+
"timestamp": "2026-05-15T10:00:00.000Z",
|
|
151
|
+
"path": "/api/users?page=2&limit=10",
|
|
152
|
+
"responseTime": "8ms"
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Deprecated route
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"success": true,
|
|
162
|
+
"statusCode": 200,
|
|
163
|
+
"message": "OK",
|
|
164
|
+
"data": { },
|
|
165
|
+
"meta": {
|
|
166
|
+
"timestamp": "2026-05-15T10:00:00.000Z",
|
|
167
|
+
"deprecated": true,
|
|
168
|
+
"deprecationNotice": "Use /v2/users instead"
|
|
104
169
|
}
|
|
105
170
|
}
|
|
106
171
|
```
|
|
@@ -115,104 +180,215 @@ Every route in your application will now return a standardized response automati
|
|
|
115
180
|
|---|---|---|---|
|
|
116
181
|
| `includePath` | `boolean` | `true` | Include request path in `meta` |
|
|
117
182
|
| `includeTimestamp` | `boolean` | `true` | Include ISO timestamp in `meta` |
|
|
183
|
+
| `includeRequestId` | `boolean` | `false` | Auto-generate UUID `requestId` in `meta` if no correlation header found |
|
|
184
|
+
| `correlationIdHeader` | `string \| string[]` | `['x-request-id', 'x-correlation-id']` | Header(s) to read request ID from; echoed back on the response |
|
|
185
|
+
| `includeResponseTime` | `boolean` | `false` | Include handler duration as `meta.responseTime` (e.g. `"12ms"`) |
|
|
118
186
|
| `version` | `string` | `undefined` | API version string added to `meta` |
|
|
119
|
-
| `defaultSuccessMessage` | `string` | `'Request successful'` |
|
|
187
|
+
| `defaultSuccessMessage` | `string` | `'Request successful'` | Fallback success message |
|
|
188
|
+
|
|
189
|
+
### `ApiForgeModule.forRootAsync(asyncOptions)`
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
ApiForgeModule.forRootAsync({
|
|
193
|
+
imports: [ConfigModule],
|
|
194
|
+
inject: [ConfigService],
|
|
195
|
+
useFactory: (config: ConfigService) => ({
|
|
196
|
+
version: config.get('API_VERSION'),
|
|
197
|
+
includeRequestId: true,
|
|
198
|
+
includeResponseTime: true,
|
|
199
|
+
correlationIdHeader: config.get('CORRELATION_HEADER'),
|
|
200
|
+
}),
|
|
201
|
+
})
|
|
202
|
+
```
|
|
120
203
|
|
|
121
204
|
### Decorators
|
|
122
205
|
|
|
123
206
|
| Decorator | Scope | Description |
|
|
124
207
|
|---|---|---|
|
|
125
|
-
| `@ApiForge(options?)` | Controller / Method | Apply filter + interceptor
|
|
208
|
+
| `@ApiForge(options?)` | Controller / Method | Apply filter + interceptor without going global |
|
|
126
209
|
| `@ForgeMessage(msg)` | Controller / Method | Override the success message for that route |
|
|
127
|
-
| `@ForgeRawResponse()` | Controller / Method | Skip
|
|
210
|
+
| `@ForgeRawResponse()` | Controller / Method | Skip envelope wrapping; return raw handler value |
|
|
211
|
+
| `@ForgeMeta(extra)` | Controller / Method | Merge extra key-value pairs into `meta` |
|
|
212
|
+
| `@ForgeDeprecated(notice?)` | Controller / Method | Mark route deprecated — adds `meta.deprecated`, optional `meta.deprecationNotice`, and `Deprecation: true` header |
|
|
213
|
+
|
|
214
|
+
### `ForgeValidationPipe`
|
|
215
|
+
|
|
216
|
+
Drop-in replacement for NestJS `ValidationPipe`. Throws `ValidationException` with structured `details` instead of a string-message array. Supports nested objects (dot-notation fields).
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// main.ts
|
|
220
|
+
app.useGlobalPipes(new ForgeValidationPipe());
|
|
221
|
+
|
|
222
|
+
// Override defaults
|
|
223
|
+
app.useGlobalPipes(new ForgeValidationPipe({
|
|
224
|
+
whitelist: false,
|
|
225
|
+
forbidNonWhitelisted: false,
|
|
226
|
+
}));
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### `ApiResponseDto` — manual usage
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { ApiResponseDto } from 'nestjs-api-forge';
|
|
233
|
+
|
|
234
|
+
ApiResponseDto.success(data, 'OK', 200, { path: '/users/1' });
|
|
235
|
+
ApiResponseDto.created(data, 'User created');
|
|
236
|
+
ApiResponseDto.accepted(jobRef, 'Export queued'); // 202
|
|
237
|
+
ApiResponseDto.noContent('Deleted'); // 204
|
|
238
|
+
ApiResponseDto.paginated(data, total, page, limit, 'Users fetched');
|
|
239
|
+
ApiResponseDto.error('Not found', 404, { code: 'NOT_FOUND' });
|
|
240
|
+
```
|
|
128
241
|
|
|
129
242
|
### Built-in Exceptions
|
|
130
243
|
|
|
131
|
-
All
|
|
244
|
+
All extend `ApiException` → `HttpException`.
|
|
132
245
|
|
|
133
246
|
| Class | Status | Code |
|
|
134
247
|
|---|---|---|
|
|
135
248
|
| `BadRequestException` | 400 | `BAD_REQUEST` |
|
|
136
249
|
| `UnauthorizedException` | 401 | `UNAUTHORIZED` |
|
|
250
|
+
| `PaymentRequiredException` | 402 | `PAYMENT_REQUIRED` |
|
|
137
251
|
| `ForbiddenException` | 403 | `FORBIDDEN` |
|
|
138
252
|
| `NotFoundException` | 404 | `NOT_FOUND` |
|
|
253
|
+
| `MethodNotAllowedException` | 405 | `METHOD_NOT_ALLOWED` |
|
|
139
254
|
| `ConflictException` | 409 | `CONFLICT` |
|
|
140
255
|
| `UnprocessableEntityException` | 422 | `UNPROCESSABLE_ENTITY` |
|
|
141
256
|
| `TooManyRequestsException` | 429 | `TOO_MANY_REQUESTS` |
|
|
142
257
|
| `InternalServerException` | 500 | `INTERNAL_SERVER_ERROR` |
|
|
143
258
|
| `ServiceUnavailableException` | 503 | `SERVICE_UNAVAILABLE` |
|
|
259
|
+
| `GatewayTimeoutException` | 504 | `GATEWAY_TIMEOUT` |
|
|
144
260
|
| `ValidationException` | 400 | `VALIDATION_ERROR` |
|
|
145
261
|
|
|
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
262
|
---
|
|
158
263
|
|
|
159
264
|
## Usage Examples
|
|
160
265
|
|
|
161
|
-
###
|
|
266
|
+
### Standard CRUD controller
|
|
162
267
|
|
|
163
268
|
```typescript
|
|
164
|
-
import { Controller, Get, Param } from '@nestjs/common';
|
|
165
|
-
import { ForgeMessage, NotFoundException } from 'nestjs-api-forge';
|
|
269
|
+
import { Controller, Get, Post, Delete, Param, Body, HttpCode, HttpStatus } from '@nestjs/common';
|
|
270
|
+
import { ForgeMessage, ForgeRawResponse, ForgeDeprecated, NotFoundException } from 'nestjs-api-forge';
|
|
166
271
|
|
|
167
272
|
@Controller('users')
|
|
168
273
|
export class UsersController {
|
|
169
274
|
@Get(':id')
|
|
170
275
|
@ForgeMessage('User fetched successfully')
|
|
171
|
-
findOne(@Param('id') id:
|
|
172
|
-
const user = this.usersService.findById(
|
|
276
|
+
findOne(@Param('id') id: number) {
|
|
277
|
+
const user = this.usersService.findById(id);
|
|
173
278
|
if (!user) throw new NotFoundException('User');
|
|
174
279
|
return user;
|
|
175
280
|
}
|
|
281
|
+
|
|
282
|
+
@Delete(':id')
|
|
283
|
+
@HttpCode(HttpStatus.NO_CONTENT)
|
|
284
|
+
remove(@Param('id') id: number) {
|
|
285
|
+
this.usersService.remove(id);
|
|
286
|
+
}
|
|
176
287
|
}
|
|
177
288
|
```
|
|
178
289
|
|
|
179
|
-
###
|
|
290
|
+
### Deprecated route
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
@Get('export')
|
|
294
|
+
@ForgeDeprecated('Use POST /v2/users/export instead')
|
|
295
|
+
@ForgeMessage('Export started')
|
|
296
|
+
startExport() {
|
|
297
|
+
const job = this.usersService.queueExport();
|
|
298
|
+
return ApiResponseDto.accepted({ jobId: job.id }, 'Export queued');
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Custom meta per route
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
@Get()
|
|
306
|
+
@ForgeMeta({ region: 'us-east-1', cache: 'miss' })
|
|
307
|
+
findAll() {
|
|
308
|
+
return this.usersService.findAll();
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Paginated list (raw response)
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
@Get()
|
|
316
|
+
@ForgeRawResponse()
|
|
317
|
+
findAll(@Query('page') page = '1', @Query('limit') limit = '10') {
|
|
318
|
+
const p = parseInt(page, 10);
|
|
319
|
+
const l = parseInt(limit, 10);
|
|
320
|
+
const { data, total } = this.usersService.findAll(p, l);
|
|
321
|
+
return ApiResponseDto.paginated(data, total, p, l, 'Users fetched');
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Per-controller scope (no global module)
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
@Controller('products')
|
|
329
|
+
@ApiForge({ version: '2.0', includeResponseTime: true })
|
|
330
|
+
export class ProductsController { ... }
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Raw response (health check)
|
|
180
334
|
|
|
181
335
|
```typescript
|
|
182
336
|
@Get('health')
|
|
183
337
|
@ForgeRawResponse()
|
|
184
|
-
|
|
185
|
-
return { status: 'ok' };
|
|
338
|
+
health() {
|
|
339
|
+
return { status: 'ok', uptime: process.uptime() };
|
|
186
340
|
}
|
|
187
341
|
```
|
|
188
342
|
|
|
189
|
-
###
|
|
343
|
+
### Correlation ID tracing
|
|
344
|
+
|
|
345
|
+
Send `X-Request-ID: abc-123` in the request — the same ID appears in `meta.requestId` and is echoed in the `X-Request-ID` response header. Useful for distributed tracing across microservices.
|
|
190
346
|
|
|
191
347
|
```typescript
|
|
192
|
-
ApiForgeModule.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
useFactory: (config: ConfigService) => ({
|
|
196
|
-
version: config.get('API_VERSION'),
|
|
197
|
-
defaultSuccessMessage: config.get('DEFAULT_SUCCESS_MSG'),
|
|
198
|
-
}),
|
|
348
|
+
ApiForgeModule.forRoot({
|
|
349
|
+
correlationIdHeader: 'x-request-id', // or an array of headers
|
|
350
|
+
includeRequestId: true, // generate UUID if header is absent
|
|
199
351
|
})
|
|
200
352
|
```
|
|
201
353
|
|
|
202
|
-
###
|
|
354
|
+
### Custom exception with field details
|
|
203
355
|
|
|
204
356
|
```typescript
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
|
|
357
|
+
throw new BadRequestException('Invalid input', [
|
|
358
|
+
{ field: 'price', message: 'Must be a positive number', value: -5 },
|
|
359
|
+
]);
|
|
360
|
+
|
|
361
|
+
// From class-validator constraint map
|
|
362
|
+
throw ValidationException.fromConstraints({
|
|
363
|
+
email: { isEmail: 'must be an email' },
|
|
364
|
+
age: { min: 'must be at least 1' },
|
|
365
|
+
});
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Peer Dependencies
|
|
371
|
+
|
|
213
372
|
```
|
|
373
|
+
@nestjs/common ^9 | ^10 | ^11
|
|
374
|
+
@nestjs/core ^9 | ^10 | ^11
|
|
375
|
+
reflect-metadata ^0.1 | ^0.2
|
|
376
|
+
rxjs ^7
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
---
|
|
214
380
|
|
|
215
|
-
|
|
381
|
+
## Changelog
|
|
382
|
+
|
|
383
|
+
### 1.1.0
|
|
384
|
+
- `ForgeValidationPipe` — structured validation errors with nested field support
|
|
385
|
+
- `@ForgeMeta(extra)` decorator — merge custom fields into response meta
|
|
386
|
+
- `@ForgeDeprecated(notice?)` decorator — deprecation flag in meta + response header
|
|
387
|
+
- `ApiResponseDto.accepted()` — 202 helper
|
|
388
|
+
- Correlation ID passthrough (`correlationIdHeader` option)
|
|
389
|
+
- Response time measurement (`includeResponseTime` option)
|
|
390
|
+
- `forRootAsync` fix — options factory now runs once instead of twice
|
|
391
|
+
- 3 new exceptions: `MethodNotAllowedException`, `PaymentRequiredException`, `GatewayTimeoutException`
|
|
216
392
|
|
|
217
393
|
---
|
|
218
394
|
|
package/dist/api-forge.module.js
CHANGED
|
@@ -39,26 +39,30 @@ let ApiForgeModule = ApiForgeModule_1 = class ApiForgeModule {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
static forRootAsync(asyncOptions) {
|
|
42
|
+
const optionsProvider = {
|
|
43
|
+
provide: exports.FORGE_OPTIONS,
|
|
44
|
+
useFactory: asyncOptions.useFactory,
|
|
45
|
+
inject: asyncOptions.inject ?? [],
|
|
46
|
+
};
|
|
42
47
|
const exceptionFilterProvider = {
|
|
43
48
|
provide: core_1.APP_FILTER,
|
|
44
|
-
useFactory:
|
|
45
|
-
|
|
46
|
-
return new global_exception_filter_1.ForgeExceptionFilter(options);
|
|
47
|
-
},
|
|
48
|
-
inject: asyncOptions.inject ?? [],
|
|
49
|
+
useFactory: (options) => new global_exception_filter_1.ForgeExceptionFilter(options),
|
|
50
|
+
inject: [exports.FORGE_OPTIONS],
|
|
49
51
|
};
|
|
50
52
|
const responseInterceptorProvider = {
|
|
51
53
|
provide: core_1.APP_INTERCEPTOR,
|
|
52
|
-
useFactory:
|
|
53
|
-
|
|
54
|
-
return new response_interceptor_1.ForgeResponseInterceptor(reflector, options);
|
|
55
|
-
},
|
|
56
|
-
inject: [core_1.Reflector, ...(asyncOptions.inject ?? [])],
|
|
54
|
+
useFactory: (reflector, options) => new response_interceptor_1.ForgeResponseInterceptor(reflector, options),
|
|
55
|
+
inject: [core_1.Reflector, exports.FORGE_OPTIONS],
|
|
57
56
|
};
|
|
58
57
|
return {
|
|
59
58
|
module: ApiForgeModule_1,
|
|
60
59
|
imports: asyncOptions.imports ?? [],
|
|
61
|
-
providers: [
|
|
60
|
+
providers: [
|
|
61
|
+
optionsProvider,
|
|
62
|
+
exceptionFilterProvider,
|
|
63
|
+
responseInterceptorProvider,
|
|
64
|
+
],
|
|
65
|
+
exports: [exports.FORGE_OPTIONS],
|
|
62
66
|
};
|
|
63
67
|
}
|
|
64
68
|
};
|
|
@@ -1 +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;
|
|
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;IACzB,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;IAED,MAAM,CAAC,YAAY,CAAC,YAInB;QACC,MAAM,eAAe,GAAa;YAChC,OAAO,EAAE,qBAAa;YACtB,UAAU,EAAE,YAAY,CAAC,UAAU;YACnC,MAAM,EAAE,YAAY,CAAC,MAAM,IAAI,EAAE;SAClC,CAAC;QAEF,MAAM,uBAAuB,GAAa;YACxC,OAAO,EAAE,iBAAU;YACnB,UAAU,EAAE,CAAC,OAAqB,EAAE,EAAE,CAAC,IAAI,8CAAoB,CAAC,OAAO,CAAC;YACxE,MAAM,EAAE,CAAC,qBAAa,CAAC;SACxB,CAAC;QAEF,MAAM,2BAA2B,GAAa;YAC5C,OAAO,EAAE,sBAAe;YACxB,UAAU,EAAE,CAAC,SAAoB,EAAE,OAAqB,EAAE,EAAE,CAC1D,IAAI,+CAAwB,CAAC,SAAS,EAAE,OAAO,CAAC;YAClD,MAAM,EAAE,CAAC,gBAAS,EAAE,qBAAa,CAAC;SACnC,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,OAAO,EAAE,YAAY,CAAC,OAAO,IAAI,EAAE;YACnC,SAAS,EAAE;gBACT,eAAe;gBACf,uBAAuB;gBACvB,2BAA2B;aAC5B;YACD,OAAO,EAAE,CAAC,qBAAa,CAAC;SACzB,CAAC;IACJ,CAAC;CACF,CAAA;AAjEY,wCAAc;yBAAd,cAAc;IAF1B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,cAAc,CAiE1B"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { ForgeOptions } from '../interfaces/api-response.interface';
|
|
2
2
|
export declare const FORGE_MESSAGE_KEY = "forge:response_message";
|
|
3
3
|
export declare const FORGE_RAW_RESPONSE_KEY = "forge:raw_response";
|
|
4
|
+
export declare const FORGE_META_KEY = "forge:extra_meta";
|
|
5
|
+
export declare const FORGE_DEPRECATED_KEY = "forge:deprecated";
|
|
4
6
|
export declare const ForgeMessage: (message: string) => import("@nestjs/common").CustomDecorator<string>;
|
|
5
7
|
export declare const ForgeRawResponse: () => import("@nestjs/common").CustomDecorator<string>;
|
|
8
|
+
export declare const ForgeMeta: (extra: Record<string, unknown>) => import("@nestjs/common").CustomDecorator<string>;
|
|
9
|
+
export declare const ForgeDeprecated: (notice?: string) => import("@nestjs/common").CustomDecorator<string>;
|
|
6
10
|
export declare function ApiForge(options?: ForgeOptions): <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ForgeRawResponse = exports.ForgeMessage = exports.FORGE_RAW_RESPONSE_KEY = exports.FORGE_MESSAGE_KEY = void 0;
|
|
3
|
+
exports.ForgeDeprecated = exports.ForgeMeta = exports.ForgeRawResponse = exports.ForgeMessage = exports.FORGE_DEPRECATED_KEY = exports.FORGE_META_KEY = exports.FORGE_RAW_RESPONSE_KEY = exports.FORGE_MESSAGE_KEY = void 0;
|
|
4
4
|
exports.ApiForge = ApiForge;
|
|
5
5
|
const common_1 = require("@nestjs/common");
|
|
6
6
|
const core_1 = require("@nestjs/core");
|
|
@@ -8,10 +8,16 @@ const response_interceptor_1 = require("../interceptors/response.interceptor");
|
|
|
8
8
|
const global_exception_filter_1 = require("../filters/global-exception.filter");
|
|
9
9
|
exports.FORGE_MESSAGE_KEY = 'forge:response_message';
|
|
10
10
|
exports.FORGE_RAW_RESPONSE_KEY = 'forge:raw_response';
|
|
11
|
+
exports.FORGE_META_KEY = 'forge:extra_meta';
|
|
12
|
+
exports.FORGE_DEPRECATED_KEY = 'forge:deprecated';
|
|
11
13
|
const ForgeMessage = (message) => (0, common_1.SetMetadata)(exports.FORGE_MESSAGE_KEY, message);
|
|
12
14
|
exports.ForgeMessage = ForgeMessage;
|
|
13
15
|
const ForgeRawResponse = () => (0, common_1.SetMetadata)(exports.FORGE_RAW_RESPONSE_KEY, true);
|
|
14
16
|
exports.ForgeRawResponse = ForgeRawResponse;
|
|
17
|
+
const ForgeMeta = (extra) => (0, common_1.SetMetadata)(exports.FORGE_META_KEY, extra);
|
|
18
|
+
exports.ForgeMeta = ForgeMeta;
|
|
19
|
+
const ForgeDeprecated = (notice) => (0, common_1.SetMetadata)(exports.FORGE_DEPRECATED_KEY, notice ?? true);
|
|
20
|
+
exports.ForgeDeprecated = ForgeDeprecated;
|
|
15
21
|
function ApiForge(options = {}) {
|
|
16
22
|
const reflector = new core_1.Reflector();
|
|
17
23
|
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)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-response.decorator.js","sourceRoot":"","sources":["../../src/decorators/api-response.decorator.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"api-response.decorator.js","sourceRoot":"","sources":["../../src/decorators/api-response.decorator.ts"],"names":[],"mappings":";;;AA0CA,4BAMC;AAhDD,2CAA2F;AAC3F,uCAAyC;AACzC,+EAAgF;AAChF,gFAA0E;AAG7D,QAAA,iBAAiB,GAAG,wBAAwB,CAAC;AAC7C,QAAA,sBAAsB,GAAG,oBAAoB,CAAC;AAC9C,QAAA,cAAc,GAAG,kBAAkB,CAAC;AACpC,QAAA,oBAAoB,GAAG,kBAAkB,CAAC;AAGhD,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;AAQzE,MAAM,SAAS,GAAG,CAAC,KAA8B,EAAE,EAAE,CAC1D,IAAA,oBAAW,EAAC,sBAAc,EAAE,KAAK,CAAC,CAAC;AADxB,QAAA,SAAS,aACe;AAU9B,MAAM,eAAe,GAAG,CAAC,MAAe,EAAE,EAAE,CACjD,IAAA,oBAAW,EAAC,4BAAoB,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;AADvC,QAAA,eAAe,mBACwB;AAMpD,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"}
|
|
@@ -2,6 +2,7 @@ import { ApiErrorPayload, ApiMeta, ApiSuccessResponse, ApiErrorResponse, ApiPagi
|
|
|
2
2
|
export declare class ApiResponseDto {
|
|
3
3
|
static success<T>(data: T, message?: string, statusCode?: number, meta?: Partial<ApiMeta>): ApiSuccessResponse<T>;
|
|
4
4
|
static created<T>(data: T, message?: string, meta?: Partial<ApiMeta>): ApiSuccessResponse<T>;
|
|
5
|
+
static accepted<T>(data: T, message?: string, meta?: Partial<ApiMeta>): ApiSuccessResponse<T>;
|
|
5
6
|
static noContent(message?: string, meta?: Partial<ApiMeta>): ApiSuccessResponse<null>;
|
|
6
7
|
static paginated<T>(data: T[], total: number, page: number, limit: number, message?: string, meta?: Partial<ApiMeta>): ApiPaginatedResponse<T>;
|
|
7
8
|
static error(message: string, statusCode: number, error: ApiErrorPayload, meta?: Partial<ApiMeta>): ApiErrorResponse;
|
|
@@ -17,6 +17,9 @@ class ApiResponseDto {
|
|
|
17
17
|
static created(data, message = 'Resource created successfully', meta = {}) {
|
|
18
18
|
return ApiResponseDto.success(data, message, 201, meta);
|
|
19
19
|
}
|
|
20
|
+
static accepted(data, message = 'Request accepted for processing', meta = {}) {
|
|
21
|
+
return ApiResponseDto.success(data, message, 202, meta);
|
|
22
|
+
}
|
|
20
23
|
static noContent(message = 'No content', meta = {}) {
|
|
21
24
|
return ApiResponseDto.success(null, message, 204, meta);
|
|
22
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-response.dto.js","sourceRoot":"","sources":["../../src/dto/api-response.dto.ts"],"names":[],"mappings":";;;AASA,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,SAAS,CACd,IAAS,EACT,KAAa,EACb,IAAY,EACZ,KAAa,EACb,OAAO,GAAG,2BAA2B,EACrC,OAAyB,EAAE;QAE3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAmB;YACjC,KAAK;YACL,IAAI;YACJ,KAAK;YACL,UAAU;YACV,WAAW,EAAE,IAAI,GAAG,UAAU;YAC9B,WAAW,EAAE,IAAI,GAAG,CAAC;SACtB,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,GAAG;YACf,OAAO;YACP,IAAI;YACJ,UAAU;YACV,IAAI,EAAE;gBACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,GAAG,IAAI;aACR;SACF,CAAC;IACJ,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;
|
|
1
|
+
{"version":3,"file":"api-response.dto.js","sourceRoot":"","sources":["../../src/dto/api-response.dto.ts"],"names":[],"mappings":";;;AASA,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,QAAQ,CACb,IAAO,EACP,OAAO,GAAG,iCAAiC,EAC3C,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,SAAS,CACd,IAAS,EACT,KAAa,EACb,IAAY,EACZ,KAAa,EACb,OAAO,GAAG,2BAA2B,EACrC,OAAyB,EAAE;QAE3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAmB;YACjC,KAAK;YACL,IAAI;YACJ,KAAK;YACL,UAAU;YACV,WAAW,EAAE,IAAI,GAAG,UAAU;YAC9B,WAAW,EAAE,IAAI,GAAG,CAAC;SACtB,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,GAAG;YACf,OAAO;YACP,IAAI;YACJ,UAAU;YACV,IAAI,EAAE;gBACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,GAAG,IAAI;aACR;SACF,CAAC;IACJ,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;AA1FD,wCA0FC"}
|
|
@@ -32,3 +32,12 @@ export declare class InternalServerException extends ApiException {
|
|
|
32
32
|
export declare class ServiceUnavailableException extends ApiException {
|
|
33
33
|
constructor(message?: string);
|
|
34
34
|
}
|
|
35
|
+
export declare class MethodNotAllowedException extends ApiException {
|
|
36
|
+
constructor(message?: string);
|
|
37
|
+
}
|
|
38
|
+
export declare class PaymentRequiredException extends ApiException {
|
|
39
|
+
constructor(message?: string);
|
|
40
|
+
}
|
|
41
|
+
export declare class GatewayTimeoutException extends ApiException {
|
|
42
|
+
constructor(message?: string);
|
|
43
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
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;
|
|
3
|
+
exports.GatewayTimeoutException = exports.PaymentRequiredException = exports.MethodNotAllowedException = exports.ServiceUnavailableException = exports.InternalServerException = exports.TooManyRequestsException = exports.UnprocessableEntityException = exports.ConflictException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.ApiException = void 0;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
5
|
class ApiException extends common_1.HttpException {
|
|
6
6
|
constructor(message, statusCode, code, details) {
|
|
@@ -64,4 +64,22 @@ class ServiceUnavailableException extends ApiException {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
exports.ServiceUnavailableException = ServiceUnavailableException;
|
|
67
|
+
class MethodNotAllowedException extends ApiException {
|
|
68
|
+
constructor(message = 'Method not allowed') {
|
|
69
|
+
super(message, common_1.HttpStatus.METHOD_NOT_ALLOWED, 'METHOD_NOT_ALLOWED');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.MethodNotAllowedException = MethodNotAllowedException;
|
|
73
|
+
class PaymentRequiredException extends ApiException {
|
|
74
|
+
constructor(message = 'Payment required') {
|
|
75
|
+
super(message, common_1.HttpStatus.PAYMENT_REQUIRED, 'PAYMENT_REQUIRED');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.PaymentRequiredException = PaymentRequiredException;
|
|
79
|
+
class GatewayTimeoutException extends ApiException {
|
|
80
|
+
constructor(message = 'Gateway timeout') {
|
|
81
|
+
super(message, common_1.HttpStatus.GATEWAY_TIMEOUT, 'GATEWAY_TIMEOUT');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.GatewayTimeoutException = GatewayTimeoutException;
|
|
67
85
|
//# sourceMappingURL=api.exception.js.map
|
|
@@ -1 +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"}
|
|
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;AAED,MAAa,yBAA0B,SAAQ,YAAY;IACzD,YAAY,OAAO,GAAG,oBAAoB;QACxC,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC;IACtE,CAAC;CACF;AAJD,8DAIC;AAED,MAAa,wBAAyB,SAAQ,YAAY;IACxD,YAAY,OAAO,GAAG,kBAAkB;QACtC,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAClE,CAAC;CACF;AAJD,4DAIC;AAED,MAAa,uBAAwB,SAAQ,YAAY;IACvD,YAAY,OAAO,GAAG,iBAAiB;QACrC,KAAK,CAAC,OAAO,EAAE,mBAAU,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;IAChE,CAAC;CACF;AAJD,0DAIC"}
|
|
@@ -5,6 +5,7 @@ export declare class ForgeExceptionFilter implements ExceptionFilter {
|
|
|
5
5
|
private readonly logger;
|
|
6
6
|
constructor(options?: ForgeOptions);
|
|
7
7
|
catch(exception: unknown, host: ArgumentsHost): void;
|
|
8
|
+
private resolveRequestId;
|
|
8
9
|
private buildMeta;
|
|
9
10
|
private buildErrorResponse;
|
|
10
11
|
private extractHttpExceptionMessage;
|