@naman_deep_singh/server-utils 1.4.2 → 1.4.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @naman_deep_singh/server-utils
2
2
 
3
- **Version:** 1.4.2 (with integrated cache & session support)
3
+ **Version:** 1.4.4 (with integrated cache & session support)
4
4
 
5
5
  Extensible server utilities for Express.js microservices with multi-protocol support, integrated caching, session management, and TypeScript.
6
6
 
@@ -5,7 +5,7 @@ exports.withHealthCheck = withHealthCheck;
5
5
  exports.addHealthCheck = addHealthCheck;
6
6
  function createHealthCheck(config = {}) {
7
7
  const { customChecks = [] } = config;
8
- return async (req, res) => {
8
+ return async (_req, res) => {
9
9
  try {
10
10
  const checks = {
11
11
  server: true,
@@ -16,7 +16,7 @@ function createHealthCheck(config = {}) {
16
16
  try {
17
17
  checks[check.name] = await check.check();
18
18
  }
19
- catch (error) {
19
+ catch (_error) {
20
20
  checks[check.name] = false;
21
21
  }
22
22
  }
@@ -26,7 +26,7 @@ function createHealthCheck(config = {}) {
26
26
  checks,
27
27
  });
28
28
  }
29
- catch (error) {
29
+ catch (_error) {
30
30
  res.status(503).json({
31
31
  status: 'unhealthy',
32
32
  error: 'Health check failed',
@@ -1,4 +1,4 @@
1
- import { ICache, SessionStore } from '@naman_deep_singh/cache';
1
+ import { type ICache, SessionStore } from '@naman_deep_singh/cache';
2
2
  import type { Server } from 'http';
3
3
  import type { Application } from 'express';
4
4
  import type { ServerConfig, SocketIOConfig } from '../types';
@@ -84,7 +84,7 @@ class ExpressServer {
84
84
  const corsOptions = typeof this.config.cors === 'object' ? this.config.cors : undefined;
85
85
  this.app.use(cors(corsOptions));
86
86
  }
87
- catch (error) {
87
+ catch (_error) {
88
88
  console.warn(`${this.config.name}: CORS middleware not available. Install cors package.`);
89
89
  }
90
90
  }
@@ -94,7 +94,7 @@ class ExpressServer {
94
94
  const helmet = require('helmet');
95
95
  this.app.use(helmet());
96
96
  }
97
- catch (error) {
97
+ catch (_error) {
98
98
  console.warn(`${this.config.name}: Helmet middleware not available. Install helmet package.`);
99
99
  }
100
100
  }
@@ -108,7 +108,7 @@ class ExpressServer {
108
108
  const cookieParser = require('cookie-parser');
109
109
  this.app.use(cookieParser());
110
110
  }
111
- catch (error) {
111
+ catch (_error) {
112
112
  console.warn(`${this.config.name}: Cookie parser middleware not available. Install cookie-parser package.`);
113
113
  }
114
114
  }
@@ -266,7 +266,7 @@ class ExpressServer {
266
266
  await store.close();
267
267
  }
268
268
  }
269
- catch (e) {
269
+ catch (_e) {
270
270
  // SessionStore may not have close; ignore
271
271
  }
272
272
  },
@@ -338,7 +338,7 @@ class ExpressServer {
338
338
  console.log(`🔗 ${this.config.name} gRPC server running on port ${port}`);
339
339
  });
340
340
  }
341
- catch (error) {
341
+ catch (_error) {
342
342
  console.warn(`${this.config.name}: gRPC not available. Install @grpc/grpc-js to use gRPC features.`);
343
343
  }
344
344
  }
@@ -351,7 +351,7 @@ class ExpressServer {
351
351
  this.app.use(path, rpcServer.middleware());
352
352
  console.log(`📡 ${this.config.name} JSON-RPC server mounted on ${path}`);
353
353
  }
354
- catch (error) {
354
+ catch (_error) {
355
355
  console.warn(`${this.config.name}: JSON-RPC not available. Install jayson to use RPC features.`);
356
356
  }
357
357
  }
@@ -425,7 +425,7 @@ class ExpressServer {
425
425
  console.log(`🔌 ${this.config.name} Socket.IO server attached${config.path ? ` at ${config.path}` : ''}${config.cors ? ' (CORS enabled)' : ''}`);
426
426
  return io;
427
427
  }
428
- catch (error) {
428
+ catch (_error) {
429
429
  console.warn(`${this.config.name}: Socket.IO not available. Install socket.io to use WebSocket features.`);
430
430
  return null;
431
431
  }
@@ -34,7 +34,7 @@ function createGracefulShutdown(server, config = {}) {
34
34
  process.on('SIGTERM', () => shutdown('SIGTERM'));
35
35
  }
36
36
  function withGracefulShutdown(config = {}) {
37
- return (app, serverConfig) => {
37
+ return (app, _serverConfig) => {
38
38
  // This plugin needs to be applied after server.listen()
39
39
  // Store config for later use
40
40
  ;
@@ -1,7 +1,6 @@
1
- import type { Request, RequestHandler } from 'node_modules/@types/express';
1
+ import type { Request, RequestHandler } from 'express';
2
2
  export interface AuthConfig {
3
3
  secret: string;
4
- unauthorizedMessage?: string;
5
4
  tokenExtractor?: (req: Request) => string | null;
6
5
  }
7
6
  export declare function createAuthMiddleware(config: AuthConfig): RequestHandler;
@@ -4,38 +4,41 @@ exports.createAuthMiddleware = createAuthMiddleware;
4
4
  const errors_utils_1 = require("@naman_deep_singh/errors-utils");
5
5
  const security_1 = require("@naman_deep_singh/security");
6
6
  function createAuthMiddleware(config) {
7
- const { secret, unauthorizedMessage = 'Unauthorized access', tokenExtractor = (req) => (0, security_1.extractToken)({
7
+ const { secret, tokenExtractor = (req) => (0, security_1.extractToken)({
8
8
  header: req.headers.authorization || undefined,
9
9
  cookies: req.cookies,
10
10
  query: req.query,
11
11
  body: req.body,
12
12
  }), } = config;
13
- return async (req, res, next) => {
13
+ return async (req, _res, next) => {
14
14
  try {
15
- // Extract token from request
15
+ // 1️⃣ Extract token
16
16
  const token = tokenExtractor(req);
17
17
  if (!token) {
18
- const error = new errors_utils_1.UnauthorizedError(unauthorizedMessage, {
18
+ // No cause client mistake
19
+ return next(new errors_utils_1.TokenMalformedError({
19
20
  reason: 'No token provided',
20
- });
21
- return next(error);
21
+ }));
22
22
  }
23
- // Use safe verify token from security package
23
+ // 2️⃣ Verify token
24
24
  const result = (0, security_1.safeVerifyToken)(token, secret);
25
25
  if (!result.valid) {
26
- const error = new errors_utils_1.UnauthorizedError(unauthorizedMessage, {
27
- reason: 'Invalid or expired token',
28
- originalError: result.error?.message,
29
- });
30
- return next(error);
26
+ // Token expired
27
+ if (result.error?.name === 'TokenExpiredError') {
28
+ return next(new errors_utils_1.TokenExpiredError({ reason: 'Token expired' }, result.error));
29
+ }
30
+ // Token invalid / malformed
31
+ return next(new errors_utils_1.TokenMalformedError({
32
+ reason: 'Invalid token',
33
+ }, result.error));
31
34
  }
32
- // Attach the verified payload as user
35
+ // 3️⃣ Attach payload
33
36
  req.user = result.payload;
34
37
  next();
35
38
  }
36
39
  catch (error) {
37
- const unauthorizedError = new errors_utils_1.UnauthorizedError(unauthorizedMessage, error instanceof Error ? { originalError: error.message } : error);
38
- return next(unauthorizedError);
40
+ // Unexpected error always pass cause
41
+ return next(new errors_utils_1.UnauthorizedError({ reason: 'Authentication failed' }, error instanceof Error ? error : undefined));
39
42
  }
40
43
  };
41
44
  }
@@ -1,2 +1,2 @@
1
- import type { ErrorRequestHandler } from 'node_modules/@types/express';
1
+ import type { ErrorRequestHandler } from 'express';
2
2
  export declare function createErrorHandler(): ErrorRequestHandler;
@@ -1,29 +1,44 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createErrorHandler = createErrorHandler;
4
- // Error handling middleware
4
+ const errors_utils_1 = require("@naman_deep_singh/errors-utils");
5
5
  function createErrorHandler() {
6
- return (err, req, res, next) => {
7
- console.error('Error:', err);
6
+ return (err, _req, res, next) => {
8
7
  if (res.headersSent) {
9
8
  return next(err);
10
9
  }
11
- // Type guard for error objects
12
- const errorObj = err;
13
- const status = errorObj.status || errorObj.statusCode || 500;
14
- const message = process.env.NODE_ENV === 'production'
15
- ? 'Internal Server Error'
16
- : errorObj.message || 'Unknown error';
17
- res.status(status).json({
10
+ // Use responder if available
11
+ const responder = res.responder?.() ?? null;
12
+ // Known application error
13
+ if (err instanceof errors_utils_1.AppError) {
14
+ if (responder) {
15
+ return responder.status(err.statusCode).error(err.code, err.details);
16
+ }
17
+ // Fallback (if responder middleware is not mounted)
18
+ return res.status(err.statusCode).json({
19
+ success: false,
20
+ message: err.code,
21
+ error: {
22
+ message: err.code,
23
+ details: err.details,
24
+ },
25
+ data: undefined,
26
+ meta: null,
27
+ });
28
+ }
29
+ // Unknown / unhandled error
30
+ console.error('Unhandled error:', err);
31
+ const status = 500;
32
+ const message = 'Internal Server Error';
33
+ if (responder) {
34
+ return responder.status(status).error(message);
35
+ }
36
+ // Final fallback
37
+ return res.status(status).json({
18
38
  success: false,
19
39
  message,
40
+ error: { message },
20
41
  data: undefined,
21
- error: {
22
- message,
23
- ...(process.env.NODE_ENV !== 'production' && {
24
- details: { stack: errorObj.stack },
25
- }),
26
- },
27
42
  meta: null,
28
43
  });
29
44
  };
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useSession = useSession;
4
4
  // Session middleware helper (attaches sessionStore and helpers to req)
5
5
  function useSession(cookieName) {
6
- return async (req, res, next) => {
6
+ return async (req, _res, next) => {
7
7
  try {
8
8
  const store = req.app.locals.sessionStore;
9
9
  if (!store)
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createValidationMiddleware = createValidationMiddleware;
4
4
  const errors_utils_1 = require("@naman_deep_singh/errors-utils");
5
5
  function createValidationMiddleware(rules) {
6
- return (req, res, next) => {
6
+ return (req, _res, next) => {
7
7
  const errors = [];
8
8
  for (const rule of rules) {
9
9
  const value = req.body[rule.field];
@@ -57,8 +57,8 @@ function createValidationMiddleware(rules) {
57
57
  }
58
58
  if (errors.length > 0) {
59
59
  // Use ValidationError from errors-utils and let error middleware handle response
60
- const validationError = new errors_utils_1.ValidationError('Validation failed', {
61
- validationErrors: errors,
60
+ const validationError = new errors_utils_1.ValidationError({
61
+ fieldErrors: errors,
62
62
  });
63
63
  return next(validationError);
64
64
  }
@@ -1,6 +1,6 @@
1
1
  export function createHealthCheck(config = {}) {
2
2
  const { customChecks = [] } = config;
3
- return async (req, res) => {
3
+ return async (_req, res) => {
4
4
  try {
5
5
  const checks = {
6
6
  server: true,
@@ -11,7 +11,7 @@ export function createHealthCheck(config = {}) {
11
11
  try {
12
12
  checks[check.name] = await check.check();
13
13
  }
14
- catch (error) {
14
+ catch (_error) {
15
15
  checks[check.name] = false;
16
16
  }
17
17
  }
@@ -21,7 +21,7 @@ export function createHealthCheck(config = {}) {
21
21
  checks,
22
22
  });
23
23
  }
24
- catch (error) {
24
+ catch (_error) {
25
25
  res.status(503).json({
26
26
  status: 'unhealthy',
27
27
  error: 'Health check failed',
@@ -1,4 +1,4 @@
1
- import { ICache, SessionStore } from '@naman_deep_singh/cache';
1
+ import { type ICache, SessionStore } from '@naman_deep_singh/cache';
2
2
  import type { Server } from 'http';
3
3
  import type { Application } from 'express';
4
4
  import type { ServerConfig, SocketIOConfig } from '../types';
@@ -1,5 +1,5 @@
1
1
  import crypto from 'crypto';
2
- import { CacheFactory, SessionStore } from '@naman_deep_singh/cache';
2
+ import { CacheFactory, SessionStore, } from '@naman_deep_singh/cache';
3
3
  import express, { json, raw } from 'express';
4
4
  import { PeriodicHealthMonitor } from './periodic-health';
5
5
  import { createGracefulShutdown } from './shutdown';
@@ -44,7 +44,7 @@ export class ExpressServer {
44
44
  const corsOptions = typeof this.config.cors === 'object' ? this.config.cors : undefined;
45
45
  this.app.use(cors(corsOptions));
46
46
  }
47
- catch (error) {
47
+ catch (_error) {
48
48
  console.warn(`${this.config.name}: CORS middleware not available. Install cors package.`);
49
49
  }
50
50
  }
@@ -54,7 +54,7 @@ export class ExpressServer {
54
54
  const helmet = require('helmet');
55
55
  this.app.use(helmet());
56
56
  }
57
- catch (error) {
57
+ catch (_error) {
58
58
  console.warn(`${this.config.name}: Helmet middleware not available. Install helmet package.`);
59
59
  }
60
60
  }
@@ -68,7 +68,7 @@ export class ExpressServer {
68
68
  const cookieParser = require('cookie-parser');
69
69
  this.app.use(cookieParser());
70
70
  }
71
- catch (error) {
71
+ catch (_error) {
72
72
  console.warn(`${this.config.name}: Cookie parser middleware not available. Install cookie-parser package.`);
73
73
  }
74
74
  }
@@ -226,7 +226,7 @@ export class ExpressServer {
226
226
  await store.close();
227
227
  }
228
228
  }
229
- catch (e) {
229
+ catch (_e) {
230
230
  // SessionStore may not have close; ignore
231
231
  }
232
232
  },
@@ -298,7 +298,7 @@ export class ExpressServer {
298
298
  console.log(`🔗 ${this.config.name} gRPC server running on port ${port}`);
299
299
  });
300
300
  }
301
- catch (error) {
301
+ catch (_error) {
302
302
  console.warn(`${this.config.name}: gRPC not available. Install @grpc/grpc-js to use gRPC features.`);
303
303
  }
304
304
  }
@@ -311,7 +311,7 @@ export class ExpressServer {
311
311
  this.app.use(path, rpcServer.middleware());
312
312
  console.log(`📡 ${this.config.name} JSON-RPC server mounted on ${path}`);
313
313
  }
314
- catch (error) {
314
+ catch (_error) {
315
315
  console.warn(`${this.config.name}: JSON-RPC not available. Install jayson to use RPC features.`);
316
316
  }
317
317
  }
@@ -385,7 +385,7 @@ export class ExpressServer {
385
385
  console.log(`🔌 ${this.config.name} Socket.IO server attached${config.path ? ` at ${config.path}` : ''}${config.cors ? ' (CORS enabled)' : ''}`);
386
386
  return io;
387
387
  }
388
- catch (error) {
388
+ catch (_error) {
389
389
  console.warn(`${this.config.name}: Socket.IO not available. Install socket.io to use WebSocket features.`);
390
390
  return null;
391
391
  }
@@ -29,7 +29,7 @@ export function createGracefulShutdown(server, config = {}) {
29
29
  process.on('SIGTERM', () => shutdown('SIGTERM'));
30
30
  }
31
31
  export function withGracefulShutdown(config = {}) {
32
- return (app, serverConfig) => {
32
+ return (app, _serverConfig) => {
33
33
  // This plugin needs to be applied after server.listen()
34
34
  // Store config for later use
35
35
  ;
@@ -1,7 +1,6 @@
1
- import type { Request, RequestHandler } from 'node_modules/@types/express';
1
+ import type { Request, RequestHandler } from 'express';
2
2
  export interface AuthConfig {
3
3
  secret: string;
4
- unauthorizedMessage?: string;
5
4
  tokenExtractor?: (req: Request) => string | null;
6
5
  }
7
6
  export declare function createAuthMiddleware(config: AuthConfig): RequestHandler;
@@ -1,38 +1,41 @@
1
- import { UnauthorizedError } from '@naman_deep_singh/errors-utils';
1
+ import { TokenExpiredError, TokenMalformedError, UnauthorizedError, } from '@naman_deep_singh/errors-utils';
2
2
  import { extractToken, safeVerifyToken } from '@naman_deep_singh/security';
3
3
  export function createAuthMiddleware(config) {
4
- const { secret, unauthorizedMessage = 'Unauthorized access', tokenExtractor = (req) => extractToken({
4
+ const { secret, tokenExtractor = (req) => extractToken({
5
5
  header: req.headers.authorization || undefined,
6
6
  cookies: req.cookies,
7
7
  query: req.query,
8
8
  body: req.body,
9
9
  }), } = config;
10
- return async (req, res, next) => {
10
+ return async (req, _res, next) => {
11
11
  try {
12
- // Extract token from request
12
+ // 1️⃣ Extract token
13
13
  const token = tokenExtractor(req);
14
14
  if (!token) {
15
- const error = new UnauthorizedError(unauthorizedMessage, {
15
+ // No cause client mistake
16
+ return next(new TokenMalformedError({
16
17
  reason: 'No token provided',
17
- });
18
- return next(error);
18
+ }));
19
19
  }
20
- // Use safe verify token from security package
20
+ // 2️⃣ Verify token
21
21
  const result = safeVerifyToken(token, secret);
22
22
  if (!result.valid) {
23
- const error = new UnauthorizedError(unauthorizedMessage, {
24
- reason: 'Invalid or expired token',
25
- originalError: result.error?.message,
26
- });
27
- return next(error);
23
+ // Token expired
24
+ if (result.error?.name === 'TokenExpiredError') {
25
+ return next(new TokenExpiredError({ reason: 'Token expired' }, result.error));
26
+ }
27
+ // Token invalid / malformed
28
+ return next(new TokenMalformedError({
29
+ reason: 'Invalid token',
30
+ }, result.error));
28
31
  }
29
- // Attach the verified payload as user
32
+ // 3️⃣ Attach payload
30
33
  req.user = result.payload;
31
34
  next();
32
35
  }
33
36
  catch (error) {
34
- const unauthorizedError = new UnauthorizedError(unauthorizedMessage, error instanceof Error ? { originalError: error.message } : error);
35
- return next(unauthorizedError);
37
+ // Unexpected error always pass cause
38
+ return next(new UnauthorizedError({ reason: 'Authentication failed' }, error instanceof Error ? error : undefined));
36
39
  }
37
40
  };
38
41
  }
@@ -1,2 +1,2 @@
1
- import type { ErrorRequestHandler } from 'node_modules/@types/express';
1
+ import type { ErrorRequestHandler } from 'express';
2
2
  export declare function createErrorHandler(): ErrorRequestHandler;
@@ -1,26 +1,41 @@
1
- // Error handling middleware
1
+ import { AppError } from '@naman_deep_singh/errors-utils';
2
2
  export function createErrorHandler() {
3
- return (err, req, res, next) => {
4
- console.error('Error:', err);
3
+ return (err, _req, res, next) => {
5
4
  if (res.headersSent) {
6
5
  return next(err);
7
6
  }
8
- // Type guard for error objects
9
- const errorObj = err;
10
- const status = errorObj.status || errorObj.statusCode || 500;
11
- const message = process.env.NODE_ENV === 'production'
12
- ? 'Internal Server Error'
13
- : errorObj.message || 'Unknown error';
14
- res.status(status).json({
7
+ // Use responder if available
8
+ const responder = res.responder?.() ?? null;
9
+ // Known application error
10
+ if (err instanceof AppError) {
11
+ if (responder) {
12
+ return responder.status(err.statusCode).error(err.code, err.details);
13
+ }
14
+ // Fallback (if responder middleware is not mounted)
15
+ return res.status(err.statusCode).json({
16
+ success: false,
17
+ message: err.code,
18
+ error: {
19
+ message: err.code,
20
+ details: err.details,
21
+ },
22
+ data: undefined,
23
+ meta: null,
24
+ });
25
+ }
26
+ // Unknown / unhandled error
27
+ console.error('Unhandled error:', err);
28
+ const status = 500;
29
+ const message = 'Internal Server Error';
30
+ if (responder) {
31
+ return responder.status(status).error(message);
32
+ }
33
+ // Final fallback
34
+ return res.status(status).json({
15
35
  success: false,
16
36
  message,
37
+ error: { message },
17
38
  data: undefined,
18
- error: {
19
- message,
20
- ...(process.env.NODE_ENV !== 'production' && {
21
- details: { stack: errorObj.stack },
22
- }),
23
- },
24
39
  meta: null,
25
40
  });
26
41
  };
@@ -1,6 +1,6 @@
1
1
  // Session middleware helper (attaches sessionStore and helpers to req)
2
2
  export function useSession(cookieName) {
3
- return async (req, res, next) => {
3
+ return async (req, _res, next) => {
4
4
  try {
5
5
  const store = req.app.locals.sessionStore;
6
6
  if (!store)
@@ -1,6 +1,6 @@
1
1
  import { ValidationError } from '@naman_deep_singh/errors-utils';
2
2
  export function createValidationMiddleware(rules) {
3
- return (req, res, next) => {
3
+ return (req, _res, next) => {
4
4
  const errors = [];
5
5
  for (const rule of rules) {
6
6
  const value = req.body[rule.field];
@@ -54,8 +54,8 @@ export function createValidationMiddleware(rules) {
54
54
  }
55
55
  if (errors.length > 0) {
56
56
  // Use ValidationError from errors-utils and let error middleware handle response
57
- const validationError = new ValidationError('Validation failed', {
58
- validationErrors: errors,
57
+ const validationError = new ValidationError({
58
+ fieldErrors: errors,
59
59
  });
60
60
  return next(validationError);
61
61
  }
@@ -1,4 +1,4 @@
1
- import { ICache, SessionStore } from '@naman_deep_singh/cache';
1
+ import { type ICache, SessionStore } from '@naman_deep_singh/cache';
2
2
  import type { Server } from 'http';
3
3
  import type { Application } from 'express';
4
4
  import type { ServerConfig, SocketIOConfig } from '../types';
@@ -1,7 +1,6 @@
1
- import type { Request, RequestHandler } from 'node_modules/@types/express';
1
+ import type { Request, RequestHandler } from 'express';
2
2
  export interface AuthConfig {
3
3
  secret: string;
4
- unauthorizedMessage?: string;
5
4
  tokenExtractor?: (req: Request) => string | null;
6
5
  }
7
6
  export declare function createAuthMiddleware(config: AuthConfig): RequestHandler;
@@ -1,2 +1,2 @@
1
- import type { ErrorRequestHandler } from 'node_modules/@types/express';
1
+ import type { ErrorRequestHandler } from 'express';
2
2
  export declare function createErrorHandler(): ErrorRequestHandler;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naman_deep_singh/server-utils",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "description": "Extensible server utilities for Express.js microservices with TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -28,7 +28,7 @@
28
28
  "license": "ISC",
29
29
  "dependencies": {
30
30
  "@naman_deep_singh/cache": "^1.3.1",
31
- "@naman_deep_singh/errors-utils": "^1.1.1",
31
+ "@naman_deep_singh/errors-utils": "^1.3.4",
32
32
  "@naman_deep_singh/security": "^1.3.2",
33
33
  "@types/express": "^5.0.5",
34
34
  "cookie-parser": "^1.4.6",