response-standardizer 1.1.1 → 1.1.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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Request, Response } from "express";
1
2
  import { RestResponseFunctions, RestMiddlewareFunctions } from "./types.js";
2
3
  declare global {
3
4
  namespace Express {
@@ -22,3 +23,4 @@ export declare const error: (message: string, meta?: any) => void;
22
23
  export declare const warn: (message: string, meta?: any) => void;
23
24
  export declare const info: (message: string, meta?: any) => void;
24
25
  export declare const log: (level: "INFO" | "WARN" | "ERROR", message: string, meta?: any) => void;
26
+ export declare const handleRestException: (req: Request, res: Response, err: Error) => void;
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { generateRequestId, getTimestamp } from "./utils.js";
2
2
  import axios from "axios";
3
3
  import jwt from "jsonwebtoken";
4
4
  import path from "path";
5
+ import { ServiceException } from "./service.exception.js";
5
6
  let KEYCLOAK_PUBLIC_KEY = null;
6
7
  export const initKeycloak = async (config) => {
7
8
  const KEYCLOAK_SERVICE = config.service ?? "localhost";
@@ -51,24 +52,23 @@ const role = (req, res, next, allowedRoles) => {
51
52
  }
52
53
  next();
53
54
  };
54
- const success = (req, res, data, message = null) => {
55
- res.status(200).json({ data, message });
55
+ const success = (req, res, data) => {
56
+ res.status(200).json(data);
56
57
  };
57
- const paginate = (req, res, data, pagination, message = null) => {
58
- res.status(200).json({ data, message, pagination });
58
+ const paginate = (req, res, data) => {
59
+ res.status(200).json(data);
59
60
  };
60
- const created = (req, res, data, message = "Record created successfully") => {
61
- res.status(201).json({ data, message });
61
+ const created = (req, res, data) => {
62
+ res.status(201).json(data);
62
63
  };
63
64
  const deleted = (req, res) => {
64
65
  res.status(204).send();
65
66
  };
66
67
  const validationError = (req, res, errors, message = "Validation error") => {
67
- res.status(400).json({ errors, message, data: null });
68
+ res.status(400).json({ errors, message });
68
69
  };
69
70
  const exceptionError = (req, res, errors, message = "Internal server error") => {
70
71
  res.status(500).json({
71
- data: null,
72
72
  message,
73
73
  errors
74
74
  });
@@ -95,20 +95,17 @@ const responseHandlerMiddleware = (req, res, next) => {
95
95
  res.json = function (data) {
96
96
  if (res.statusCode > 204) {
97
97
  const response = {
98
- status: res.statusCode >= 200 && res.statusCode < 300 ? "success" : "error",
99
98
  code: res.statusCode,
100
99
  message: data?.message || res.locals.message || (res.statusCode < 300 ? "OK" : "Error"),
101
- data: data?.data ?? null,
102
100
  errors: data?.errors ?? null,
103
101
  meta: {
104
102
  requestId: res.locals.requestId || generateRequestId(),
105
- timestamp: getTimestamp(),
106
- pagination: data?.pagination ?? null
103
+ timestamp: getTimestamp()
107
104
  }
108
105
  };
109
106
  return oldJson(response);
110
107
  }
111
- return oldJson(data?.data);
108
+ return oldJson(data);
112
109
  };
113
110
  res.send = function (data) {
114
111
  if (res.statusCode === 204) {
@@ -166,3 +163,22 @@ export const log = (level, message, meta) => {
166
163
  // چاپ لاگ
167
164
  console.log(`${color}[${timestamp}][${location}][${level}] ${message}${metaStr}${colors.RESET}`);
168
165
  };
166
+ export const handleRestException = (req, res, err) => {
167
+ if (err instanceof ServiceException) {
168
+ if (err?.status === 401) {
169
+ RestResponse.unauthorized(req, res, err.message);
170
+ }
171
+ else if (err?.status === 403) {
172
+ RestResponse.accessDenied(req, res, err.message);
173
+ }
174
+ else if (err?.status === 400) {
175
+ RestResponse.validationError(req, res, err.errors);
176
+ }
177
+ else if (err?.status === 500) {
178
+ RestResponse.exceptionError(req, res, err.message);
179
+ }
180
+ }
181
+ else if (err instanceof Error) {
182
+ RestResponse.exceptionError(req, res, err.message);
183
+ }
184
+ };
@@ -0,0 +1,5 @@
1
+ export declare class ServiceException extends Error {
2
+ status: number;
3
+ errors: any;
4
+ constructor(message: string, status?: number, errors?: any);
5
+ }
@@ -0,0 +1,8 @@
1
+ export class ServiceException extends Error {
2
+ constructor(message, status = 400, errors = null) {
3
+ super(message);
4
+ this.name = "ServiceException";
5
+ this.status = status;
6
+ this.errors = errors;
7
+ }
8
+ }
package/dist/types.d.ts CHANGED
@@ -1,17 +1,15 @@
1
1
  import { Request, Response, NextFunction } from "express";
2
2
  export interface StandardResponse<T = any> {
3
- status: "success" | "error";
4
3
  code: number;
5
4
  message: string;
6
- data: T | null;
7
5
  errors: Record<string, string[]> | null;
8
6
  meta: {
9
7
  requestId: string;
10
8
  timestamp: string;
11
- pagination: PaginationMeta | null;
12
9
  };
13
10
  }
14
- export interface PaginationMeta {
11
+ export interface Pagination<T> {
12
+ data: T[];
15
13
  total: number;
16
14
  page: number;
17
15
  perPage: number;
@@ -23,9 +21,9 @@ export interface RestMiddlewareFunctions {
23
21
  responseHandlerMiddleware: <T>(req: Request, res: Response, next: NextFunction) => void;
24
22
  }
25
23
  export interface RestResponseFunctions {
26
- success: <T>(req: Request, res: Response, data: T, message?: string | null) => void;
27
- paginate: <T>(req: Request, res: Response, data: T, pagination: PaginationMeta, message?: string | null) => void;
28
- created: <T>(req: Request, res: Response, data: T, message?: string) => void;
24
+ success: <T>(req: Request, res: Response, data: T) => void;
25
+ paginate: <T>(req: Request, res: Response, data: Pagination<T>) => void;
26
+ created: <T>(req: Request, res: Response, data: T) => void;
29
27
  deleted: (req: Request, res: Response) => void;
30
28
  validationError: (req: Request, res: Response, errors: ErrorFields, message?: string) => void;
31
29
  exceptionError: (req: Request, res: Response, errors: any, message?: string) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "response-standardizer",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Express middleware to standardize API responses",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { Request, Response, NextFunction } from "express";
2
- import { ErrorFields, PaginationMeta, StandardResponse, RestResponseFunctions, RestMiddlewareFunctions, AuthRequest } from "./types.js";
2
+ import { ErrorFields, StandardResponse, RestResponseFunctions, RestMiddlewareFunctions, AuthRequest, Pagination } from "./types.js";
3
3
  import { generateRequestId, getTimestamp } from "./utils.js";
4
4
  import axios from "axios";
5
5
  import jwt, { TokenExpiredError } from "jsonwebtoken";
6
6
  import path from "path";
7
+ import { ServiceException } from "./service.exception.js";
7
8
  declare global {
8
9
  namespace Express {
9
10
  interface Response {
@@ -71,22 +72,20 @@ const role = (req: any, res: any, next: any, allowedRoles: string[]) => {
71
72
  }
72
73
  next()
73
74
  }
74
- const success = <T>(req: Request, res: Response, data: T, message: string | null = null) => {
75
- res.status(200).json({ data, message });
75
+ const success = <T>(req: Request, res: Response, data: T) => {
76
+ res.status(200).json(data);
76
77
  };
77
78
 
78
79
  const paginate = <T>(
79
80
  req: Request,
80
81
  res: Response,
81
- data: T,
82
- pagination: PaginationMeta,
83
- message: string | null = null
82
+ data: Pagination<T>
84
83
  ) => {
85
- res.status(200).json({ data, message, pagination });
84
+ res.status(200).json(data);
86
85
  };
87
86
 
88
- const created = <T>(req: Request, res: Response, data: T, message = "Record created successfully") => {
89
- res.status(201).json({ data, message });
87
+ const created = <T>(req: Request, res: Response, data: T) => {
88
+ res.status(201).json(data);
90
89
  };
91
90
 
92
91
  const deleted = (req: Request, res: Response) => {
@@ -99,7 +98,7 @@ const validationError = (
99
98
  errors: ErrorFields,
100
99
  message = "Validation error"
101
100
  ) => {
102
- res.status(400).json({ errors, message, data: null });
101
+ res.status(400).json({ errors, message });
103
102
  };
104
103
 
105
104
  const exceptionError = (
@@ -109,7 +108,6 @@ const exceptionError = (
109
108
  message = "Internal server error"
110
109
  ) => {
111
110
  res.status(500).json({
112
- data: null,
113
111
  message,
114
112
  errors
115
113
  });
@@ -147,21 +145,18 @@ const responseHandlerMiddleware = (
147
145
  res.json = function (data: any) {
148
146
  if(res.statusCode > 204){
149
147
  const response: StandardResponse = {
150
- status: res.statusCode >= 200 && res.statusCode < 300 ? "success" : "error",
151
148
  code: res.statusCode,
152
149
  message: data?.message || res.locals.message || (res.statusCode < 300 ? "OK" : "Error"),
153
- data: data?.data ?? null,
154
150
  errors: data?.errors ?? null,
155
151
  meta: {
156
152
  requestId: res.locals.requestId || generateRequestId(),
157
- timestamp: getTimestamp(),
158
- pagination: data?.pagination ?? null
153
+ timestamp: getTimestamp()
159
154
  }
160
155
  };
161
156
 
162
157
  return oldJson(response);
163
158
  }
164
- return oldJson(data?.data);
159
+ return oldJson(data);
165
160
  };
166
161
 
167
162
  res.send = function (data: any) {
@@ -226,4 +221,20 @@ export const log = (level: "INFO" | "WARN" | "ERROR", message: string, meta?: an
226
221
 
227
222
  // چاپ لاگ
228
223
  console.log(`${color}[${timestamp}][${location}][${level}] ${message}${metaStr}${colors.RESET}`);
229
- };
224
+ };
225
+
226
+ export const handleRestException = (req: Request, res: Response, err: Error) => {
227
+ if(err instanceof ServiceException){
228
+ if(err?.status === 401){
229
+ RestResponse.unauthorized(req, res, err.message)
230
+ }else if(err?.status === 403){
231
+ RestResponse.accessDenied(req, res, err.message)
232
+ }else if(err?.status === 400){
233
+ RestResponse.validationError(req, res, err.errors)
234
+ }else if(err?.status === 500){
235
+ RestResponse.exceptionError(req, res, err.message)
236
+ }
237
+ }else if(err instanceof Error){
238
+ RestResponse.exceptionError(req, res, err.message)
239
+ }
240
+ }
@@ -0,0 +1,10 @@
1
+ export class ServiceException extends Error {
2
+ status: number;
3
+ errors: any
4
+ constructor(message: string, status: number = 400, errors: any = null) {
5
+ super(message);
6
+ this.name = "ServiceException";
7
+ this.status = status;
8
+ this.errors = errors;
9
+ }
10
+ }
package/src/types.ts CHANGED
@@ -1,19 +1,17 @@
1
1
  import { Request, Response, NextFunction } from "express";
2
2
 
3
3
  export interface StandardResponse<T = any> {
4
- status: "success" | "error";
5
4
  code: number;
6
5
  message: string;
7
- data: T | null;
8
6
  errors: Record<string, string[]> | null;
9
7
  meta: {
10
8
  requestId: string;
11
9
  timestamp: string;
12
- pagination: PaginationMeta | null;
13
10
  };
14
11
  }
15
12
 
16
- export interface PaginationMeta {
13
+ export interface Pagination<T>{
14
+ data: T[];
17
15
  total: number;
18
16
  page: number;
19
17
  perPage: number;
@@ -28,15 +26,13 @@ export interface RestMiddlewareFunctions {
28
26
  responseHandlerMiddleware: <T>(req: Request, res: Response, next: NextFunction) => void
29
27
  }
30
28
  export interface RestResponseFunctions {
31
- success: <T>(req: Request, res: Response, data: T, message?: string | null) => void;
29
+ success: <T>(req: Request, res: Response, data: T) => void;
32
30
  paginate: <T>(
33
31
  req: Request,
34
32
  res: Response,
35
- data: T,
36
- pagination: PaginationMeta,
37
- message?: string | null
33
+ data: Pagination<T>
38
34
  ) => void;
39
- created: <T>(req: Request, res: Response, data: T, message?: string) => void;
35
+ created: <T>(req: Request, res: Response, data: T) => void;
40
36
  deleted: (req: Request, res: Response) => void;
41
37
  validationError: (
42
38
  req: Request,
package/src/utils.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { v4 as uuidv4 } from "uuid";
2
+ import { RestResponse } from ".";
2
3
 
3
4
  export const generateRequestId = () => {
4
5
  return uuidv4();
@@ -6,4 +7,4 @@ export const generateRequestId = () => {
6
7
 
7
8
  export const getTimestamp = () => {
8
9
  return new Date().toISOString();
9
- }
10
+ }