@prosopo/api-express-router 3.0.47 → 3.1.17

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.
Files changed (31) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +10 -6
  2. package/.turbo/turbo-build$colon$tsc.log +27 -21
  3. package/.turbo/turbo-build.log +11 -7
  4. package/CHANGELOG.md +325 -0
  5. package/dist/cjs/endpointAdapter/apiExpressDefaultEndpointAdapter.cjs +2 -1
  6. package/dist/cjs/middlewares/requestLoggerMiddleware.cjs +14 -4
  7. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.d.ts +1 -1
  8. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.d.ts.map +1 -1
  9. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js +2 -1
  10. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js.map +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/middlewares/requestLoggerMiddleware.d.ts.map +1 -1
  13. package/dist/middlewares/requestLoggerMiddleware.js +11 -1
  14. package/dist/middlewares/requestLoggerMiddleware.js.map +1 -1
  15. package/dist/tests/unit/middlewares/authMiddleware.unit.test.js +2 -1
  16. package/dist/tests/unit/middlewares/authMiddleware.unit.test.js.map +1 -1
  17. package/express.d.ts +3 -1
  18. package/package.json +14 -8
  19. package/src/apiExpressRouterFactory.ts +68 -0
  20. package/src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts +65 -0
  21. package/src/endpointAdapter/apiExpressEndpointAdapter.ts +28 -0
  22. package/src/errorHandler.ts +33 -0
  23. package/src/index.ts +37 -0
  24. package/src/middlewares/authMiddleware.ts +93 -0
  25. package/src/middlewares/requestLoggerMiddleware.ts +55 -0
  26. package/src/tests/unit/errorHandler.unit.test.ts +190 -0
  27. package/src/tests/unit/middlewares/authMiddleware.unit.test.ts +183 -0
  28. package/tsconfig.cjs.json +34 -0
  29. package/tsconfig.json +41 -0
  30. package/tsconfig.tsbuildinfo +1 -0
  31. package/tsconfig.types.json +9 -0
@@ -1 +1 @@
1
- {"version":3,"file":"authMiddleware.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/unit/middlewares/authMiddleware.unit.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authMiddleware.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/unit/middlewares/authMiddleware.unit.test.ts"],"names":[],"mappings":"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"}
package/express.d.ts CHANGED
@@ -12,7 +12,8 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- import type { Logger } from "@prosopo/common";
15
+ import type { Logger } from "@prosopo/logger";
16
+ import type { IPInfoResponse } from "@prosopo/types";
16
17
  import type { TFunction } from "i18next";
17
18
 
18
19
  declare global {
@@ -27,6 +28,7 @@ declare global {
27
28
  ja4: string;
28
29
  logger: Logger;
29
30
  requestId?: string;
31
+ ipInfo?: IPInfoResponse;
30
32
  }
31
33
  }
32
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/api-express-router",
3
- "version": "3.0.47",
3
+ "version": "3.1.17",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -26,11 +26,12 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@polkadot/util": "13.5.7",
29
- "@prosopo/api-route": "2.6.36",
30
- "@prosopo/common": "3.1.28",
31
- "@prosopo/env": "3.2.35",
32
- "@prosopo/locale": "3.1.28",
33
- "@prosopo/types": "3.8.0",
29
+ "@prosopo/api-route": "2.6.46",
30
+ "@prosopo/common": "3.1.38",
31
+ "@prosopo/logger": "1.0.2",
32
+ "@prosopo/env": "3.5.7",
33
+ "@prosopo/locale": "3.2.4",
34
+ "@prosopo/types": "4.3.0",
34
35
  "@prosopo/util-crypto": "13.5.29",
35
36
  "dotenv": "16.4.5",
36
37
  "express": "4.21.2",
@@ -39,7 +40,7 @@
39
40
  "zod": "3.23.8"
40
41
  },
41
42
  "devDependencies": {
42
- "@prosopo/config": "3.3.0",
43
+ "@prosopo/config": "3.3.1",
43
44
  "@types/node": "22.10.2",
44
45
  "vitest": "3.2.4"
45
46
  },
@@ -49,5 +50,10 @@
49
50
  "url": "https://github.com/prosopo/captcha/issues"
50
51
  },
51
52
  "homepage": "https://github.com/prosopo/captcha#readme",
52
- "sideEffects": false
53
+ "sideEffects": false,
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/prosopo/captcha.git",
57
+ "directory": "packages/api-express-router"
58
+ }
53
59
  }
