@mustafahmed1997/learnify-backend 1.0.0 → 1.1.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.
@@ -0,0 +1,4 @@
1
+ export declare function handlePrismaError(error: unknown): {
2
+ status: number;
3
+ message: string;
4
+ };
@@ -0,0 +1,57 @@
1
+ function isPrismaKnownRequestError(error) {
2
+ return (typeof error === "object" &&
3
+ error !== null &&
4
+ "code" in error &&
5
+ typeof error.code === "string" &&
6
+ /^P\d{4}$/.test(error.code));
7
+ }
8
+ export function handlePrismaError(error) {
9
+ if (isPrismaKnownRequestError(error)) {
10
+ switch (error.code) {
11
+ case "P2002":
12
+ return {
13
+ status: 409,
14
+ message: `Duplicate value for ${String(error.meta?.target ?? "field")}`,
15
+ };
16
+ case "P2003":
17
+ return {
18
+ status: 400,
19
+ message: "Invalid foreign key reference",
20
+ };
21
+ case "P2025":
22
+ return {
23
+ status: 404,
24
+ message: "Record not found",
25
+ };
26
+ case "P2014":
27
+ return {
28
+ status: 400,
29
+ message: "Invalid relation reference",
30
+ };
31
+ case "P2000":
32
+ return {
33
+ status: 400,
34
+ message: `Value too long for ${String(error.meta?.column_name ?? "column")}`,
35
+ };
36
+ default:
37
+ return {
38
+ status: 500,
39
+ message: `Database error: ${error.message ?? "Unknown database error"}`,
40
+ };
41
+ }
42
+ }
43
+ if (typeof error === "object" &&
44
+ error !== null &&
45
+ "name" in error &&
46
+ error.name === "PrismaClientValidationError") {
47
+ return {
48
+ status: 400,
49
+ message: `Invalid input data: ${error instanceof Error ? error.message : String(error)}`,
50
+ };
51
+ }
52
+ return {
53
+ status: 500,
54
+ message: `Unknown server error: ${error instanceof Error ? error.message : String(error)}`,
55
+ };
56
+ }
57
+ //# sourceMappingURL=handlePrismaError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlePrismaError.js","sourceRoot":"","sources":["../../src/errors/handlePrismaError.ts"],"names":[],"mappings":"AAUA,SAAS,yBAAyB,CAChC,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAQ,KAA4B,CAAC,IAAI,KAAK,QAAQ;QACtD,UAAU,CAAC,IAAI,CAAE,KAA0B,CAAC,IAAI,CAAC,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAI9C,IAAI,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,OAAO;gBACV,OAAO;oBACL,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,uBAAuB,MAAM,CACpC,KAAK,CAAC,IAAI,EAAE,MAAM,IAAI,OAAO,CAC9B,EAAE;iBACJ,CAAC;YAEJ,KAAK,OAAO;gBACV,OAAO;oBACL,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,+BAA+B;iBACzC,CAAC;YAEJ,KAAK,OAAO;gBACV,OAAO;oBACL,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,kBAAkB;iBAC5B,CAAC;YAEJ,KAAK,OAAO;gBACV,OAAO;oBACL,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,4BAA4B;iBACtC,CAAC;YAEJ,KAAK,OAAO;gBACV,OAAO;oBACL,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,sBAAsB,MAAM,CACnC,KAAK,CAAC,IAAI,EAAE,WAAW,IAAI,QAAQ,CACpC,EAAE;iBACJ,CAAC;YAEJ;gBACE,OAAO;oBACL,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,mBAAmB,KAAK,CAAC,OAAO,IAAI,wBAAwB,EAAE;iBACxE,CAAC;QACN,CAAC;IACH,CAAC;IAED,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,KAAK,CAAC,IAAI,KAAK,6BAA6B,EAC5C,CAAC;QACD,OAAO;YACL,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,uBACP,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE;SACH,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,yBACP,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE;KACH,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import "./types/express.js";
2
2
  export { checkAuth } from "./middlewares/checkAuth.js";
