nestjs-api-forge 1.0.2 → 1.0.3

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 CHANGED
@@ -1,17 +1,27 @@
1
1
  # nestjs-api-forge
2
2
 
3
- Standardized API response formatting, structured error handling, and exception filters for [NestJS](https://nestjs.com/) applications.
3
+ [![Build & Publish](https://github.com/mirzasaikatahmmed/nestjs-api-forge/actions/workflows/publish.yml/badge.svg)](https://github.com/mirzasaikatahmmed/nestjs-api-forge/actions/workflows/publish.yml)
4
+ [![npm version](https://img.shields.io/npm/v/nestjs-api-forge.svg)](https://www.npmjs.com/package/nestjs-api-forge)
5
+ [![npm downloads](https://img.shields.io/npm/dm/nestjs-api-forge.svg)](https://www.npmjs.com/package/nestjs-api-forge)
6
+ [![license](https://img.shields.io/npm/l/nestjs-api-forge.svg)](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 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
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
+ - **`@ApiForge`** — apply filter + interceptor to a single controller without going global
22
+ - **`ApiForgeModule.forRoot()`** — one-line global registration
23
+ - **`ApiForgeModule.forRootAsync()`** — config-service-driven async options
24
+ - **Request ID tracing** — optional UUID `requestId` in every response `meta`
15
25
 
16
26
  ---
17
27
 
@@ -25,7 +35,7 @@ npm install nestjs-api-forge
25
35
 
26
36
  ## Quick Start
27
37
 
28
- ### 1. Register globally (`app.module.ts`)
38
+ ### 1. Register globally in `app.module.ts`
29
39
 
30
40
  ```typescript
31
41
  import { Module } from '@nestjs/common';
@@ -34,39 +44,57 @@ import { ApiForgeModule } from 'nestjs-api-forge';
34
44
  @Module({
35
45
  imports: [
36
46
  ApiForgeModule.forRoot({
37
- version: '1.0',
38
- defaultSuccessMessage: 'OK',
47
+ version: '1.0.0',
48
+ defaultSuccessMessage: 'Request successful',
39
49
  includePath: true,
40
50
  includeTimestamp: true,
51
+ includeRequestId: true,
41
52
  }),
42
53
  ],
43
54
  })
44
55
  export class AppModule {}
45
56
  ```
46
57
 
47
- Every route in your application will now return a standardized response automatically.
58
+ Every route in your application now returns a standardized response automatically.
59
+
60
+ ### 2. Add `ValidationPipe` in `main.ts`
61
+
62
+ ```typescript
63
+ import { ValidationPipe } from '@nestjs/common';
64
+
65
+ app.useGlobalPipes(
66
+ new ValidationPipe({
67
+ whitelist: true,
68
+ forbidNonWhitelisted: true,
69
+ transform: true,
70
+ }),
71
+ );
72
+ ```
73
+
74
+ The exception filter automatically parses `ValidationPipe` errors and formats them into `error.details`.
48
75
 
49
76
  ---
50
77
 
51
- ## Response Formats
78
+ ## Response Shapes
52
79
 
53
- ### Success
80
+ ### Success (`2xx`)
54
81
 
55
82
  ```json
56
83
  {
57
84
  "success": true,
58
85
  "statusCode": 200,
59
- "message": "Request successful",
60
- "data": { "id": 1, "name": "Alice" },
86
+ "message": "User fetched successfully",
87
+ "data": { "id": 1, "name": "Alice Johnson", "email": "alice@example.com" },
61
88
  "meta": {
62
- "timestamp": "2026-05-02T10:00:00.000Z",
89
+ "timestamp": "2026-05-15T10:00:00.000Z",
63
90
  "path": "/api/users/1",
64
- "version": "1.0"
91
+ "version": "1.0.0",
92
+ "requestId": "a3f2c1d0-84e5-4b6a-9123-abc123def456"
65
93
  }
66
94
  }
67
95
  ```
68
96
 
69
- ### Error
97
+ ### Error (`4xx` / `5xx`)
70
98
 
71
99
  ```json
72
100
  {
@@ -77,9 +105,10 @@ Every route in your application will now return a standardized response automati
77
105
  "code": "NOT_FOUND"
78
106
  },
79
107
  "meta": {
80
- "timestamp": "2026-05-02T10:00:00.000Z",
108
+ "timestamp": "2026-05-15T10:00:00.000Z",
81
109
  "path": "/api/users/99",
82
- "version": "1.0"
110
+ "version": "1.0.0",
111
+ "requestId": "b1e2f3a4-0000-4b5c-8d9e-fedcba987654"
83
112
  }
84
113
  }
85
114
  ```
@@ -95,12 +124,35 @@ Every route in your application will now return a standardized response automati
95
124
  "code": "VALIDATION_ERROR",
96
125
  "details": [
97
126
  { "field": "email", "message": "must be an email" },
98
- { "field": "password", "message": "must be longer than 8 characters" }
127
+ { "field": "age", "message": "must be an integer number" }
99
128
  ]
100
129
  },
101
130
  "meta": {
102
- "timestamp": "2026-05-02T10:00:00.000Z",
103
- "path": "/api/auth/register"
131
+ "timestamp": "2026-05-15T10:00:00.000Z",
132
+ "path": "/api/users"
133
+ }
134
+ }
135
+ ```
136
+
137
+ ### Paginated (`ApiResponseDto.paginated()`)
138
+
139
+ ```json
140
+ {
141
+ "success": true,
142
+ "statusCode": 200,
143
+ "message": "Users fetched successfully",
144
+ "data": [ { "id": 1, "name": "Alice Johnson" } ],
145
+ "pagination": {
146
+ "total": 42,
147
+ "page": 2,
148
+ "limit": 10,
149
+ "totalPages": 5,
150
+ "hasNextPage": true,
151
+ "hasPrevPage": true
152
+ },
153
+ "meta": {
154
+ "timestamp": "2026-05-15T10:00:00.000Z",
155
+ "path": "/api/users?page=2&limit=10"
104
156
  }
105
157
  }
106
158
  ```
@@ -115,104 +167,171 @@ Every route in your application will now return a standardized response automati
115
167
  |---|---|---|---|
116
168
  | `includePath` | `boolean` | `true` | Include request path in `meta` |
117
169
  | `includeTimestamp` | `boolean` | `true` | Include ISO timestamp in `meta` |
170
+ | `includeRequestId` | `boolean` | `false` | Attach a generated UUID to `meta.requestId` |
118
171
  | `version` | `string` | `undefined` | API version string added to `meta` |
119
- | `defaultSuccessMessage` | `string` | `'Request successful'` | Default success message |
172
+ | `defaultSuccessMessage` | `string` | `'Request successful'` | Fallback success message |
173
+
174
+ ### `ApiForgeModule.forRootAsync(asyncOptions)`
175
+
176
+ ```typescript
177
+ ApiForgeModule.forRootAsync({
178
+ imports: [ConfigModule],
179
+ inject: [ConfigService],
180
+ useFactory: (config: ConfigService) => ({
181
+ version: config.get('API_VERSION'),
182
+ defaultSuccessMessage: config.get('DEFAULT_SUCCESS_MSG'),
183
+ includeRequestId: true,
184
+ }),
185
+ })
186
+ ```
120
187
 
121
188
  ### Decorators
122
189
 
123
190
  | Decorator | Scope | Description |
124
191
  |---|---|---|
125
- | `@ApiForge(options?)` | Controller / Method | Apply filter + interceptor to a single controller or method |
192
+ | `@ApiForge(options?)` | Controller / Method | Apply filter + interceptor without going global |
126
193
  | `@ForgeMessage(msg)` | Controller / Method | Override the success message for that route |
127
- | `@ForgeRawResponse()` | Controller / Method | Skip response wrapping; return handler value as-is |
194
+ | `@ForgeRawResponse()` | Controller / Method | Skip envelope wrapping; return raw handler value |
195
+
196
+ ### `ApiResponseDto` — manual usage
197
+
198
+ ```typescript
199
+ import { ApiResponseDto } from 'nestjs-api-forge';
200
+
201
+ // Success
202
+ ApiResponseDto.success(data, 'User fetched', 200, { path: '/users/1' });
203
+
204
+ // Created (201)
205
+ ApiResponseDto.created(data, 'User created');
206
+
207
+ // No content (204)
208
+ ApiResponseDto.noContent('Deleted');
209
+
210
+ // Paginated
211
+ ApiResponseDto.paginated(data, total, page, limit, 'Users fetched');
212
+
213
+ // Error
214
+ ApiResponseDto.error('Not found', 404, { code: 'NOT_FOUND' });
215
+ ```
128
216
 
129
217
  ### Built-in Exceptions
130
218
 
131
- All exceptions extend `ApiException` which extends NestJS's `HttpException`.
219
+ All exceptions extend `ApiException` → `HttpException` and produce a structured error body.
132
220
 
133
221
  | Class | Status | Code |
134
222
  |---|---|---|
135
223
  | `BadRequestException` | 400 | `BAD_REQUEST` |
136
224
  | `UnauthorizedException` | 401 | `UNAUTHORIZED` |
225
+ | `PaymentRequiredException` | 402 | `PAYMENT_REQUIRED` |
137
226
  | `ForbiddenException` | 403 | `FORBIDDEN` |
138
227
  | `NotFoundException` | 404 | `NOT_FOUND` |
228
+ | `MethodNotAllowedException` | 405 | `METHOD_NOT_ALLOWED` |
139
229
  | `ConflictException` | 409 | `CONFLICT` |
140
230
  | `UnprocessableEntityException` | 422 | `UNPROCESSABLE_ENTITY` |
141
231
  | `TooManyRequestsException` | 429 | `TOO_MANY_REQUESTS` |
142
232
  | `InternalServerException` | 500 | `INTERNAL_SERVER_ERROR` |
143
233
  | `ServiceUnavailableException` | 503 | `SERVICE_UNAVAILABLE` |
234
+ | `GatewayTimeoutException` | 504 | `GATEWAY_TIMEOUT` |
144
235
  | `ValidationException` | 400 | `VALIDATION_ERROR` |
145
236
 
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
237
  ---
158
238
 
159
239
  ## Usage Examples
160
240
 
161
- ### Controller with custom message
241
+ ### Standard CRUD controller
162
242
 
163
243
  ```typescript
164
- import { Controller, Get, Param } from '@nestjs/common';
165
- import { ForgeMessage, NotFoundException } from 'nestjs-api-forge';
244
+ import { Controller, Get, Post, Delete, Param, Body, HttpCode, HttpStatus } from '@nestjs/common';
245
+ import { ForgeMessage, ForgeRawResponse, NotFoundException } from 'nestjs-api-forge';
166
246
 
167
247
  @Controller('users')
168
248
  export class UsersController {
249
+ constructor(private readonly usersService: UsersService) {}
250
+
169
251
  @Get(':id')
170
252
  @ForgeMessage('User fetched successfully')
171
- findOne(@Param('id') id: string) {
172
- const user = this.usersService.findById(+id);
253
+ findOne(@Param('id') id: number) {
254
+ const user = this.usersService.findById(id);
173
255
  if (!user) throw new NotFoundException('User');
174
256
  return user;
175
257
  }
258
+
259
+ @Delete(':id')
260
+ @HttpCode(HttpStatus.NO_CONTENT)
261
+ remove(@Param('id') id: number) {
262
+ this.usersService.remove(id);
263
+ }
176
264
  }
177
265
  ```
178
266
 
179
- ### Skip wrapping for a specific route
267
+ ### Paginated list (skip envelope, build manually)
180
268
 
181
269
  ```typescript
182
- @Get('health')
270
+ import { ApiResponseDto, ForgeRawResponse } from 'nestjs-api-forge';
271
+
272
+ @Get()
183
273
  @ForgeRawResponse()
184
- healthCheck() {
185
- return { status: 'ok' };
274
+ findAll(@Query('page') page = '1', @Query('limit') limit = '10') {
275
+ const p = parseInt(page, 10);
276
+ const l = parseInt(limit, 10);
277
+ const { data, total } = this.usersService.findAll(p, l);
278
+ return ApiResponseDto.paginated(data, total, p, l, 'Users fetched');
186
279
  }
187
280
  ```
188
281
 
189
- ### Async module registration (with ConfigService)
282
+ ### Per-controller scope (no global module)
190
283
 
191
284
  ```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
- })
285
+ import { ApiForge, ForgeMessage } from 'nestjs-api-forge';
286
+
287
+ @Controller('products')
288
+ @ApiForge({ version: '2.0' })
289
+ export class ProductsController {
290
+ @Get()
291
+ @ForgeMessage('Products fetched successfully')
292
+ findAll() {
293
+ return this.productsService.findAll();
294
+ }
295
+ }
200
296
  ```
201
297
 
202
- ### Use with `ValidationPipe`
298
+ ### Raw response (health check)
203
299
 
204
300
  ```typescript
205
- // main.ts
206
- app.useGlobalPipes(
207
- new ValidationPipe({
208
- whitelist: true,
209
- forbidNonWhitelisted: true,
210
- transform: true,
211
- }),
212
- );
301
+ @Get('health')
302
+ @ForgeRawResponse()
303
+ health() {
304
+ return { status: 'ok', uptime: process.uptime() };
305
+ }
306
+ ```
307
+
308
+ ### Custom exception with field details
309
+
310
+ ```typescript
311
+ import { BadRequestException, ValidationException } from 'nestjs-api-forge';
312
+
313
+ // With field-level details
314
+ throw new BadRequestException('Invalid input', [
315
+ { field: 'price', message: 'Must be a positive number', value: -5 },
316
+ ]);
317
+
318
+ // From class-validator constraints map
319
+ throw ValidationException.fromConstraints({
320
+ email: { isEmail: 'must be an email' },
321
+ age: { min: 'must be at least 1' },
322
+ });
213
323
  ```
214
324
 
215
- The exception filter automatically parses `ValidationPipe` error arrays and formats them into `error.details`.
325
+ ---
326
+
327
+ ## Peer Dependencies
328
+
329
+ ```
330
+ @nestjs/common ^9 | ^10 | ^11
331
+ @nestjs/core ^9 | ^10 | ^11
332
+ reflect-metadata ^0.1 | ^0.2
333
+ rxjs ^7
334
+ ```
216
335
 
217
336
  ---
218
337
 
@@ -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: async (...args) => {
45
- const options = await asyncOptions.useFactory(...args);
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: 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 ?? [])],
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: [exceptionFilterProvider, responseInterceptorProvider],
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;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"}
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"}
@@ -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":"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"}
@@ -12,6 +12,7 @@ var ForgeExceptionFilter_1;
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.ForgeExceptionFilter = void 0;
14
14
  const common_1 = require("@nestjs/common");
15
+ const crypto_1 = require("crypto");
15
16
  const api_exception_1 = require("../exceptions/api.exception");
16
17
  const api_response_dto_1 = require("../dto/api-response.dto");
17
18
  const error_code_util_1 = require("../utils/error-code.util");
@@ -35,11 +36,12 @@ let ForgeExceptionFilter = ForgeExceptionFilter_1 = class ForgeExceptionFilter {
35
36
  response.status(errorResponse.statusCode).json(errorResponse);
36
37
  }
37
38
  buildMeta(request) {
38
- const { includePath = true, includeTimestamp = true, version } = this.options;
39
+ const { includePath = true, includeTimestamp = true, includeRequestId = false, version, } = this.options;
39
40
  return {
40
41
  ...(includeTimestamp && { timestamp: new Date().toISOString() }),
41
42
  ...(includePath && { path: request.url }),
42
43
  ...(version && { version }),
44
+ ...(includeRequestId && { requestId: (0, crypto_1.randomUUID)() }),
43
45
  };
44
46
  }
45
47
  buildErrorResponse(exception, meta) {
@@ -79,9 +81,13 @@ let ForgeExceptionFilter = ForgeExceptionFilter_1 = class ForgeExceptionFilter {
79
81
  if (!Array.isArray(r['message']))
80
82
  return [];
81
83
  return r['message'].map((msg) => {
82
- const parts = msg.split(' ');
83
- const field = parts.shift();
84
- return { field, message: parts.join(' ') };
84
+ const spaceIndex = msg.indexOf(' ');
85
+ if (spaceIndex === -1)
86
+ return { message: msg };
87
+ return {
88
+ field: msg.slice(0, spaceIndex),
89
+ message: msg.slice(spaceIndex + 1),
90
+ };
85
91
  });
86
92
  }
87
93
  };
@@ -1 +1 @@
1
- {"version":3,"file":"global-exception.filter.js","sourceRoot":"","sources":["../../src/filters/global-exception.filter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"global-exception.filter.js","sourceRoot":"","sources":["../../src/filters/global-exception.filter.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ForgeResponseInterceptor = void 0;
13
13
  const common_1 = require("@nestjs/common");
14
14
  const core_1 = require("@nestjs/core");
15
+ const crypto_1 = require("crypto");
15
16
  const operators_1 = require("rxjs/operators");
16
17
  const api_response_dto_1 = require("../dto/api-response.dto");
17
18
  const api_response_decorator_1 = require("../decorators/api-response.decorator");
@@ -36,11 +37,12 @@ let ForgeResponseInterceptor = class ForgeResponseInterceptor {
36
37
  }));
37
38
  }
38
39
  buildMeta(request) {
39
- const { includePath = true, includeTimestamp = true, version } = this.options;
40
+ const { includePath = true, includeTimestamp = true, includeRequestId = false, version, } = this.options;
40
41
  return {
41
42
  ...(includeTimestamp && { timestamp: new Date().toISOString() }),
42
43
  ...(includePath && { path: request.url }),
43
44
  ...(version && { version }),
45
+ ...(includeRequestId && { requestId: (0, crypto_1.randomUUID)() }),
44
46
  };
45
47
  }
46
48
  };
@@ -1 +1 @@
1
- {"version":3,"file":"response.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/response.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AACxB,uCAAyC;AAEzC,8CAAqC;AAErC,8DAAyD;AAEzD,iFAG8C;AAGvC,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;IACnC,YACmB,SAAoB,EACpB,UAAwB,EAAE;QAD1B,cAAS,GAAT,SAAS,CAAW;QACpB,YAAO,GAAP,OAAO,CAAmB;IAC1C,CAAC;IAEJ,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAC5C,+CAAsB,EACtB,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC3C,CAAC;QAEF,IAAI,KAAK;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QAEhC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACpD,0CAAiB,EACjB,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC3C,CAAC;QAEF,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC;QAC7D,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC;QAEnE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAErC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC,CAAC,IAAI,EAAE,EAAE;YACX,MAAM,OAAO,GACX,aAAa;gBACb,IAAI,CAAC,OAAO,CAAC,qBAAqB;gBAClC,oBAAoB,CAAC;YAEvB,OAAO,iCAAc,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACjE,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,OAAgB;QAChC,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,gBAAgB,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9E,OAAO;YACL,GAAG,CAAC,gBAAgB,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YAChE,GAAG,CAAC,WAAW,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;YACzC,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;SAC5B,CAAC;IACJ,CAAC;CACF,CAAA;AA5CY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,mBAAU,GAAE;qCAGmB,gBAAS;GAF5B,wBAAwB,CA4CpC"}
1
+ {"version":3,"file":"response.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/response.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AACxB,uCAAyC;AACzC,mCAAoC;AAEpC,8CAAqC;AAErC,8DAAyD;AAEzD,iFAG8C;AAGvC,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;IACnC,YACmB,SAAoB,EACpB,UAAwB,EAAE;QAD1B,cAAS,GAAT,SAAS,CAAW;QACpB,YAAO,GAAP,OAAO,CAAmB;IAC1C,CAAC;IAEJ,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAC5C,+CAAsB,EACtB,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC3C,CAAC;QAEF,IAAI,KAAK;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QAEhC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACpD,0CAAiB,EACjB,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC3C,CAAC;QAEF,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC;QAC7D,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC;QAEnE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAErC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,eAAG,EAAC,CAAC,IAAI,EAAE,EAAE;YACX,MAAM,OAAO,GACX,aAAa;gBACb,IAAI,CAAC,OAAO,CAAC,qBAAqB;gBAClC,oBAAoB,CAAC;YAEvB,OAAO,iCAAc,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACjE,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,OAAgB;QAChC,MAAM,EACJ,WAAW,GAAG,IAAI,EAClB,gBAAgB,GAAG,IAAI,EACvB,gBAAgB,GAAG,KAAK,EACxB,OAAO,GACR,GAAG,IAAI,CAAC,OAAO,CAAC;QACjB,OAAO;YACL,GAAG,CAAC,gBAAgB,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YAChE,GAAG,CAAC,WAAW,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;YACzC,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;YAC3B,GAAG,CAAC,gBAAgB,IAAI,EAAE,SAAS,EAAE,IAAA,mBAAU,GAAE,EAAE,CAAC;SACrD,CAAC;IACJ,CAAC;CACF,CAAA;AAlDY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,mBAAU,GAAE;qCAGmB,gBAAS;GAF5B,wBAAwB,CAkDpC"}
@@ -47,6 +47,7 @@ export interface ApiPaginatedResponse<T = unknown> {
47
47
  export interface ForgeOptions {
48
48
  includePath?: boolean;
49
49
  includeTimestamp?: boolean;
50
+ includeRequestId?: boolean;
50
51
  version?: string;
51
52
  defaultSuccessMessage?: string;
52
53
  }