response-standardizer 1.2.1 → 1.2.2

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.js CHANGED
@@ -1,27 +1,34 @@
1
- import { generateRequestId, getTimestamp } from "./utils.js";
2
- import axios from "axios";
3
- import jwt from "jsonwebtoken";
4
- import path from "path";
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ServiceException = exports.handleValidationException = exports.handleRestException = exports.log = exports.info = exports.warn = exports.error = exports.RestMiddleware = exports.RestResponse = exports.protect = exports.initKeycloak = void 0;
7
+ const utils_1 = require("./utils");
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
10
+ const path_1 = __importDefault(require("path"));
5
11
  let KEYCLOAK_PUBLIC_KEY = null;
6
- export const initKeycloak = async (config) => {
12
+ const initKeycloak = async (config) => {
7
13
  const KEYCLOAK_SERVICE = config.service ?? "localhost";
8
14
  const KEYCLOAK_REALM = config.realm ?? "master";
9
15
  const realmUrl = `http://${KEYCLOAK_SERVICE}/realms/${KEYCLOAK_REALM}`;
10
- info(`Keycloak PublicKey Url: ${realmUrl}`);
11
- const resp = await axios.get(realmUrl);
16
+ (0, exports.info)(`Keycloak PublicKey Url: ${realmUrl}`);
17
+ const resp = await axios_1.default.get(realmUrl);
12
18
  const key = resp.data.public_key;
13
19
  KEYCLOAK_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----\n${key.match(/.{1,64}/g)?.join("\n")}\n-----END PUBLIC KEY-----`;
14
20
  };
15
- export const protect = (allowedRoles) => {
21
+ exports.initKeycloak = initKeycloak;
22
+ const protect = (allowedRoles) => {
16
23
  return (req, res, next) => {
17
24
  const authHeader = req.headers["authorization"];
18
25
  if (!authHeader)
19
- return RestResponse.unauthorized(req, res);
26
+ return exports.RestResponse.unauthorized(req, res);
20
27
  const token = authHeader.split(" ")[1];
21
28
  if (!token)
22
- return RestResponse.unauthorized(req, res, "Token malformed");
29
+ return exports.RestResponse.unauthorized(req, res, "Token malformed");
23
30
  try {
24
- const decoded = jwt.verify(token, KEYCLOAK_PUBLIC_KEY, { algorithms: ["RS256"] });
31
+ const decoded = jsonwebtoken_1.default.verify(token, KEYCLOAK_PUBLIC_KEY, { algorithms: ["RS256"] });
25
32
  req.user = decoded;
26
33
  req.token = token;
27
34
  if (allowedRoles)
@@ -29,15 +36,16 @@ export const protect = (allowedRoles) => {
29
36
  next();
30
37
  }
31
38
  catch (err) {
32
- error(err?.message);
33
- return RestResponse.unauthorized(req, res, "Token is not valid");
39
+ (0, exports.error)(err?.message);
40
+ return exports.RestResponse.unauthorized(req, res, "Token is not valid");
34
41
  }
35
42
  };
36
43
  };
44
+ exports.protect = protect;
37
45
  const role = (req, res, next, allowedRoles) => {
38
46
  const user = req.user;
39
47
  if (!user) {
40
- return RestResponse.unauthorized(req, res);
48
+ return exports.RestResponse.unauthorized(req, res);
41
49
  }
42
50
  const realmRoles = (user?.realm_access?.roles ?? []).map((r) => r.toUpperCase());
43
51
  const clientRoles = Object.values(user?.resource_access ?? {})
@@ -47,7 +55,7 @@ const role = (req, res, next, allowedRoles) => {
47
55
  const allRoles = [...realmRoles, ...clientRoles];
48
56
  const hasAccess = allowedUpper.some((role) => allRoles.includes(role));
49
57
  if (!hasAccess) {
50
- return RestResponse.accessDenied(req, res);
58
+ return exports.RestResponse.accessDenied(req, res);
51
59
  }
52
60
  next();
53
61
  };
@@ -81,7 +89,7 @@ const accessDenied = (req, res, message = "Access denied") => {
81
89
  const notFound = (req, res, message = "Not found") => {
82
90
  res.status(404).json({ message });
83
91
  };
84
- export const RestResponse = {
92
+ exports.RestResponse = {
85
93
  success,
86
94
  paginate,
87
95
  created,
@@ -102,8 +110,8 @@ const responseHandlerMiddleware = (req, res, next) => {
102
110
  message: data?.message || res.locals.message || (res.statusCode < 300 ? "OK" : "Error"),
103
111
  errors: data?.errors ?? null,
104
112
  meta: {
105
- requestId: res.locals.requestId || generateRequestId(),
106
- timestamp: getTimestamp()
113
+ requestId: res.locals.requestId || (0, utils_1.generateRequestId)(),
114
+ timestamp: (0, utils_1.getTimestamp)()
107
115
  }
108
116
  };
109
117
  return oldJson(response);
@@ -116,10 +124,10 @@ const responseHandlerMiddleware = (req, res, next) => {
116
124
  }
117
125
  return oldSend(data);
118
126
  };
119
- res.locals.requestId = generateRequestId();
127
+ res.locals.requestId = (0, utils_1.generateRequestId)();
120
128
  next();
121
129
  };
122
- export const RestMiddleware = {
130
+ exports.RestMiddleware = {
123
131
  responseHandlerMiddleware
124
132
  };
125
133
  const colors = {
@@ -129,16 +137,19 @@ const colors = {
129
137
  YELLOW: "\x1b[33m"
130
138
  };
131
139
  const isProduction = process.env.NODE_ENV === "production";
132
- export const error = (message, meta) => {
133
- log("ERROR", message, meta);
140
+ const error = (message, meta) => {
141
+ (0, exports.log)("ERROR", message, meta);
134
142
  };
135
- export const warn = (message, meta) => {
136
- log("WARN", message, meta);
143
+ exports.error = error;
144
+ const warn = (message, meta) => {
145
+ (0, exports.log)("WARN", message, meta);
137
146
  };
138
- export const info = (message, meta) => {
139
- log("INFO", message, meta);
147
+ exports.warn = warn;
148
+ const info = (message, meta) => {
149
+ (0, exports.log)("INFO", message, meta);
140
150
  };
141
- export const log = (level, message, meta) => {
151
+ exports.info = info;
152
+ const log = (level, message, meta) => {
142
153
  const timestamp = new Date().toISOString();
143
154
  // انتخاب رنگ فقط در dev
144
155
  let color = colors.RESET;
@@ -156,7 +167,7 @@ export const log = (level, message, meta) => {
156
167
  if (stack) {
157
168
  const match = stack.match(/\((.*):(\d+):(\d+)\)/);
158
169
  if (match) {
159
- const fileName = path.basename(match[1]);
170
+ const fileName = path_1.default.basename(match[1]);
160
171
  const line = match[2];
161
172
  const column = match[3];
162
173
  location = `${fileName}:${line}:${column}`;
@@ -166,29 +177,31 @@ export const log = (level, message, meta) => {
166
177
  // چاپ لاگ
167
178
  console.log(`${color}[${timestamp}][${location}][${level}] ${message}${metaStr}${colors.RESET}`);
168
179
  };
169
- export const handleRestException = (req, res, err) => {
180
+ exports.log = log;
181
+ const handleRestException = (req, res, err) => {
170
182
  if (err instanceof ServiceException) {
171
183
  if (err?.status === 401) {
172
- RestResponse.unauthorized(req, res, err.message);
184
+ exports.RestResponse.unauthorized(req, res, err.message);
173
185
  }
174
186
  else if (err?.status === 403) {
175
- RestResponse.accessDenied(req, res, err.message);
187
+ exports.RestResponse.accessDenied(req, res, err.message);
176
188
  }
177
189
  else if (err?.status === 400) {
178
- RestResponse.validationError(req, res, err.errors);
190
+ exports.RestResponse.validationError(req, res, err.errors);
179
191
  }
180
192
  else if (err?.status === 500) {
181
- RestResponse.exceptionError(req, res, err.message);
193
+ exports.RestResponse.exceptionError(req, res, err.message);
182
194
  }
183
195
  else if (err?.status === 404) {
184
- RestResponse.notFound(req, res, err.message);
196
+ exports.RestResponse.notFound(req, res, err.message);
185
197
  }
186
198
  }
187
199
  else if (err instanceof Error) {
188
- RestResponse.exceptionError(req, res, err.message);
200
+ exports.RestResponse.exceptionError(req, res, err.message);
189
201
  }
190
202
  };
191
- export const handleValidationException = (error) => {
203
+ exports.handleRestException = handleRestException;
204
+ const handleValidationException = (error) => {
192
205
  const zodError = error;
193
206
  if (zodError.issues) {
194
207
  const validationErrors = {};
@@ -202,7 +215,8 @@ export const handleValidationException = (error) => {
202
215
  }
203
216
  throw new ServiceException("Internal server error", 500, error);
204
217
  };
205
- export class ServiceException extends Error {
218
+ exports.handleValidationException = handleValidationException;
219
+ class ServiceException extends Error {
206
220
  constructor(message, status = 400, errors = null) {
207
221
  super(message);
208
222
  this.name = "ServiceException";
@@ -210,3 +224,4 @@ export class ServiceException extends Error {
210
224
  this.errors = errors;
211
225
  }
212
226
  }
227
+ exports.ServiceException = ServiceException;
package/dist/types.js CHANGED
@@ -1 +1,2 @@
1
- export {};
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/utils.js CHANGED
@@ -1,7 +1,12 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- export const generateRequestId = () => {
3
- return uuidv4();
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTimestamp = exports.generateRequestId = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const generateRequestId = () => {
6
+ return (0, uuid_1.v4)();
4
7
  };
5
- export const getTimestamp = () => {
8
+ exports.generateRequestId = generateRequestId;
9
+ const getTimestamp = () => {
6
10
  return new Date().toISOString();
7
11
  };
12
+ exports.getTimestamp = getTimestamp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "response-standardizer",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
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,6 +1,6 @@
1
1
  import { Request, Response, NextFunction } from "express";
2
- import { ErrorFields, StandardResponse, RestResponseFunctions, RestMiddlewareFunctions, AuthRequest, Pagination } from "./types.js";
3
- import { generateRequestId, getTimestamp } from "./utils.js";
2
+ import { ErrorFields, StandardResponse, RestResponseFunctions, RestMiddlewareFunctions, AuthRequest, Pagination } from "./types";
3
+ import { generateRequestId, getTimestamp } from "./utils";
4
4
  import axios from "axios";
5
5
  import jwt, { TokenExpiredError } from "jsonwebtoken";
6
6
  import path from "path";
package/src/utils.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { v4 as uuidv4 } from "uuid";
2
- import { RestResponse } from ".";
3
2
 
4
3
  export const generateRequestId = () => {
5
4
  return uuidv4();
package/tsconfig.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2020",
4
- "module": "ESNext",
4
+ "module": "CommonJS",
5
5
  "moduleResolution": "Node",
6
- "declaration": true,
6
+ "rootDir": "src",
7
7
  "outDir": "dist",
8
8
  "strict": true,
9
9
  "esModuleInterop": true,
10
+ "forceConsistentCasingInFileNames": true,
10
11
  "skipLibCheck": true
11
12
  },
12
- "include": ["src/**/*.ts"]
13
+ "include": ["src/**/*"]
13
14
  }
package/dist/index.d.ts DELETED
@@ -1,32 +0,0 @@
1
- import { Request, Response } from "express";
2
- import { RestResponseFunctions, RestMiddlewareFunctions } from "./types.js";
3
- declare global {
4
- namespace Express {
5
- interface Response {
6
- json: (data: any) => Response;
7
- send: (data?: any) => Response;
8
- locals: {
9
- requestId: string;
10
- [key: string]: any;
11
- };
12
- }
13
- }
14
- }
15
- export declare const initKeycloak: (config: {
16
- service?: string;
17
- realm?: string;
18
- }) => Promise<void>;
19
- export declare const protect: (allowedRoles?: string[]) => (req: any, res: any, next: any) => void;
20
- export declare const RestResponse: RestResponseFunctions;
21
- export declare const RestMiddleware: RestMiddlewareFunctions;
22
- export declare const error: (message: string, meta?: any) => void;
23
- export declare const warn: (message: string, meta?: any) => void;
24
- export declare const info: (message: string, meta?: any) => void;
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;
27
- export declare const handleValidationException: (error: any) => never;
28
- export declare class ServiceException extends Error {
29
- status: number;
30
- errors: any;
31
- constructor(message: string, status?: number, errors?: any);
32
- }
package/dist/types.d.ts DELETED
@@ -1,40 +0,0 @@
1
- import { Request, Response, NextFunction } from "express";
2
- export interface StandardResponse<T = any> {
3
- code: number;
4
- message: string;
5
- errors: Record<string, string[]> | null;
6
- meta: {
7
- requestId: string;
8
- timestamp: string;
9
- };
10
- }
11
- export interface PaginationMeta {
12
- total: number;
13
- page: number;
14
- limit: number;
15
- totalPages: number;
16
- }
17
- export interface Pagination<T> {
18
- data: T[];
19
- meta: PaginationMeta;
20
- }
21
- export type ErrorFields = Record<string, string[]>;
22
- export type Middleware = (req: Request, res: Response, next: NextFunction) => void;
23
- export interface RestMiddlewareFunctions {
24
- responseHandlerMiddleware: <T>(req: Request, res: Response, next: NextFunction) => void;
25
- }
26
- export interface RestResponseFunctions {
27
- success: <T>(req: Request, res: Response, data: T) => void;
28
- paginate: <T>(req: Request, res: Response, data: Pagination<T>) => void;
29
- created: <T>(req: Request, res: Response, data: T) => void;
30
- deleted: (req: Request, res: Response) => void;
31
- validationError: (req: Request, res: Response, errors: ErrorFields, message?: string) => void;
32
- exceptionError: (req: Request, res: Response, errors: any, message?: string) => void;
33
- unauthorized: (req: Request, res: Response, message?: string) => void;
34
- accessDenied: (req: Request, res: Response, message?: string) => void;
35
- notFound: (req: Request, res: Response, message?: string) => void;
36
- }
37
- export interface AuthRequest extends Request {
38
- user?: any;
39
- token?: string;
40
- }
package/dist/utils.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare const generateRequestId: () => string;
2
- export declare const getTimestamp: () => string;