npm package: @heavybit/response-utils-ts
Description: A comprehensive TypeScript response utilities package for Express.js with API response builders, error classes, and error handling middleware
Author: Nicholas Kute
Latest version: 2.0.0

# @pesalink/response-utils-ts

A comprehensive TypeScript response utilities package for Express.js with API response builders, error classes, and error handling middleware.

## Features

- 🎯 **Type-Safe API Responses** - Standardized success and error response builders with full TypeScript support
- 🚨 **Custom Error Classes** - Pre-built error classes for common HTTP error scenarios
- 🛡️ **Error Handling Middleware** - Centralized error handling for Express applications
- 📧 **Message Templates** - Pre-defined error and success messages with dynamic builders
- 📄 **Pagination Support** - Built-in pagination utilities for list responses
- ✅ **Validation Middleware** - Joi-compatible validation middleware factory

## Installation

```bash
npm install @pesalink/response-utils-ts
```

## Quick Start

```typescript
import express from 'express';
import {
  apiResponseBuilder,
  errorHandler,
  ResourceNotFoundError,
  SUCCESS_MESSAGES,
  RESPONSE_CODES,
} from '@pesalink/response-utils-ts';

const app = express();
app.use(express.json());

// Success response
app.get('/api/users', async (req, res) => {
  const users = await getUsersFromDB();
  
  const response = apiResponseBuilder.buildSuccessResponse(
    RESPONSE_CODES.SUCCESSFUL_RESPONSE,
    SUCCESS_MESSAGES.FETCH_SUCCESS,
    users
  );
  
  res.json(response);
});

// Error handling
app.get('/api/users/:id', async (req, res, next) => {
  try {
    const user = await findUserById(req.params.id);
    
    if (!user) {
      throw new ResourceNotFoundError('User not found');
    }
    
    res.json(apiResponseBuilder.buildSuccessResponse(200, 'Success', user));
  } catch (error) {
    next(error);
  }
});

// Error handling middleware
app.use(errorHandler.createErrorMiddleware());

app.listen(3000);
```

## API Reference

### Response Builder

```typescript
import { apiResponseBuilder } from '@pesalink/response-utils-ts';

// Success response
const response = apiResponseBuilder.buildSuccessResponse(200, 'Success', data);

// Error response
const errorResponse = apiResponseBuilder.buildErrorResponse(400, 'Bad Request', { field: 'error' });

// Paginated response
const paginated = apiResponseBuilder.createPaginatedResponse(rows, totalCount, pageSize, currentPage);

const paginatedResponse = apiResponseBuilder.buildSuccessResponseWithPagination(
  200,
  'Data retrieved',
  paginated.data,
  paginated.pagination
);
```

### Error Classes

```typescript
import {
  ResourceNotFoundError,
  ValidationError,
  AuthenticationError,
  AuthorizationError,
  BadRequestError,
  ConflictError,
  InternalServerError,
  ServiceUnavailableError,
  TimeoutError,
  ForbiddenError,
  RateLimitExceededError,
  UnprocessableEntityError,
  DatabaseError,
} from '@pesalink/response-utils-ts';

// Throw errors in your code
throw new ResourceNotFoundError('User not found');
throw new ValidationError('Validation failed', { email: 'Invalid email' });
throw new AuthenticationError('Invalid credentials');
```

### Error Handler

```typescript
import { errorHandler } from '@pesalink/response-utils-ts';

// Use individual handlers
app.use(errorHandler.handleValidationError.bind(errorHandler));
app.use(errorHandler.handleResourceNotFoundError.bind(errorHandler));
app.use(errorHandler.handleError.bind(errorHandler));

// Or use combined middleware
app.use(errorHandler.createErrorMiddleware());
```

### Validation Middleware

```typescript
import { validationErrorCheck } from '@pesalink/response-utils-ts';
import Joi from 'joi';

const schema = Joi.object({
  name: Joi.string().required(),
  email: Joi.string().email().required(),
});

app.post('/api/users', validationErrorCheck(schema, 'body'), createUserHandler);
```

### Message Constants

```typescript
import { ERROR_MESSAGES, SUCCESS_MESSAGES, RESPONSE_CODES } from '@pesalink/response-utils-ts';

// Static messages
console.log(ERROR_MESSAGES.UNAUTHORIZED); // 'Unauthorized'
console.log(SUCCESS_MESSAGES.LOGIN_SUCCESS); // 'Login successful.'

// Dynamic messages
console.log(ERROR_MESSAGES.NOT_FOUND('User', 123)); // 'User with ID 123 not found.'
console.log(SUCCESS_MESSAGES.CREATE_SUCCESS('User')); // 'User created successfully.'

// Response codes
console.log(RESPONSE_CODES.SUCCESSFUL_RESPONSE); // 200
console.log(RESPONSE_CODES.NOT_FOUND); // 404
```

### Email Templates

```typescript
import { EMAIL_MESSAGES, EMAIL_SUBJECTS, SMS_MESSAGES } from '@pesalink/response-utils-ts';

// Email subjects
const subject = EMAIL_SUBJECTS.ITEM_CREATED_REQUEST('Transaction', 'Banking Portal');

// Email messages
const body = EMAIL_MESSAGES.EMAIL_OPERATION_REQUEST(
  'Transaction',
  'ID',
  'TXN-12345',
  'created',
  'Banking Portal',
  'John Doe'
);

// SMS messages
const sms = SMS_MESSAGES.BOND_CREATED_SMS('bond', 'Portal', 'review');
```

## Response Format

### Success Response

```json
{
  "timestamp": "2024-01-15T10:30:00.000Z",
  "status": 200,
  "statusCode": 200,
  "message": "Data fetched successfully.",
  "data": { ... }
}
```

### Error Response

```json
{
  "timestamp": "2024-01-15T10:30:00.000Z",
  "status": 400,
  "statusCode": 400,
  "message": "Validation error",
  "errors": {
    "email": "Invalid email format"
  }
}
```

### Paginated Response

```json
{
  "timestamp": "2024-01-15T10:30:00.000Z",
  "status": 200,
  "statusCode": 200,
  "message": "Data retrieved successfully.",
  "data": [ ... ],
  "pagination": {
    "currentPage": 1,
    "totalPages": 10,
    "pageSize": 20,
    "totalItems": 200,
    "from": 1,
    "to": 20
  }
}
```

## Types

```typescript
import type {
  ApiResponse,
  ApiResponseWithPagination,
  PaginationInfo,
  PaginatedResult,
  ValidationSchema,
  ExtendedError,
  AuthenticatedRequest,
} from '@pesalink/response-utils-ts';
```

## Dependencies

- `@heavybit/logger-ts` (optional) - For logging in error handler

## License

MIT