@@ -0,0 +1,68 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import type { ApiRoutes, ApiRoutesProvider } from "@prosopo/api-route";
16
+ import {
17
+ type NextFunction,
18
+ type Request,
19
+ type Response,
20
+ Router,
21
+ } from "express";
22
+ import type { ApiExpressEndpointAdapter } from "./endpointAdapter/apiExpressEndpointAdapter.js";
23
+ import { handleErrors } from "./errorHandler.js";
24
+
25
+ class ApiExpressRouterFactory {
26
+ public createRouter(
27
+ routersProvider: ApiRoutesProvider,
28
+ apiEndpointAdapter: ApiExpressEndpointAdapter,
29
+ ): Router {
30
+ const router = Router();
31
+ const apiRoutes = routersProvider.getRoutes();
32
+
33
+ this.registerRoutes(router, apiRoutes, apiEndpointAdapter);
34
+
35
+ // Your error handler should always be at the end of your application stack. Apparently it means not only after all
36
+ // app.use() but also after all your app.get() and app.post() calls.
37
+ // https://stackoverflow.com/a/62358794/1178971
38
+ router.use(handleErrors);
39
+
40
+ return router;
41
+ }
42
+
43
+ protected registerRoutes(
44
+ router: Router,
45
+ routes: ApiRoutes,
46
+ apiEndpointAdapter: ApiExpressEndpointAdapter,
47
+ ): void {
48
+ for (const [route, endpoint] of Object.entries(routes)) {
49
+ router.post(
50
+ route,
51
+ async (
52
+ request: Request,
53
+ response: Response,
54
+ next: NextFunction,
55
+ ): Promise<void> => {
56
+ return await apiEndpointAdapter.handleRequest(
57
+ endpoint,
58
+ request,
59
+ response,
60
+ next,
61
+ );
62
+ },
63
+ );
64
+ }
65
+ }
66
+ }
67
+
68
+ export { ApiExpressRouterFactory };
@@ -0,0 +1,65 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import type { ApiEndpoint } from "@prosopo/api-route";
16
+ import { ProsopoApiError } from "@prosopo/common";
17
+ import { type LogLevel, stringifyBigInts } from "@prosopo/logger";
18
+ import type { NextFunction, Request, Response } from "express";
19
+ import type { ZodType } from "zod";
20
+ import type { ApiExpressEndpointAdapter } from "./apiExpressEndpointAdapter.js";
21
+
22
+ class ApiExpressDefaultEndpointAdapter implements ApiExpressEndpointAdapter {
23
+ public constructor(
24
+ private readonly logLevel: LogLevel,
25
+ private readonly errorStatusCode: number,
26
+ ) {}
27
+
28
+ public async handleRequest(
29
+ endpoint: ApiEndpoint<ZodType | undefined>,
30
+ request: Request,
31
+ response: Response,
32
+ next: NextFunction,
33
+ ): Promise<void> {
34
+ let args: unknown;
35
+ try {
36
+ args = endpoint.getRequestArgsSchema()?.parse(request.body);
37
+ } catch (error) {
38
+ return next(
39
+ new ProsopoApiError("API.PARSE_ERROR", {
40
+ context: { code: 400, error: error },
41
+ }),
42
+ );
43
+ }
44
+
45
+ try {
46
+ const apiEndpointResponse = await endpoint.processRequest(
47
+ args,
48
+ request.logger,
49
+ );
50
+
51
+ // otherwise .json() will throw "TypeError: Do not know how to serialize a BigInt" as uses JSON.stringify
52
+ const responseObject = stringifyBigInts(apiEndpointResponse);
53
+
54
+ response.json(responseObject);
55
+ } catch (error) {
56
+ request.logger.error(() => ({
57
+ err: error,
58
+ }));
59
+
60
+ response.status(500).send("An internal server error occurred.");
61
+ }
62
+ }
63
+ }
64
+
65
+ export { ApiExpressDefaultEndpointAdapter };
@@ -0,0 +1,28 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import type { ApiEndpoint } from "@prosopo/api-route";
16
+ import type { NextFunction, Request, Response } from "express";
17
+ import type { ZodType } from "zod";
18
+
19
+ interface ApiExpressEndpointAdapter {
20
+ handleRequest(
21
+ endpoint: ApiEndpoint<ZodType | undefined>,
22
+ request: Request,
23
+ response: Response,
24
+ next: NextFunction,
25
+ ): Promise<void>;
26
+ }
27
+
28
+ export type { ApiExpressEndpointAdapter };
@@ -0,0 +1,33 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // We need the unused params to make express recognise this function as an error handler
16
+
17
+ import { type ProsopoApiError, unwrapError } from "@prosopo/common";
18
+ import type { NextFunction, Request, Response } from "express";
19
+ import type { ZodError } from "zod";
20
+
21
+ export const handleErrors = (
22
+ err: ProsopoApiError | SyntaxError | ZodError,
23
+ request: Request,
24
+ response: Response,
25
+ next: NextFunction,
26
+ ) => {
27
+ const { code, statusMessage, jsonError } = unwrapError(err, request.i18n);
28
+ response.statusMessage = statusMessage;
29
+ response.set("content-type", "application/json");
30
+ response.status(code);
31
+ response.send({ error: jsonError });
32
+ response.end();
33
+ };
package/src/index.ts ADDED
@@ -0,0 +1,37 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import type { LogLevel } from "@prosopo/logger";
16
+ import { ApiExpressRouterFactory } from "./apiExpressRouterFactory.js";
17
+ import { ApiExpressDefaultEndpointAdapter } from "./endpointAdapter/apiExpressDefaultEndpointAdapter.js";
18
+ import type { ApiExpressEndpointAdapter } from "./endpointAdapter/apiExpressEndpointAdapter.js";
19
+
20
+ const apiExpressRouterFactory = new ApiExpressRouterFactory();
21
+
22
+ const createApiExpressDefaultEndpointAdapter = (
23
+ logLevel: LogLevel,
24
+ errorStatusCode = 500,
25
+ ): ApiExpressEndpointAdapter => {
26
+ return new ApiExpressDefaultEndpointAdapter(logLevel, errorStatusCode);
27
+ };
28
+
29
+ export {
30
+ apiExpressRouterFactory,
31
+ createApiExpressDefaultEndpointAdapter,
32
+ type ApiExpressEndpointAdapter,
33
+ };
34
+
35
+ export * from "./errorHandler.js";
36
+ export * from "./middlewares/authMiddleware.js";
37
+ export * from "./middlewares/requestLoggerMiddleware.js";
@@ -0,0 +1,93 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import { hexToU8a } from "@polkadot/util";
16
+ import { ProsopoApiError, ProsopoEnvError } from "@prosopo/common";
17
+ import type { KeyringPair } from "@prosopo/types";
18
+ import type { JWT } from "@prosopo/util-crypto";
19
+ import type { NextFunction, Request, Response } from "express";
20
+
21
+ export const authMiddleware = (
22
+ pair: KeyringPair | undefined,
23
+ authAccount?: KeyringPair | undefined,
24
+ ) => {
25
+ return async (req: Request, res: Response, next: NextFunction) => {
26
+ try {
27
+ const jwt = extractJWT(req);
28
+
29
+ let error: ProsopoApiError | undefined;
30
+
31
+ if (authAccount?.jwtVerify(jwt).isValid) {
32
+ next();
33
+ return;
34
+ }
35
+
36
+ if (pair?.jwtVerify(jwt).isValid) {
37
+ next();
38
+ return;
39
+ }
40
+
41
+ res.status(401).json({
42
+ error: new ProsopoEnvError(error || "API.UNAUTHORIZED", {
43
+ context: { i18n: req.i18n, code: 401 },
44
+ }),
45
+ });
46
+ return;
47
+ } catch (err) {
48
+ req.logger.error(() => ({ err, msg: "Auth Middleware Error" }));
49
+ res.status(401).json({ error: "Unauthorized", message: err });
50
+ return;
51
+ }
52
+ };
53
+ };
54
+
55
+ const extractJWT = (req: Request) => {
56
+ const authHeader = req.headers.Authorization || req.headers.authorization;
57
+
58
+ if (!authHeader || typeof authHeader !== "string") {
59
+ throw new ProsopoApiError("GENERAL.MISSING_AUTH_HEADER", {
60
+ context: { error: "Missing Authorization header", code: 401 },
61
+ });
62
+ }
63
+
64
+ const jwt = authHeader.replace("Bearer ", "");
65
+
66
+ if (!jwt) {
67
+ throw new ProsopoApiError("GENERAL.INVALID_JWT", {
68
+ context: { error: "Missing JWT", code: 400 },
69
+ });
70
+ }
71
+
72
+ return jwt as JWT;
73
+ };
74
+
75
+ export const verifySignature = (
76
+ signature: string,
77
+ message: string,
78
+ pair: KeyringPair,
79
+ ) => {
80
+ const u8Sig = hexToU8a(signature);
81
+
82
+ if (!pair.verify(message, u8Sig, pair.publicKey)) {
83
+ throw new ProsopoApiError("GENERAL.INVALID_SIGNATURE", {
84
+ context: {
85
+ error: "Signature verification failed",
86
+ code: 401,
87
+ account: pair.address,
88
+ message,
89
+ signature,
90
+ },
91
+ });
92
+ }
93
+ };
@@ -0,0 +1,55 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import type { ProviderEnvironment } from "@prosopo/env";
16
+ import { getLogger, parseLogLevel } from "@prosopo/logger";
17
+ import type { NextFunction, Request, Response } from "express";
18
+ import { v4 as uuidv4 } from "uuid";
19
+
20
+ const getHeaderValue = (
21
+ req: Request,
22
+ headerName: string,
23
+ ): string | undefined => {
24
+ if (headerName in req.headers && req.headers[headerName]) {
25
+ return req.headers[headerName].toString();
26
+ }
27
+ return undefined;
28
+ };
29
+
30
+ export function requestLoggerMiddleware(env: ProviderEnvironment) {
31
+ return (req: Request, res: Response, next: NextFunction) => {
32
+ const requestId =
33
+ (req.headers["x-request-id"] as string) || `e-${uuidv4()}`; // use prefix to differentiate from other IDs
34
+ const user = getHeaderValue(req, "prosopo-user");
35
+ const siteKey = getHeaderValue(req, "prosopo-site-key");
36
+ const sessionId = req.body?.sessionId ? req.body.sessionId : null;
37
+
38
+ const logger = getLogger(
39
+ parseLogLevel(env.config.logLevel),
40
+ "request-logger",
41
+ ).with({
42
+ requestId,
43
+ ...(user ? { user } : {}),
44
+ ...(siteKey ? { siteKey } : {}),
45
+ ...(sessionId ? { sessionId } : {}),
46
+ });
47
+
48
+ // Attach logger to the request
49
+ req.logger = logger;
50
+ req.requestId = requestId;
51
+
52
+ // Continue to next middleware
53
+ next();
54
+ };
55
+ }
@@ -0,0 +1,190 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import { ProsopoApiError, ProsopoEnvError } from "@prosopo/common";
16
+ import { loadI18next } from "@prosopo/locale";
17
+ import type { NextFunction, Request, Response } from "express";
18
+ import { describe, expect, it, vi } from "vitest";
19
+ import { ZodError } from "zod";
20
+ import { handleErrors } from "../../errorHandler.js";
21
+
22
+ describe("handleErrors", async () => {
23
+ const i18n = await loadI18next(true);
24
+ await i18n.changeLanguage("en");
25
+
26
+ it("should handle ProsopoApiError", async () => {
27
+ const mockRequest = { i18n } as unknown as Request;
28
+ const mockResponse = {
29
+ writeHead: vi.fn().mockReturnThis(),
30
+ set: vi.fn().mockReturnThis(),
31
+ status: vi.fn().mockReturnThis(),
32
+ send: vi.fn(),
33
+ end: vi.fn(),
34
+ } as unknown as Response;
35
+ const mockNext = vi.fn() as unknown as NextFunction;
36
+
37
+ const error = new ProsopoApiError("CONTRACT.INVALID_DATA_FORMAT", {
38
+ context: { code: 400 },
39
+ i18n,
40
+ });
41
+ console.log(error);
42
+
43
+ handleErrors(error, mockRequest, mockResponse, mockNext);
44
+
45
+ expect(mockResponse.set).toHaveBeenCalledWith(
46
+ "content-type",
47
+ "application/json",
48
+ );
49
+ expect(mockResponse.send).toHaveBeenCalledWith({
50
+ error: {
51
+ code: 400,
52
+ key: "CONTRACT.INVALID_DATA_FORMAT",
53
+ message: "Invalid data format",
54
+ },
55
+ });
56
+ expect(mockResponse.status).toHaveBeenCalledWith(400);
57
+ expect(mockResponse.end).toHaveBeenCalled();
58
+ });
59
+
60
+ it("should not return SyntaxError", async () => {
61
+ const mockRequest = { i18n } as unknown as Request;
62
+ const mockResponse = {
63
+ writeHead: vi.fn().mockReturnThis(),
64
+ set: vi.fn().mockReturnThis(),
65
+ status: vi.fn().mockReturnThis(),
66
+ send: vi.fn(),
67
+ end: vi.fn(),
68
+ } as unknown as Response;
69
+ const mockNext = vi.fn() as unknown as NextFunction;
70
+
71
+ const message = "Unknown API error";
72
+ const error = new SyntaxError(message);
73
+
74
+ handleErrors(error, mockRequest, mockResponse, mockNext);
75
+
76
+ expect(mockResponse.set).toHaveBeenCalledWith(
77
+ "content-type",
78
+ "application/json",
79
+ );
80
+ expect(mockResponse.status).toHaveBeenCalledWith(400);
81
+ expect(mockResponse.send).toHaveBeenCalledWith({
82
+ error: {
83
+ message,
84
+ key: "API.UNKNOWN",
85
+ code: 400,
86
+ },
87
+ });
88
+ expect(mockResponse.end).toHaveBeenCalled();
89
+ });
90
+
91
+ it("should handle ZodError", () => {
92
+ const mockRequest = { i18n } as unknown as Request;
93
+ const mockResponse = {
94
+ writeHead: vi.fn().mockReturnThis(),
95
+ set: vi.fn().mockReturnThis(),
96
+ status: vi.fn().mockReturnThis(),
97
+ send: vi.fn(),
98
+ end: vi.fn(),
99
+ } as unknown as Response;
100
+ const mockNext = vi.fn() as unknown as NextFunction;
101
+
102
+ const zodError = {
103
+ code: "custom" as const,
104
+ message: "Invalid input",
105
+ path: ["some", "variable"],
106
+ };
107
+ const error = new ZodError([zodError]);
108
+
109
+ handleErrors(error, mockRequest, mockResponse, mockNext);
110
+
111
+ expect(mockResponse.set).toHaveBeenCalledWith(
112
+ "content-type",
113
+ "application/json",
114
+ );
115
+ expect(mockResponse.status).toHaveBeenCalledWith(400);
116
+ expect(mockResponse.send).toHaveBeenCalledWith({
117
+ error: { code: 400, key: "API.INVALID_BODY", message: [zodError] },
118
+ });
119
+ expect(mockResponse.end).toHaveBeenCalled();
120
+ });
121
+
122
+ it("should unwrap nested ProsopoBaseError", async () => {
123
+ const mockRequest = { i18n } as unknown as Request;
124
+ const mockResponse = {
125
+ writeHead: vi.fn().mockReturnThis(),
126
+ set: vi.fn().mockReturnThis(),
127
+ status: vi.fn().mockReturnThis(),
128
+ send: vi.fn(),
129
+ end: vi.fn(),
130
+ } as unknown as Response;
131
+ const mockNext = vi.fn() as unknown as NextFunction;
132
+
133
+ const envError = new ProsopoEnvError("GENERAL.ENVIRONMENT_NOT_READY", {
134
+ i18n,
135
+ });
136
+ const apiError = new ProsopoApiError(envError);
137
+
138
+ handleErrors(apiError, mockRequest, mockResponse, mockNext);
139
+
140
+ expect(mockResponse.set).toHaveBeenCalledWith(
141
+ "content-type",
142
+ "application/json",
143
+ );
144
+ expect(mockResponse.status).toHaveBeenCalledWith(500);
145
+ expect(mockResponse.send).toHaveBeenCalledWith({
146
+ error: {
147
+ code: 500,
148
+ key: "GENERAL.ENVIRONMENT_NOT_READY",
149
+ message: "Environment not ready",
150
+ },
151
+ });
152
+ expect(mockResponse.end).toHaveBeenCalled();
153
+ });
154
+
155
+ it("should unwrap nested ProsopoBaseErrors but not an Error that is nested inside them", async () => {
156
+ const mockRequest = { i18n } as unknown as Request;
157
+ const mockResponse = {
158
+ writeHead: vi.fn().mockReturnThis(),
159
+ set: vi.fn().mockReturnThis(),
160
+ status: vi.fn().mockReturnThis(),
161
+ send: vi.fn(),
162
+ end: vi.fn(),
163
+ } as unknown as Response;
164
+ const mockNext = vi.fn() as unknown as NextFunction;
165
+ const code = 400;
166
+ const key = "API.UNKNOWN";
167
+
168
+ const error = new Error("Some error");
169
+ const apiError = new ProsopoApiError(key, {
170
+ context: { code, error },
171
+ i18n,
172
+ });
173
+
174
+ handleErrors(apiError, mockRequest, mockResponse, mockNext);
175
+
176
+ expect(mockResponse.set).toHaveBeenCalledWith(
177
+ "content-type",
178
+ "application/json",
179
+ );
180
+ expect(mockResponse.status).toHaveBeenCalledWith(code);
181
+ expect(mockResponse.send).toHaveBeenCalledWith({
182
+ error: {
183
+ code,
184
+ key,
185
+ message: "Unknown API error",
186
+ },
187
+ });
188
+ expect(mockResponse.end).toHaveBeenCalled();
189
+ });
190
+ });