3
3
  export { checkRole } from "./middlewares/checkRole.js";
4
+ export { validationMiddleware } from "./middlewares/validationMiddleware.js";
4
5
  export { validRoles } from "./constants/validRoles.js";
5
6
  export type { Role } from "./constants/validRoles.js";
6
7
  export { AppError } from "./errors/AppError.js";
7
8
  export { globalErrorHandler } from "./errors/globalErrorHandler.js";
9
+ export { handlePrismaError } from "./errors/handlePrismaError.js";
8
10
  export type { ClerkUser } from "./types/ClerkUser.js";
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import "./types/express.js";
2
2
  export { checkAuth } from "./middlewares/checkAuth.js";
3
3
  export { checkRole } from "./middlewares/checkRole.js";
4
+ export { validationMiddleware } from "./middlewares/validationMiddleware.js";
4
5
  export { validRoles } from "./constants/validRoles.js";
5
6
  export { AppError } from "./errors/AppError.js";
6
7
  export { globalErrorHandler } from "./errors/globalErrorHandler.js";
8
+ export { handlePrismaError } from "./errors/handlePrismaError.js";
7
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAGvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAGvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { NextFunction, Request, Response } from "express";
2
+ import z from "zod";
3
+ export declare function validationMiddleware(validaitonSchema: z.ZodType): (req: Request, res: Response, next: NextFunction) => void;
@@ -0,0 +1,27 @@
1
+ import z from "zod";
2
+ export function validationMiddleware(validaitonSchema) {
3
+ return (req, res, next) => {
4
+ try {
5
+ const result = validaitonSchema.safeParse(req.body);
6
+ if (!result.success) {
7
+ const formattedErrors = result.error.issues.map((issue) => ({
8
+ field: issue.path.join("."),
9
+ message: issue.message,
10
+ }));
11
+ req.validationErrorArr = formattedErrors;
12
+ return next(new Error(""));
13
+ }
14
+ else {
15
+ return next();
16
+ }
17
+ }
18
+ catch (error) {
19
+ if (error instanceof z.ZodError) {
20
+ req.validationErrorArr = error.issues;
21
+ return next(error.issues);
22
+ }
23
+ return next(error);
24
+ }
25
+ };
26
+ }
27
+ //# sourceMappingURL=validationMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validationMiddleware.js","sourceRoot":"","sources":["../../src/middlewares/validationMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,MAAM,UAAU,oBAAoB,CAAC,gBAA2B;IAC9D,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACzD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBAC1D,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;oBAC3B,OAAO,EAAE,KAAK,CAAC,OAAO;iBACvB,CAAC,CAAC,CAAC;gBAEJ,GAAG,CAAC,kBAAkB,GAAG,eAAe,CAAC;gBAEzC,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC/B,GAAW,CAAC,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -3,6 +3,10 @@ declare global {
3
3
  namespace Express {
4
4
  interface Request {
5
5
  user?: ClerkUser;
6
+ validationErrorArr?: {
7
+ field: string;
8
+ message: string;
9
+ }[];
6
10
  }
7
11
  }
8
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mustafahmed1997/learnify-backend",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Shared Clerk-based auth middlewares, role checking, error utilities, and Express types for Learnify backend microservices.",
5
5
  "keywords": [
6
6
  "express",
@@ -37,7 +37,8 @@
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@clerk/express": "^1.7.74",
40
- "express": "^5.1.0"
40
+ "express": "^5.1.0",
41
+ "zod": "^4.5.4"
41
42
  },
42
43
  "devDependencies": {
43
44
  "@clerk/express": "^1.7.74",
@@ -45,6 +46,7 @@
45
46
  "@types/node": "^20.19.39",
46
47
  "express": "^5.1.0",
47
48
  "typescript": "^5.1.6",
48
- "vitest": "^3.0.0"
49
+ "vitest": "^3.0.0",
50
+ "zod": "^4.5.4"
49
51
  }
50
52
  }