@myko.pk/response 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright © 2026 MYKO Pakistan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,256 @@
1
+ <p align="center">
2
+ <h1 align="center">@myko.pk/response</h1>
3
+ <p align="center"><strong>Consistent responses. Clear errors.</strong></p>
4
+ <p align="center">Shared response utilities, builders, and exception filters for MYKO services. Provides a unified API response envelope, configurable NestJS exception filters, a response interceptor for automatic wrapping, request context tracking, Swagger integration, and reusable pagination DTOs.</p>
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/@myko.pk/response"><img src="https://img.shields.io/npm/v/@myko.pk/response?style=for-the-badge&logo=npm&logoColor=white" alt="npm version"></a>
7
+ <a href="https://www.npmjs.com/package/@myko.pk/response"><img src="https://img.shields.io/npm/dm/@myko.pk/response?style=for-the-badge&logo=npm&logoColor=white" alt="npm downloads"></a>
8
+ <a href="https://github.com/mykopk/response/actions"><img src="https://img.shields.io/github/actions/workflow/status/mykopk/response/ci.yml?style=for-the-badge&logo=githubactions&logoColor=white&label=CI" alt="build"></a>
9
+ <a href="https://github.com/mykopk/response"><img src="https://img.shields.io/github/stars/mykopk/response?style=for-the-badge&logo=github" alt="stars"></a>
10
+ <a href="https://github.com/mykopk/response"><img src="https://img.shields.io/github/forks/mykopk/response?style=for-the-badge&logo=github" alt="forks"></a>
11
+ <a href="https://github.com/mykopk/response"><img src="https://img.shields.io/github/issues/mykopk/response?style=for-the-badge&logo=github" alt="issues"></a>
12
+ <a href="https://github.com/mykopk/response"><img src="https://img.shields.io/github/last-commit/mykopk/response?style=for-the-badge&logo=github" alt="last commit"></a>
13
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge" alt="license"></a>
14
+ </p>
15
+ </p>
16
+
17
+ ## 📑 Table of Contents
18
+
19
+ - [Description](#description)
20
+ - [Key Features](#key-features)
21
+ - [Use Cases](#use-cases)
22
+ - [Tech Stack](#tech-stack)
23
+ - [Quick Start](#quick-start)
24
+ - [Available Scripts](#available-scripts)
25
+ - [Project Structure](#project-structure)
26
+ - [Contributors](#contributors)
27
+ - [Contributing](#contributing)
28
+ - [License](#license)
29
+
30
+ ## 📝 Description
31
+
32
+ @myko.pk/response provides a standardised response envelope (`ApiResponse<T>`) and a set of reusable NestJS exception filters for every MYKO service. The `ResponseBuilder` class offers a fluent API for constructing success, error, paginated, cursor-paginated, and specialised responses. Built-in exception filters handle `HttpException`, validation errors, database errors, and auth failures — all rendered into a consistent `ApiResponse` shape.
33
+
34
+ The package also includes a request context system (AsyncLocalStorage-based requestId tracking across the request lifecycle), decorators for fine-grained control over response wrapping, reusable pagination DTOs, a Swagger decorator to document the `ApiResponse` envelope, and a validation error formatter utility.
35
+
36
+ ## ✨ Key Features
37
+
38
+ - **📦 Unified Response Envelope** — Every response follows the `ApiResponse<T>` shape: `success`, `statusCode`, `message`, `data`, `error`, `timestamp`, `requestId`.
39
+ - **🏗️ Fluent Response Builder** — `ResponseBuilder.success()`, `ResponseBuilder.error()`, `ResponseBuilder.paginated()`, `ResponseBuilder.cursorPaginated()`, `ResponseBuilder.ok()`, and specialised methods for bulk, import/export, redirect, file download, and partial success.
40
+ - **🛡️ Configurable Exception Filters** — 5 NestJS exception filters covering global, validation, HTTP, database, and auth exceptions. Register all or pick specific ones via `ResponseModule.forRoot()`.
41
+ - **🔄 Response Interceptor** — Automatically wraps controller returns into `ApiResponse`. Respects `@SkipResponseWrapper()` and `@ResponseMessage()` decorators.
42
+ - **🔗 Request Context** — `RequestContextInterceptor` captures or generates a `requestId` (via `x-request-id` header or `crypto.randomUUID()`) and stores it in AsyncLocalStorage. Access it anywhere with `responseContext.getStore()`.
43
+ - **📐 Reusable DTOs** — `PaginatedQueryDto` and `CursorPaginatedQueryDto` with `class-validator` decorators for consistent pagination parameters.
44
+ - **📘 Swagger Integration** — `@ApiResponseEnvelope(YourDto)` decorator documents the full `ApiResponse<T>` wrapper shape in your OpenAPI spec.
45
+ - **🔍 Validation Formatter** — `formatValidationErrors()` flattens NestJS `ValidationError[]` into a structured `{ field, constraints, children? }[]` shape.
46
+ - **📘 Fully Typed** — Full TypeScript support with strict mode, typed response envelopes, and filter options.
47
+
48
+ ## 🎯 Use Cases
49
+
50
+ - Standardising API response format across all MYKO NestJS microservices.
51
+ - Replacing ad-hoc error handling with consistent, typed exception filters.
52
+ - Automatically wrapping all controller responses in a uniform envelope.
53
+ - Tracking request IDs across the entire request lifecycle without manual parameter passing.
54
+ - Handling validation errors with structured field-level error messages.
55
+ - Documenting the `ApiResponse` envelope in Swagger/OpenAPI without manual schema definitions.
56
+ - Building paginated endpoints with reusable, validated query DTOs.
57
+ - Rendering user-friendly error pages for browser-facing requests.
58
+
59
+ ## 🛠️ Tech Stack
60
+
61
+ - 📘 **TypeScript** (strict mode)
62
+ - 🪺 **NestJS** (optional: `@nestjs/swagger` for OpenAPI decorator)
63
+ - 🚂 **Express**
64
+
65
+ ## ⚡ Quick Start
66
+
67
+ ### Installation
68
+
69
+ ```bash
70
+ npm install @myko.pk/response
71
+
72
+ # Optional — for paginated DTOs
73
+ npm install class-validator class-transformer
74
+
75
+ # Optional — for Swagger decorator
76
+ npm install @nestjs/swagger
77
+ ```
78
+
79
+ ### Response Builder
80
+
81
+ ```ts
82
+ import { ResponseBuilder } from '@myko.pk/response';
83
+
84
+ // Success response
85
+ ResponseBuilder.success(data, 'User fetched', 200, requestId);
86
+ ResponseBuilder.created(newUser); // 201
87
+ ResponseBuilder.ok('Operation completed'); // 200, no data
88
+ ResponseBuilder.noContent('Item deleted'); // 204
89
+
90
+ // Error response
91
+ ResponseBuilder.error('User not found', 'USER_NOT_FOUND', 404, 'User ID: 123', requestId);
92
+
93
+ // Offset pagination
94
+ ResponseBuilder.paginated(items, total, page, limit);
95
+
96
+ // Cursor pagination (infinite scroll / load more)
97
+ ResponseBuilder.cursorPaginated(items, total, nextCursor, hasNextPage, limit);
98
+ ```
99
+
100
+ ### Module Registration
101
+
102
+ ```ts
103
+ import { Module } from '@nestjs/common';
104
+ import { ResponseModule } from '@myko.pk/response';
105
+
106
+ @Module({
107
+ imports: [
108
+ ResponseModule.forRoot({
109
+ filters: ['GLOBAL', 'VALIDATION', 'HTTP', 'DATABASE', 'AUTH'],
110
+ enableResponseWrapper: true, // auto-wrap controller returns
111
+ enableRequestContext: true, // auto-track requestId via AsyncLocalStorage
112
+ }),
113
+ ],
114
+ })
115
+ export class AppModule {}
116
+ ```
117
+
118
+ ### Decorators
119
+
120
+ ```ts
121
+ import { SkipResponseWrapper, ResponseMessage } from '@myko.pk/response';
122
+
123
+ @SkipResponseWrapper() // skip auto-wrapping for this route
124
+ @ResponseMessage('Users fetched') // override default "Success" message
125
+ @Get('/users')
126
+ getUsers() { ... }
127
+ ```
128
+
129
+ ### Swagger
130
+
131
+ ```ts
132
+ import { ApiResponseEnvelope } from '@myko.pk/response';
133
+ import { UserDto } from './user.dto';
134
+
135
+ @Get('/users')
136
+ @ApiResponseEnvelope(UserDto) // documents ApiResponse<UserDto> in OpenAPI
137
+ getUsers() { ... }
138
+ ```
139
+
140
+ ### Paginated DTOs
141
+
142
+ ```ts
143
+ import { PaginatedQueryDto, CursorPaginatedQueryDto } from '@myko.pk/response';
144
+
145
+ @Get('/users')
146
+ async getUsers(@Query() query: PaginatedQueryDto) {
147
+ // query.page -> number (default 1)
148
+ // query.limit -> number (default 20, max 100)
149
+ }
150
+ ```
151
+
152
+ ### Request Context (AsyncLocalStorage)
153
+
154
+ ```ts
155
+ import { responseContext } from '@myko.pk/response';
156
+
157
+ // Inside any service (after RequestContextInterceptor has run)
158
+ const ctx = responseContext.getStore();
159
+ console.log(ctx?.requestId); // "abc-123"
160
+ console.log(ctx?.path); // "/api/users"
161
+ console.log(ctx?.method); // "GET"
162
+ ```
163
+
164
+ ## 🚀 Available Scripts
165
+
166
+ - **build** — `npm run build` (tsup → CJS + ESM + DTS, copies views/)
167
+ - **dev** — `npm run dev` (tsup --watch)
168
+ - **typecheck** — `npm run typecheck` (tsc --noEmit)
169
+
170
+ ## 📁 Project Structure
171
+
172
+ ```
173
+ .
174
+ ├── CHANGELOG.md
175
+ ├── CONTRIBUTING.md
176
+ ├── LICENSE
177
+ ├── SECURITY.md
178
+ ├── package.json
179
+ ├── docs/
180
+ │ ├── README.md
181
+ │ └── QUICK-START.md
182
+ ├── src
183
+ │ ├── builders
184
+ │ │ └── response.builder.ts
185
+ │ ├── decorators
186
+ │ │ ├── skip-response-wrapper.decorator.ts
187
+ │ │ └── response-message.decorator.ts
188
+ │ ├── dto
189
+ │ │ └── paginated-query.dto.ts
190
+ │ ├── filters
191
+ │ │ ├── auth.filter.ts
192
+ │ │ ├── database.filter.ts
193
+ │ │ ├── global-exception.filter.ts
194
+ │ │ ├── http-exception.filter.ts
195
+ │ │ └── validation.filter.ts
196
+ │ ├── interceptors
197
+ │ │ ├── response.interceptor.ts
198
+ │ ├── request-context
199
+ │ │ ├── request-context.interceptor.ts
200
+ │ ├── swagger
201
+ │ │ └── api-response-envelope.decorator.ts
202
+ │ ├── validation
203
+ │ │ └── validation-formatter.ts
204
+ │ ├── index.ts
205
+ │ ├── response.constants.ts
206
+ │ ├── response.context.ts
207
+ │ ├── response.module.ts
208
+ │ ├── types.ts
209
+ │ └── views-path.ts
210
+ ├── tsconfig.json
211
+ ├── tsup.config.mjs
212
+ └── views
213
+ └── error.hbs
214
+ ```
215
+
216
+ ## 🛠️ Development Setup
217
+
218
+ 1. Install Node.js (v18+ recommended)
219
+ 2. Install dependencies: `npm install`
220
+ 3. Build: `npm run build`
221
+
222
+ > **Note:** This package does not currently have tests. Tests will be added in a future release.
223
+
224
+ ## 👥 Contributors
225
+
226
+ <p align="left">
227
+ <a href="https://github.com/arsalanwahab" title="arsalanwahab"><img src="https://avatars.githubusercontent.com/u/178069156?v=4&s=64" width="64" height="64" alt="arsalanwahab" style="border-radius:50%" /></a>
228
+ </p>
229
+
230
+ [See the full list of contributors →](https://github.com/mykopk/response/graphs/contributors)
231
+
232
+ ## 👥 Contributing
233
+
234
+ Contributions are welcome! Here's the standard flow:
235
+
236
+ 1. **Fork** the repository
237
+ 2. **Clone** your fork: `git clone https://github.com/mykopk/response.git`
238
+ 3. **Branch**: `git checkout -b feature/your-feature`
239
+ 4. **Commit**: `git commit -m 'feat: add some feature'`
240
+ 5. **Push**: `git push origin feature/your-feature`
241
+ 6. **Open** a pull request
242
+
243
+ Please follow the existing code style and include tests for new behavior where applicable.
244
+
245
+ ## 📜 License
246
+
247
+ This project is licensed under the **MIT** License.
248
+
249
+
250
+ MYKO Pakistan
251
+
252
+ Detail Information
253
+ Website myko.pk
254
+ Email support@myko.pk
255
+ About Building digital infrastructure and super-app experiences for millions of users across Pakistan.
256
+ Built with ❤️ in Pakistan 🇵🇰
@@ -0,0 +1,315 @@
1
+ 'use strict';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
+
6
+ // src/response.constants.ts
7
+ var HTTP_STATUS = {
8
+ OK: 200,
9
+ CREATED: 201,
10
+ ACCEPTED: 202,
11
+ NO_CONTENT: 204,
12
+ MULTI_STATUS: 207,
13
+ FOUND: 302,
14
+ BAD_REQUEST: 400
15
+ };
16
+ var RESPONSE_MESSAGES = {
17
+ SUCCESS: "Success",
18
+ CREATED: "Created successfully",
19
+ ACCEPTED: "Request accepted",
20
+ NO_CONTENT: "No content",
21
+ UPDATED: "Updated successfully",
22
+ DELETED: "Deleted successfully",
23
+ PARTIAL_SUCCESS: "Partially successful",
24
+ REDIRECTING: "Redirecting",
25
+ FILE_READY: "File ready for download"
26
+ };
27
+
28
+ // src/builders/response.builder.ts
29
+ var ResponseBuilder = class {
30
+ static {
31
+ __name(this, "ResponseBuilder");
32
+ }
33
+ /**
34
+ * Build a success response
35
+ * @template T - Type of response data
36
+ * @param data - Response data
37
+ * @param message - Success message
38
+ * @param statusCode - HTTP status code
39
+ * @param requestId - Request tracking ID for correlation
40
+ * @returns ApiResponse with success data
41
+ */
42
+ static success(data, message = RESPONSE_MESSAGES.SUCCESS, statusCode = HTTP_STATUS.OK, requestId) {
43
+ return {
44
+ success: true,
45
+ statusCode,
46
+ message,
47
+ data,
48
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
49
+ requestId
50
+ };
51
+ }
52
+ /**
53
+ * Shorthand success response with no data payload (e.g. status-only endpoints)
54
+ * @param message - Success message
55
+ * @param statusCode - HTTP status code
56
+ * @param requestId - Request tracking ID for correlation
57
+ * @returns ApiResponse with no data field
58
+ */
59
+ static ok(message = RESPONSE_MESSAGES.SUCCESS, statusCode = HTTP_STATUS.OK, requestId) {
60
+ return {
61
+ success: true,
62
+ statusCode,
63
+ message,
64
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
65
+ requestId
66
+ };
67
+ }
68
+ /**
69
+ * Build an error response
70
+ * @param message - Error message
71
+ * @param code - Error code for categorization
72
+ * @param statusCode - HTTP status code
73
+ * @param details - Additional error details
74
+ * @param requestId - Request tracking ID for correlation
75
+ * @returns ApiResponse with error information
76
+ */
77
+ static error(message, code, statusCode = HTTP_STATUS.BAD_REQUEST, details, requestId) {
78
+ return {
79
+ success: false,
80
+ statusCode,
81
+ message,
82
+ error: {
83
+ code,
84
+ details
85
+ },
86
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
87
+ requestId
88
+ };
89
+ }
90
+ /**
91
+ * Build a paginated response
92
+ * @template T - Type of array items
93
+ * @param data - Array of items
94
+ * @param total - Total number of items available
95
+ * @param page - Current page number
96
+ * @param limit - Items per page
97
+ * @param message - Success message
98
+ * @param statusCode - HTTP status code
99
+ * @param requestId - Request tracking ID for correlation
100
+ * @returns PaginatedResponse with pagination metadata
101
+ */
102
+ static paginated(data, total, page, limit, message = RESPONSE_MESSAGES.SUCCESS, statusCode = HTTP_STATUS.OK, requestId) {
103
+ const pages = Math.ceil(total / limit);
104
+ return {
105
+ success: true,
106
+ statusCode,
107
+ message,
108
+ data,
109
+ pagination: {
110
+ total,
111
+ page,
112
+ limit,
113
+ pages
114
+ },
115
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
116
+ requestId
117
+ };
118
+ }
119
+ /**
120
+ * Build a cursor-based paginated response for infinite-scroll / "load more" patterns
121
+ * @template T - Type of array items
122
+ * @param data - Array of items for the current page
123
+ * @param total - Total number of items available
124
+ * @param nextCursor - Cursor string for the next page
125
+ * @param hasNextPage - Whether more items exist after this page
126
+ * @param limit - Items per page
127
+ * @param message - Success message
128
+ * @param statusCode - HTTP status code
129
+ * @param requestId - Request tracking ID for correlation
130
+ * @returns CursorPaginatedResponse with cursor metadata
131
+ */
132
+ static cursorPaginated(data, total, nextCursor, hasNextPage, limit, previousCursor, hasPreviousPage, message = RESPONSE_MESSAGES.SUCCESS, statusCode = HTTP_STATUS.OK, requestId) {
133
+ return {
134
+ success: true,
135
+ statusCode,
136
+ message,
137
+ data,
138
+ pagination: {
139
+ total,
140
+ nextCursor,
141
+ previousCursor,
142
+ hasNextPage,
143
+ hasPreviousPage: hasPreviousPage ?? false,
144
+ limit
145
+ },
146
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
147
+ requestId
148
+ };
149
+ }
150
+ /**
151
+ * Build a created (201) response
152
+ * @template T - Type of response data
153
+ * @param data - Created resource data
154
+ * @param message - Success message
155
+ * @param requestId - Request tracking ID for correlation
156
+ * @returns ApiResponse with 201 status code
157
+ */
158
+ static created(data, message = RESPONSE_MESSAGES.CREATED, requestId) {
159
+ return this.success(data, message, HTTP_STATUS.CREATED, requestId);
160
+ }
161
+ /**
162
+ * Build an accepted (202) response for async operations
163
+ * @template T - Type of response data
164
+ * @param data - Response data (optional)
165
+ * @param message - Success message
166
+ * @param requestId - Request tracking ID for correlation
167
+ * @returns ApiResponse with 202 status code
168
+ */
169
+ static accepted(data, message = RESPONSE_MESSAGES.ACCEPTED, requestId) {
170
+ return this.success(data, message, HTTP_STATUS.ACCEPTED, requestId);
171
+ }
172
+ /**
173
+ * Build a no content (204) response
174
+ * @param message - Success message
175
+ * @param requestId - Request tracking ID for correlation
176
+ * @returns ApiResponse with 204 status code
177
+ */
178
+ static noContent(message = RESPONSE_MESSAGES.NO_CONTENT, requestId) {
179
+ return {
180
+ success: true,
181
+ statusCode: HTTP_STATUS.NO_CONTENT,
182
+ message,
183
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
184
+ requestId
185
+ };
186
+ }
187
+ /**
188
+ * Response for successful update operations
189
+ * @param data - Updated resource data
190
+ * @param message - Success message
191
+ * @param requestId - Request tracking ID
192
+ */
193
+ static updated(data, message = RESPONSE_MESSAGES.UPDATED, requestId) {
194
+ return this.success(data, message, HTTP_STATUS.OK, requestId);
195
+ }
196
+ /**
197
+ * Response for successful delete operations
198
+ * @param message - Success message
199
+ * @param requestId - Request tracking ID
200
+ */
201
+ static deleted(message = RESPONSE_MESSAGES.DELETED, requestId) {
202
+ return {
203
+ success: true,
204
+ statusCode: HTTP_STATUS.OK,
205
+ message,
206
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
207
+ requestId
208
+ };
209
+ }
210
+ /**
211
+ * Response for bulk operations (create, update, delete multiple)
212
+ * @param succeeded - Number of successful operations
213
+ * @param failed - Number of failed operations
214
+ * @param total - Total operations attempted
215
+ * @param requestId - Request tracking ID
216
+ */
217
+ static bulkOperation(succeeded, failed, total, requestId) {
218
+ const message = failed === 0 ? `All ${total} operations completed successfully` : `${succeeded} succeeded, ${failed} failed out of ${total} operations`;
219
+ return {
220
+ success: failed === 0,
221
+ statusCode: failed === 0 ? HTTP_STATUS.OK : HTTP_STATUS.MULTI_STATUS,
222
+ message,
223
+ data: {
224
+ succeeded,
225
+ failed,
226
+ total
227
+ },
228
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
229
+ requestId
230
+ };
231
+ }
232
+ /**
233
+ * Response for partial success scenarios
234
+ * @param data - Partial data that was processed
235
+ * @param message - Message describing the partial success
236
+ * @param requestId - Request tracking ID
237
+ */
238
+ static partialSuccess(data, message = RESPONSE_MESSAGES.PARTIAL_SUCCESS, requestId) {
239
+ return {
240
+ success: true,
241
+ statusCode: HTTP_STATUS.MULTI_STATUS,
242
+ message,
243
+ data,
244
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
245
+ requestId
246
+ };
247
+ }
248
+ /**
249
+ * Response for redirect operations
250
+ * @param url - Redirect URL
251
+ * @param statusCode - HTTP status code (301, 302, 307, 308)
252
+ * @param message - Redirect message
253
+ * @param requestId - Request tracking ID
254
+ */
255
+ static redirect(url, statusCode = HTTP_STATUS.FOUND, message = RESPONSE_MESSAGES.REDIRECTING, requestId) {
256
+ return {
257
+ success: true,
258
+ statusCode,
259
+ message,
260
+ data: { url },
261
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
262
+ requestId
263
+ };
264
+ }
265
+ /**
266
+ * Response for file download operations
267
+ * @param filename - Name of the file being downloaded
268
+ * @param size - File size in bytes
269
+ * @param mimeType - MIME type of the file
270
+ * @param requestId - Request tracking ID
271
+ */
272
+ static fileDownload(filename, size, mimeType, requestId) {
273
+ return {
274
+ success: true,
275
+ statusCode: HTTP_STATUS.OK,
276
+ message: RESPONSE_MESSAGES.FILE_READY,
277
+ data: {
278
+ filename,
279
+ size,
280
+ mimeType
281
+ },
282
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
283
+ requestId
284
+ };
285
+ }
286
+ /**
287
+ * Response for import/export operations
288
+ * @param processed - Number of records processed
289
+ * @param imported - Number of records imported
290
+ * @param skipped - Number of records skipped
291
+ * @param errors - Array of error messages
292
+ * @param requestId - Request tracking ID
293
+ */
294
+ static importExport(processed, imported, skipped, errors = [], requestId) {
295
+ const hasErrors = errors.length > 0;
296
+ const message = hasErrors ? `Imported ${imported} records with ${errors.length} errors` : `Successfully imported ${imported} records`;
297
+ return {
298
+ success: !hasErrors,
299
+ statusCode: hasErrors ? HTTP_STATUS.MULTI_STATUS : HTTP_STATUS.OK,
300
+ message,
301
+ data: {
302
+ processed,
303
+ imported,
304
+ skipped,
305
+ errors: hasErrors ? errors : void 0
306
+ },
307
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
308
+ requestId
309
+ };
310
+ }
311
+ };
312
+
313
+ exports.ResponseBuilder = ResponseBuilder;
314
+ //# sourceMappingURL=response.builder.cjs.map
315
+ //# sourceMappingURL=response.builder.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/response.constants.ts","../../src/builders/response.builder.ts"],"names":[],"mappings":"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","file":"response.builder.cjs","sourcesContent":["export const RESPONSE_FILTERS = {\n GLOBAL: 'global',\n VALIDATION: 'validation',\n HTTP: 'http',\n DATABASE: 'database',\n AUTH: 'auth',\n} as const;\n\nexport const HTTP_STATUS = {\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n MULTI_STATUS: 207,\n FOUND: 302,\n BAD_REQUEST: 400,\n} as const;\n\nexport const RESPONSE_MESSAGES = {\n SUCCESS: 'Success',\n CREATED: 'Created successfully',\n ACCEPTED: 'Request accepted',\n NO_CONTENT: 'No content',\n UPDATED: 'Updated successfully',\n DELETED: 'Deleted successfully',\n PARTIAL_SUCCESS: 'Partially successful',\n REDIRECTING: 'Redirecting',\n FILE_READY: 'File ready for download',\n} as const;\n","import { ApiResponse, PaginatedResponse, CursorPaginatedResponse } from '../types';\nimport { HTTP_STATUS, RESPONSE_MESSAGES } from '../response.constants';\nimport { responseContext } from '../response.context';\n\nexport class ResponseBuilder {\n /**\n * Build a success response\n * @template T - Type of response data\n * @param data - Response data\n * @param message - Success message\n * @param statusCode - HTTP status code\n * @param requestId - Request tracking ID for correlation\n * @returns ApiResponse with success data\n */\n static success<T = any>(\n data: T,\n message: string = RESPONSE_MESSAGES.SUCCESS,\n statusCode: number = HTTP_STATUS.OK,\n requestId?: string\n ): ApiResponse<T> {\n return {\n success: true,\n statusCode,\n message,\n data,\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Shorthand success response with no data payload (e.g. status-only endpoints)\n * @param message - Success message\n * @param statusCode - HTTP status code\n * @param requestId - Request tracking ID for correlation\n * @returns ApiResponse with no data field\n */\n static ok(\n message: string = RESPONSE_MESSAGES.SUCCESS,\n statusCode: number = HTTP_STATUS.OK,\n requestId?: string\n ): ApiResponse {\n return {\n success: true,\n statusCode,\n message,\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Build an error response\n * @param message - Error message\n * @param code - Error code for categorization\n * @param statusCode - HTTP status code\n * @param details - Additional error details\n * @param requestId - Request tracking ID for correlation\n * @returns ApiResponse with error information\n */\n static error(\n message: string,\n code: string,\n statusCode: number = HTTP_STATUS.BAD_REQUEST,\n details?: string,\n requestId?: string\n ): ApiResponse {\n return {\n success: false,\n statusCode,\n message,\n error: {\n code,\n details,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Build a paginated response\n * @template T - Type of array items\n * @param data - Array of items\n * @param total - Total number of items available\n * @param page - Current page number\n * @param limit - Items per page\n * @param message - Success message\n * @param statusCode - HTTP status code\n * @param requestId - Request tracking ID for correlation\n * @returns PaginatedResponse with pagination metadata\n */\n static paginated<T = any>(\n data: T[],\n total: number,\n page: number,\n limit: number,\n message: string = RESPONSE_MESSAGES.SUCCESS,\n statusCode: number = HTTP_STATUS.OK,\n requestId?: string\n ): PaginatedResponse<T> {\n const pages = Math.ceil(total / limit);\n return {\n success: true,\n statusCode,\n message,\n data,\n pagination: {\n total,\n page,\n limit,\n pages,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Build a cursor-based paginated response for infinite-scroll / \"load more\" patterns\n * @template T - Type of array items\n * @param data - Array of items for the current page\n * @param total - Total number of items available\n * @param nextCursor - Cursor string for the next page\n * @param hasNextPage - Whether more items exist after this page\n * @param limit - Items per page\n * @param message - Success message\n * @param statusCode - HTTP status code\n * @param requestId - Request tracking ID for correlation\n * @returns CursorPaginatedResponse with cursor metadata\n */\n static cursorPaginated<T = any>(\n data: T[],\n total: number,\n nextCursor: string | undefined,\n hasNextPage: boolean,\n limit: number,\n previousCursor?: string,\n hasPreviousPage?: boolean,\n message: string = RESPONSE_MESSAGES.SUCCESS,\n statusCode: number = HTTP_STATUS.OK,\n requestId?: string\n ): CursorPaginatedResponse<T> {\n return {\n success: true,\n statusCode,\n message,\n data,\n pagination: {\n total,\n nextCursor,\n previousCursor,\n hasNextPage,\n hasPreviousPage: hasPreviousPage ?? false,\n limit,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Build a created (201) response\n * @template T - Type of response data\n * @param data - Created resource data\n * @param message - Success message\n * @param requestId - Request tracking ID for correlation\n * @returns ApiResponse with 201 status code\n */\n static created<T = any>(\n data: T,\n message: string = RESPONSE_MESSAGES.CREATED,\n requestId?: string\n ): ApiResponse<T> {\n return this.success(data, message, HTTP_STATUS.CREATED, requestId);\n }\n\n /**\n * Build an accepted (202) response for async operations\n * @template T - Type of response data\n * @param data - Response data (optional)\n * @param message - Success message\n * @param requestId - Request tracking ID for correlation\n * @returns ApiResponse with 202 status code\n */\n static accepted<T = any>(\n data: T,\n message: string = RESPONSE_MESSAGES.ACCEPTED,\n requestId?: string\n ): ApiResponse<T> {\n return this.success(data, message, HTTP_STATUS.ACCEPTED, requestId);\n }\n\n /**\n * Build a no content (204) response\n * @param message - Success message\n * @param requestId - Request tracking ID for correlation\n * @returns ApiResponse with 204 status code\n */\n static noContent(\n message: string = RESPONSE_MESSAGES.NO_CONTENT,\n requestId?: string\n ): ApiResponse {\n return {\n success: true,\n statusCode: HTTP_STATUS.NO_CONTENT,\n message,\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Response for successful update operations\n * @param data - Updated resource data\n * @param message - Success message\n * @param requestId - Request tracking ID\n */\n static updated<T = any>(\n data: T,\n message: string = RESPONSE_MESSAGES.UPDATED,\n requestId?: string\n ): ApiResponse<T> {\n return this.success(data, message, HTTP_STATUS.OK, requestId);\n }\n\n /**\n * Response for successful delete operations\n * @param message - Success message\n * @param requestId - Request tracking ID\n */\n static deleted(\n message: string = RESPONSE_MESSAGES.DELETED,\n requestId?: string\n ): ApiResponse {\n return {\n success: true,\n statusCode: HTTP_STATUS.OK,\n message,\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Response for bulk operations (create, update, delete multiple)\n * @param succeeded - Number of successful operations\n * @param failed - Number of failed operations\n * @param total - Total operations attempted\n * @param requestId - Request tracking ID\n */\n static bulkOperation(\n succeeded: number,\n failed: number,\n total: number,\n requestId?: string\n ): ApiResponse {\n const message = failed === 0\n ? `All ${total} operations completed successfully`\n : `${succeeded} succeeded, ${failed} failed out of ${total} operations`;\n\n return {\n success: failed === 0,\n statusCode: failed === 0 ? HTTP_STATUS.OK : HTTP_STATUS.MULTI_STATUS,\n message,\n data: {\n succeeded,\n failed,\n total,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Response for partial success scenarios\n * @param data - Partial data that was processed\n * @param message - Message describing the partial success\n * @param requestId - Request tracking ID\n */\n static partialSuccess<T = any>(\n data: T,\n message: string = RESPONSE_MESSAGES.PARTIAL_SUCCESS,\n requestId?: string\n ): ApiResponse<T> {\n return {\n success: true,\n statusCode: HTTP_STATUS.MULTI_STATUS,\n message,\n data,\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Response for redirect operations\n * @param url - Redirect URL\n * @param statusCode - HTTP status code (301, 302, 307, 308)\n * @param message - Redirect message\n * @param requestId - Request tracking ID\n */\n static redirect(\n url: string,\n statusCode: number = HTTP_STATUS.FOUND,\n message: string = RESPONSE_MESSAGES.REDIRECTING,\n requestId?: string\n ): ApiResponse {\n return {\n success: true,\n statusCode,\n message,\n data: { url },\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Response for file download operations\n * @param filename - Name of the file being downloaded\n * @param size - File size in bytes\n * @param mimeType - MIME type of the file\n * @param requestId - Request tracking ID\n */\n static fileDownload(\n filename: string,\n size: number,\n mimeType: string,\n requestId?: string\n ): ApiResponse {\n return {\n success: true,\n statusCode: HTTP_STATUS.OK,\n message: RESPONSE_MESSAGES.FILE_READY,\n data: {\n filename,\n size,\n mimeType,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n\n /**\n * Response for import/export operations\n * @param processed - Number of records processed\n * @param imported - Number of records imported\n * @param skipped - Number of records skipped\n * @param errors - Array of error messages\n * @param requestId - Request tracking ID\n */\n static importExport(\n processed: number,\n imported: number,\n skipped: number,\n errors: string[] = [],\n requestId?: string\n ): ApiResponse {\n const hasErrors = errors.length > 0;\n const message = hasErrors\n ? `Imported ${imported} records with ${errors.length} errors`\n : `Successfully imported ${imported} records`;\n\n return {\n success: !hasErrors,\n statusCode: hasErrors ? HTTP_STATUS.MULTI_STATUS : HTTP_STATUS.OK,\n message,\n data: {\n processed,\n imported,\n skipped,\n errors: hasErrors ? errors : undefined,\n },\n timestamp: new Date().toISOString(),\n requestId,\n };\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export { R as ResponseBuilder } from '../response.builder-BX9d7Taz.cjs';
@@ -0,0 +1 @@
1
+ export { R as ResponseBuilder } from '../response.builder-BX9d7Taz.js';