@prosopo/api-express-router 2.6.1 → 3.0.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/CHANGELOG.md +67 -0
- package/dist/apiExpressRouterFactory.js +24 -15
- package/dist/cjs/endpointAdapter/apiExpressDefaultEndpointAdapter.cjs +3 -1
- package/dist/cjs/index.cjs +5 -0
- package/dist/cjs/middlewares/authMiddleware.cjs +84 -0
- package/dist/cjs/middlewares/requestLoggerMiddleware.cjs +19 -0
- package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js +29 -23
- package/dist/errorHandler.js +10 -8
- package/dist/index.js +12 -4
- package/dist/middlewares/authMiddleware.js +84 -0
- package/dist/middlewares/requestLoggerMiddleware.js +19 -0
- package/package.json +15 -11
- package/vite.cjs.config.ts +5 -3
- package/vite.esm.config.ts +20 -0
- package/vite.test.config.ts +3 -4
- package/dist/apiExpressRouterFactory.d.ts +0 -9
- package/dist/apiExpressRouterFactory.d.ts.map +0 -1
- package/dist/apiExpressRouterFactory.js.map +0 -1
- package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.d.ts +0 -13
- package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.d.ts.map +0 -1
- package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js.map +0 -1
- package/dist/endpointAdapter/apiExpressEndpointAdapter.d.ts +0 -8
- package/dist/endpointAdapter/apiExpressEndpointAdapter.d.ts.map +0 -1
- package/dist/endpointAdapter/apiExpressEndpointAdapter.js +0 -2
- package/dist/endpointAdapter/apiExpressEndpointAdapter.js.map +0 -1
- package/dist/errorHandler.d.ts +0 -5
- package/dist/errorHandler.d.ts.map +0 -1
- package/dist/errorHandler.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/tests/unit/errorHandler.unit.test.d.ts +0 -2
- package/dist/tests/unit/errorHandler.unit.test.d.ts.map +0 -1
- package/dist/tests/unit/errorHandler.unit.test.js +0 -140
- package/dist/tests/unit/errorHandler.unit.test.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,72 @@
|
|
|
1
1
|
# @prosopo/api-express-router
|
|
2
2
|
|
|
3
|
+
## 3.0.4
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
- 3573f0b: fix npm scripts bundle command
|
|
7
|
+
- 3573f0b: build using vite, typecheck using tsc
|
|
8
|
+
- efd8102: Add tests for unwrap error helper
|
|
9
|
+
- f29fc7e: Refining API error handling. Adding more language strings
|
|
10
|
+
- 3573f0b: standardise all vite based npm scripts for bundling
|
|
11
|
+
- Updated dependencies [3573f0b]
|
|
12
|
+
- Updated dependencies [3573f0b]
|
|
13
|
+
- Updated dependencies [efd8102]
|
|
14
|
+
- Updated dependencies [f29fc7e]
|
|
15
|
+
- Updated dependencies [3573f0b]
|
|
16
|
+
- Updated dependencies [2d0dd8a]
|
|
17
|
+
- @prosopo/api-route@2.6.8
|
|
18
|
+
- @prosopo/common@3.1.0
|
|
19
|
+
- @prosopo/config@3.1.1
|
|
20
|
+
|
|
21
|
+
## 3.0.3
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- 9671152: uuid
|
|
25
|
+
|
|
26
|
+
## 3.0.2
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- @prosopo/common@3.0.2
|
|
30
|
+
- @prosopo/api-route@2.6.7
|
|
31
|
+
|
|
32
|
+
## 3.0.1
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- @prosopo/common@3.0.1
|
|
36
|
+
- @prosopo/api-route@2.6.6
|
|
37
|
+
|
|
38
|
+
## 3.0.0
|
|
39
|
+
### Major Changes
|
|
40
|
+
|
|
41
|
+
- 64b5bcd: Access Controls
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- Updated dependencies [64b5bcd]
|
|
46
|
+
- @prosopo/common@3.0.0
|
|
47
|
+
- @prosopo/api-route@2.6.5
|
|
48
|
+
|
|
49
|
+
## 2.6.4
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- 86c22b8: structured logging
|
|
53
|
+
- Updated dependencies [86c22b8]
|
|
54
|
+
- @prosopo/api-route@2.6.4
|
|
55
|
+
- @prosopo/common@2.7.2
|
|
56
|
+
|
|
57
|
+
## 2.6.3
|
|
58
|
+
### Patch Changes
|
|
59
|
+
|
|
60
|
+
- @prosopo/common@2.7.1
|
|
61
|
+
- @prosopo/api-route@2.6.3
|
|
62
|
+
|
|
63
|
+
## 2.6.2
|
|
64
|
+
### Patch Changes
|
|
65
|
+
|
|
66
|
+
- Updated dependencies [8f0644a]
|
|
67
|
+
- @prosopo/common@2.7.0
|
|
68
|
+
- @prosopo/api-route@2.6.2
|
|
69
|
+
|
|
3
70
|
## 2.6.1
|
|
4
71
|
|
|
5
72
|
### Patch Changes
|
|
@@ -1,20 +1,29 @@
|
|
|
1
|
-
import { Router
|
|
1
|
+
import { Router } from "express";
|
|
2
2
|
import { handleErrors } from "./errorHandler.js";
|
|
3
3
|
class ApiExpressRouterFactory {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
createRouter(routersProvider, apiEndpointAdapter) {
|
|
5
|
+
const router = Router();
|
|
6
|
+
const apiRoutes = routersProvider.getRoutes();
|
|
7
|
+
this.registerRoutes(router, apiRoutes, apiEndpointAdapter);
|
|
8
|
+
router.use(handleErrors);
|
|
9
|
+
return router;
|
|
10
|
+
}
|
|
11
|
+
registerRoutes(router, routes, apiEndpointAdapter) {
|
|
12
|
+
for (const route of routes) {
|
|
13
|
+
router.post(
|
|
14
|
+
route.path,
|
|
15
|
+
async (request, response, next) => {
|
|
16
|
+
return await apiEndpointAdapter.handleRequest(
|
|
17
|
+
route.endpoint,
|
|
18
|
+
request,
|
|
19
|
+
response,
|
|
20
|
+
next
|
|
21
|
+
);
|
|
16
22
|
}
|
|
23
|
+
);
|
|
17
24
|
}
|
|
25
|
+
}
|
|
18
26
|
}
|
|
19
|
-
export {
|
|
20
|
-
|
|
27
|
+
export {
|
|
28
|
+
ApiExpressRouterFactory
|
|
29
|
+
};
|
|
@@ -24,7 +24,9 @@ class ApiExpressDefaultEndpointAdapter {
|
|
|
24
24
|
);
|
|
25
25
|
response.json(apiEndpointResponse);
|
|
26
26
|
} catch (error) {
|
|
27
|
-
request.logger.error(
|
|
27
|
+
request.logger.error(() => ({
|
|
28
|
+
err: error
|
|
29
|
+
}));
|
|
28
30
|
response.status(500).send("An internal server error occurred.");
|
|
29
31
|
}
|
|
30
32
|
}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -3,10 +3,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const apiExpressRouterFactory$1 = require("./apiExpressRouterFactory.cjs");
|
|
4
4
|
const apiExpressDefaultEndpointAdapter = require("./endpointAdapter/apiExpressDefaultEndpointAdapter.cjs");
|
|
5
5
|
const errorHandler = require("./errorHandler.cjs");
|
|
6
|
+
const authMiddleware = require("./middlewares/authMiddleware.cjs");
|
|
7
|
+
const requestLoggerMiddleware = require("./middlewares/requestLoggerMiddleware.cjs");
|
|
6
8
|
const apiExpressRouterFactory = new apiExpressRouterFactory$1.ApiExpressRouterFactory();
|
|
7
9
|
const createApiExpressDefaultEndpointAdapter = (logLevel, errorStatusCode = 500) => {
|
|
8
10
|
return new apiExpressDefaultEndpointAdapter.ApiExpressDefaultEndpointAdapter(logLevel, errorStatusCode);
|
|
9
11
|
};
|
|
10
12
|
exports.handleErrors = errorHandler.handleErrors;
|
|
13
|
+
exports.authMiddleware = authMiddleware.authMiddleware;
|
|
14
|
+
exports.verifySignature = authMiddleware.verifySignature;
|
|
15
|
+
exports.requestLoggerMiddleware = requestLoggerMiddleware.requestLoggerMiddleware;
|
|
11
16
|
exports.apiExpressRouterFactory = apiExpressRouterFactory;
|
|
12
17
|
exports.createApiExpressDefaultEndpointAdapter = createApiExpressDefaultEndpointAdapter;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const util = require("@polkadot/util");
|
|
4
|
+
const common = require("@prosopo/common");
|
|
5
|
+
const authMiddleware = (pair, authAccount) => {
|
|
6
|
+
return async (req, res, next) => {
|
|
7
|
+
try {
|
|
8
|
+
const { signature, timestamp } = extractHeaders(req);
|
|
9
|
+
let error;
|
|
10
|
+
if (authAccount) {
|
|
11
|
+
try {
|
|
12
|
+
verifySignature(signature, timestamp, authAccount);
|
|
13
|
+
next();
|
|
14
|
+
return;
|
|
15
|
+
} catch (e) {
|
|
16
|
+
req.logger.warn(() => ({
|
|
17
|
+
err: e,
|
|
18
|
+
data: {
|
|
19
|
+
account: authAccount?.address
|
|
20
|
+
}
|
|
21
|
+
}));
|
|
22
|
+
error = e;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (pair) {
|
|
26
|
+
verifySignature(signature, timestamp, pair);
|
|
27
|
+
next();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
res.status(401).json({
|
|
31
|
+
error: "Unauthorized",
|
|
32
|
+
message: new common.ProsopoEnvError(error || "CONTRACT.CANNOT_FIND_KEYPAIR")
|
|
33
|
+
});
|
|
34
|
+
return;
|
|
35
|
+
} catch (err) {
|
|
36
|
+
req.logger.error(() => ({ err, msg: "Auth Middleware Error" }));
|
|
37
|
+
res.status(401).json({ error: "Unauthorized", message: err });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const extractHeaders = (req) => {
|
|
43
|
+
const signature = req.headers.signature;
|
|
44
|
+
const timestamp = req.headers.timestamp;
|
|
45
|
+
if (!timestamp) {
|
|
46
|
+
throw new common.ProsopoApiError("GENERAL.INVALID_TIMESTAMP", {
|
|
47
|
+
context: { error: "Missing timestamp", code: 400 }
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (!signature) {
|
|
51
|
+
throw new common.ProsopoApiError("GENERAL.INVALID_SIGNATURE", {
|
|
52
|
+
context: { error: "Missing signature", code: 400 }
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(signature) || Array.isArray(timestamp) || !util.isHex(signature)) {
|
|
56
|
+
throw new common.ProsopoApiError("CONTRACT.INVALID_DATA_FORMAT", {
|
|
57
|
+
context: { error: "Invalid header format", code: 400 }
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
61
|
+
const ts = Number.parseInt(timestamp);
|
|
62
|
+
if (now - ts > 3e5) {
|
|
63
|
+
throw new common.ProsopoApiError("GENERAL.INVALID_TIMESTAMP", {
|
|
64
|
+
context: { error: "Timestamp is too old", code: 400 }
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return { signature, timestamp };
|
|
68
|
+
};
|
|
69
|
+
const verifySignature = (signature, message, pair) => {
|
|
70
|
+
const u8Sig = util.hexToU8a(signature);
|
|
71
|
+
if (!pair.verify(message, u8Sig, pair.publicKey)) {
|
|
72
|
+
throw new common.ProsopoApiError("GENERAL.INVALID_SIGNATURE", {
|
|
73
|
+
context: {
|
|
74
|
+
error: "Signature verification failed",
|
|
75
|
+
code: 401,
|
|
76
|
+
account: pair.address,
|
|
77
|
+
message,
|
|
78
|
+
signature
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
exports.authMiddleware = authMiddleware;
|
|
84
|
+
exports.verifySignature = verifySignature;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const common = require("@prosopo/common");
|
|
4
|
+
const uuid = require("uuid");
|
|
5
|
+
function requestLoggerMiddleware(env) {
|
|
6
|
+
return (req, res, next) => {
|
|
7
|
+
const requestId = req.headers["x-request-id"] || `e-${uuid.v4()}`;
|
|
8
|
+
const logger = common.getLogger(
|
|
9
|
+
common.parseLogLevel(env.config.logLevel),
|
|
10
|
+
"request-logger"
|
|
11
|
+
).with({
|
|
12
|
+
requestId
|
|
13
|
+
});
|
|
14
|
+
req.logger = logger;
|
|
15
|
+
req.requestId = requestId;
|
|
16
|
+
next();
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
exports.requestLoggerMiddleware = requestLoggerMiddleware;
|
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
import { ProsopoApiError } from "@prosopo/common";
|
|
2
2
|
class ApiExpressDefaultEndpointAdapter {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
constructor(logLevel, errorStatusCode) {
|
|
4
|
+
this.logLevel = logLevel;
|
|
5
|
+
this.errorStatusCode = errorStatusCode;
|
|
6
|
+
}
|
|
7
|
+
async handleRequest(endpoint, request, response, next) {
|
|
8
|
+
let args;
|
|
9
|
+
try {
|
|
10
|
+
args = endpoint.getRequestArgsSchema()?.parse(request.body);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
return next(
|
|
13
|
+
new ProsopoApiError("API.PARSE_ERROR", {
|
|
14
|
+
context: { code: 400, error }
|
|
15
|
+
})
|
|
16
|
+
);
|
|
6
17
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const apiEndpointResponse = await endpoint.processRequest(args, request.logger);
|
|
19
|
-
response.json(apiEndpointResponse);
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
request.logger.error(error.message);
|
|
23
|
-
response.status(500).send("An internal server error occurred.");
|
|
24
|
-
}
|
|
18
|
+
try {
|
|
19
|
+
const apiEndpointResponse = await endpoint.processRequest(
|
|
20
|
+
args,
|
|
21
|
+
request.logger
|
|
22
|
+
);
|
|
23
|
+
response.json(apiEndpointResponse);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
request.logger.error(() => ({
|
|
26
|
+
err: error
|
|
27
|
+
}));
|
|
28
|
+
response.status(500).send("An internal server error occurred.");
|
|
25
29
|
}
|
|
30
|
+
}
|
|
26
31
|
}
|
|
27
|
-
export {
|
|
28
|
-
|
|
32
|
+
export {
|
|
33
|
+
ApiExpressDefaultEndpointAdapter
|
|
34
|
+
};
|
package/dist/errorHandler.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { unwrapError } from "@prosopo/common";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
const handleErrors = (err, request, response, next) => {
|
|
3
|
+
const { code, statusMessage, jsonError } = unwrapError(err, request.i18n);
|
|
4
|
+
response.statusMessage = statusMessage;
|
|
5
|
+
response.set("content-type", "application/json");
|
|
6
|
+
response.status(code);
|
|
7
|
+
response.send({ error: jsonError });
|
|
8
|
+
response.end();
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
handleErrors
|
|
9
12
|
};
|
|
10
|
-
//# sourceMappingURL=errorHandler.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { ApiExpressRouterFactory } from "./apiExpressRouterFactory.js";
|
|
2
2
|
import { ApiExpressDefaultEndpointAdapter } from "./endpointAdapter/apiExpressDefaultEndpointAdapter.js";
|
|
3
|
+
import { handleErrors } from "./errorHandler.js";
|
|
4
|
+
import { authMiddleware, verifySignature } from "./middlewares/authMiddleware.js";
|
|
5
|
+
import { requestLoggerMiddleware } from "./middlewares/requestLoggerMiddleware.js";
|
|
3
6
|
const apiExpressRouterFactory = new ApiExpressRouterFactory();
|
|
4
7
|
const createApiExpressDefaultEndpointAdapter = (logLevel, errorStatusCode = 500) => {
|
|
5
|
-
|
|
8
|
+
return new ApiExpressDefaultEndpointAdapter(logLevel, errorStatusCode);
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
apiExpressRouterFactory,
|
|
12
|
+
authMiddleware,
|
|
13
|
+
createApiExpressDefaultEndpointAdapter,
|
|
14
|
+
handleErrors,
|
|
15
|
+
requestLoggerMiddleware,
|
|
16
|
+
verifySignature
|
|
6
17
|
};
|
|
7
|
-
export { apiExpressRouterFactory, createApiExpressDefaultEndpointAdapter, };
|
|
8
|
-
export * from "./errorHandler.js";
|
|
9
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { isHex, hexToU8a } from "@polkadot/util";
|
|
2
|
+
import { ProsopoEnvError, ProsopoApiError } from "@prosopo/common";
|
|
3
|
+
const authMiddleware = (pair, authAccount) => {
|
|
4
|
+
return async (req, res, next) => {
|
|
5
|
+
try {
|
|
6
|
+
const { signature, timestamp } = extractHeaders(req);
|
|
7
|
+
let error;
|
|
8
|
+
if (authAccount) {
|
|
9
|
+
try {
|
|
10
|
+
verifySignature(signature, timestamp, authAccount);
|
|
11
|
+
next();
|
|
12
|
+
return;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
req.logger.warn(() => ({
|
|
15
|
+
err: e,
|
|
16
|
+
data: {
|
|
17
|
+
account: authAccount?.address
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
error = e;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (pair) {
|
|
24
|
+
verifySignature(signature, timestamp, pair);
|
|
25
|
+
next();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
res.status(401).json({
|
|
29
|
+
error: "Unauthorized",
|
|
30
|
+
message: new ProsopoEnvError(error || "CONTRACT.CANNOT_FIND_KEYPAIR")
|
|
31
|
+
});
|
|
32
|
+
return;
|
|
33
|
+
} catch (err) {
|
|
34
|
+
req.logger.error(() => ({ err, msg: "Auth Middleware Error" }));
|
|
35
|
+
res.status(401).json({ error: "Unauthorized", message: err });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const extractHeaders = (req) => {
|
|
41
|
+
const signature = req.headers.signature;
|
|
42
|
+
const timestamp = req.headers.timestamp;
|
|
43
|
+
if (!timestamp) {
|
|
44
|
+
throw new ProsopoApiError("GENERAL.INVALID_TIMESTAMP", {
|
|
45
|
+
context: { error: "Missing timestamp", code: 400 }
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (!signature) {
|
|
49
|
+
throw new ProsopoApiError("GENERAL.INVALID_SIGNATURE", {
|
|
50
|
+
context: { error: "Missing signature", code: 400 }
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(signature) || Array.isArray(timestamp) || !isHex(signature)) {
|
|
54
|
+
throw new ProsopoApiError("CONTRACT.INVALID_DATA_FORMAT", {
|
|
55
|
+
context: { error: "Invalid header format", code: 400 }
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
59
|
+
const ts = Number.parseInt(timestamp);
|
|
60
|
+
if (now - ts > 3e5) {
|
|
61
|
+
throw new ProsopoApiError("GENERAL.INVALID_TIMESTAMP", {
|
|
62
|
+
context: { error: "Timestamp is too old", code: 400 }
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return { signature, timestamp };
|
|
66
|
+
};
|
|
67
|
+
const verifySignature = (signature, message, pair) => {
|
|
68
|
+
const u8Sig = hexToU8a(signature);
|
|
69
|
+
if (!pair.verify(message, u8Sig, pair.publicKey)) {
|
|
70
|
+
throw new ProsopoApiError("GENERAL.INVALID_SIGNATURE", {
|
|
71
|
+
context: {
|
|
72
|
+
error: "Signature verification failed",
|
|
73
|
+
code: 401,
|
|
74
|
+
account: pair.address,
|
|
75
|
+
message,
|
|
76
|
+
signature
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
export {
|
|
82
|
+
authMiddleware,
|
|
83
|
+
verifySignature
|
|
84
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getLogger, parseLogLevel } from "@prosopo/common";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
function requestLoggerMiddleware(env) {
|
|
4
|
+
return (req, res, next) => {
|
|
5
|
+
const requestId = req.headers["x-request-id"] || `e-${v4()}`;
|
|
6
|
+
const logger = getLogger(
|
|
7
|
+
parseLogLevel(env.config.logLevel),
|
|
8
|
+
"request-logger"
|
|
9
|
+
).with({
|
|
10
|
+
requestId
|
|
11
|
+
});
|
|
12
|
+
req.logger = logger;
|
|
13
|
+
req.requestId = requestId;
|
|
14
|
+
next();
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
requestLoggerMiddleware
|
|
19
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prosopo/api-express-router",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.4",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"engines": {
|
|
7
8
|
"node": "20",
|
|
@@ -9,24 +10,27 @@
|
|
|
9
10
|
},
|
|
10
11
|
"exports": {
|
|
11
12
|
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
12
14
|
"import": "./dist/index.js",
|
|
13
15
|
"require": "./dist/cjs/index.cjs"
|
|
14
16
|
}
|
|
15
17
|
},
|
|
16
18
|
"scripts": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"build": "tsc --build --verbose",
|
|
20
|
-
"build:cjs": "
|
|
19
|
+
"clean": "del-cli --verbose dist tsconfig.tsbuildinfo",
|
|
20
|
+
"build": "NODE_ENV=${NODE_ENV:-production}; vite build --config vite.esm.config.ts --mode $NODE_ENV",
|
|
21
|
+
"build:tsc": "tsc --build --verbose",
|
|
22
|
+
"build:cjs": "NODE_ENV=${NODE_ENV:-production}; vite build --config vite.cjs.config.ts --mode $NODE_ENV",
|
|
23
|
+
"typecheck": "tsc --build --declaration --emitDeclarationOnly",
|
|
24
|
+
"test": "NODE_ENV=${NODE_ENV:-test}; npx vitest run --config ./vite.test.config.ts"
|
|
21
25
|
},
|
|
22
26
|
"dependencies": {
|
|
23
|
-
"@prosopo/api-route": "2.6.
|
|
24
|
-
"@prosopo/common": "
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"@prosopo/config": "2.6.0"
|
|
27
|
+
"@prosopo/api-route": "2.6.8",
|
|
28
|
+
"@prosopo/common": "3.1.0",
|
|
29
|
+
"uuid": "11.1.0",
|
|
30
|
+
"zod": "3.23.8",
|
|
31
|
+
"@prosopo/config": "3.1.1"
|
|
29
32
|
},
|
|
33
|
+
"devDependencies": {},
|
|
30
34
|
"author": "PROSOPO LIMITED <info@prosopo.io>",
|
|
31
35
|
"license": "Apache-2.0",
|
|
32
36
|
"bugs": {
|
package/vite.cjs.config.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
// Copyright 2021-2025 Prosopo (UK) Ltd.
|
|
2
3
|
//
|
|
3
4
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -11,10 +12,11 @@
|
|
|
11
12
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
13
|
// See the License for the specific language governing permissions and
|
|
13
14
|
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
import path from "node:path";
|
|
16
15
|
import { ViteCommonJSConfig } from "@prosopo/config";
|
|
17
16
|
|
|
18
17
|
export default function () {
|
|
19
|
-
return ViteCommonJSConfig(
|
|
18
|
+
return ViteCommonJSConfig(
|
|
19
|
+
path.basename("."),
|
|
20
|
+
path.resolve("./tsconfig.json"),
|
|
21
|
+
);
|
|
20
22
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2021-2025 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 path from "node:path";
|
|
16
|
+
import { ViteEsmConfig } from "@prosopo/config";
|
|
17
|
+
|
|
18
|
+
export default function () {
|
|
19
|
+
return ViteEsmConfig(path.basename("."), path.resolve("./tsconfig.json"));
|
|
20
|
+
}
|
package/vite.test.config.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
1
3
|
// Copyright 2021-2025 Prosopo (UK) Ltd.
|
|
2
4
|
//
|
|
3
5
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -11,9 +13,6 @@
|
|
|
11
13
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
14
|
// See the License for the specific language governing permissions and
|
|
13
15
|
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
import fs from "node:fs";
|
|
16
|
-
import path from "node:path";
|
|
17
16
|
import { ViteTestConfig } from "@prosopo/config";
|
|
18
17
|
import dotenv from "dotenv";
|
|
19
18
|
process.env.NODE_ENV = "test";
|
|
@@ -30,4 +29,4 @@ if (fs.existsSync(envFile)) {
|
|
|
30
29
|
|
|
31
30
|
dotenv.config({ path: envPath });
|
|
32
31
|
|
|
33
|
-
export default ViteTestConfig;
|
|
32
|
+
export default ViteTestConfig();
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ApiRoute, ApiRoutesProvider } from "@prosopo/api-route";
|
|
2
|
-
import { Router } from "express";
|
|
3
|
-
import type { ApiExpressEndpointAdapter } from "./endpointAdapter/apiExpressEndpointAdapter.js";
|
|
4
|
-
declare class ApiExpressRouterFactory {
|
|
5
|
-
createRouter(routersProvider: ApiRoutesProvider, apiEndpointAdapter: ApiExpressEndpointAdapter): Router;
|
|
6
|
-
protected registerRoutes(router: Router, routes: ApiRoute[], apiEndpointAdapter: ApiExpressEndpointAdapter): void;
|
|
7
|
-
}
|
|
8
|
-
export { ApiExpressRouterFactory };
|
|
9
|
-
//# sourceMappingURL=apiExpressRouterFactory.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiExpressRouterFactory.d.ts","sourceRoot":"","sources":["../src/apiExpressRouterFactory.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAIN,MAAM,EACN,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAGhG,cAAM,uBAAuB;IACrB,YAAY,CAClB,eAAe,EAAE,iBAAiB,EAClC,kBAAkB,EAAE,yBAAyB,GAC3C,MAAM;IAcT,SAAS,CAAC,cAAc,CACvB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,QAAQ,EAAE,EAClB,kBAAkB,EAAE,yBAAyB,GAC3C,IAAI;CAmBP;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiExpressRouterFactory.js","sourceRoot":"","sources":["../src/apiExpressRouterFactory.ts"],"names":[],"mappings":"AAeA,OAAO,EAIN,MAAM,GACN,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,uBAAuB;IACrB,YAAY,CAClB,eAAkC,EAClC,kBAA6C;QAE7C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,EAAE,CAAC;QAE9C,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;QAK3D,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEzB,OAAO,MAAM,CAAC;IACf,CAAC;IAES,cAAc,CACvB,MAAc,EACd,MAAkB,EAClB,kBAA6C;QAE7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CACV,KAAK,CAAC,IAAI,EACV,KAAK,EACJ,OAAgB,EAChB,QAAkB,EAClB,IAAkB,EACF,EAAE;gBAClB,OAAO,MAAM,kBAAkB,CAAC,aAAa,CAC5C,KAAK,CAAC,QAAQ,EACd,OAAO,EACP,QAAQ,EACR,IAAI,CACJ,CAAC;YACH,CAAC,CACD,CAAC;QACH,CAAC;IACF,CAAC;CACD;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ApiEndpoint } from "@prosopo/api-route";
|
|
2
|
-
import { type LogLevel } from "@prosopo/common";
|
|
3
|
-
import type { NextFunction, Request, Response } from "express";
|
|
4
|
-
import type { ZodType } from "zod";
|
|
5
|
-
import type { ApiExpressEndpointAdapter } from "./apiExpressEndpointAdapter.js";
|
|
6
|
-
declare class ApiExpressDefaultEndpointAdapter implements ApiExpressEndpointAdapter {
|
|
7
|
-
private readonly logLevel;
|
|
8
|
-
private readonly errorStatusCode;
|
|
9
|
-
constructor(logLevel: LogLevel, errorStatusCode: number);
|
|
10
|
-
handleRequest(endpoint: ApiEndpoint<ZodType | undefined>, request: Request, response: Response, next: NextFunction): Promise<void>;
|
|
11
|
-
}
|
|
12
|
-
export { ApiExpressDefaultEndpointAdapter };
|
|
13
|
-
//# sourceMappingURL=apiExpressDefaultEndpointAdapter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiExpressDefaultEndpointAdapter.d.ts","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,KAAK,QAAQ,EAAmB,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAEhF,cAAM,gCAAiC,YAAW,yBAAyB;IAEzE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;gBADf,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,MAAM;IAG5B,aAAa,CACzB,QAAQ,EAAE,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,EAC1C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC;CAyBhB;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiExpressDefaultEndpointAdapter.js","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts"],"names":[],"mappings":"AAeA,OAAO,EAAiB,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKjE,MAAM,gCAAgC;IACrC,YACkB,QAAkB,EAClB,eAAuB;QADvB,aAAQ,GAAR,QAAQ,CAAU;QAClB,oBAAe,GAAf,eAAe,CAAQ;IACtC,CAAC;IAEG,KAAK,CAAC,aAAa,CACzB,QAA0C,EAC1C,OAAgB,EAChB,QAAkB,EAClB,IAAkB;QAElB,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACJ,IAAI,GAAG,QAAQ,CAAC,oBAAoB,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,IAAI,CACV,IAAI,eAAe,CAAC,iBAAiB,EAAE;gBACtC,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE;aACpC,CAAC,CACF,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,mBAAmB,GAAG,MAAM,QAAQ,CAAC,cAAc,CACxD,IAAI,EACJ,OAAO,CAAC,MAAM,CACd,CAAC;YAEF,QAAQ,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC;YAE/C,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACjE,CAAC;IACF,CAAC;CACD;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ApiEndpoint } from "@prosopo/api-route";
|
|
2
|
-
import type { NextFunction, Request, Response } from "express";
|
|
3
|
-
import type { ZodType } from "zod";
|
|
4
|
-
interface ApiExpressEndpointAdapter {
|
|
5
|
-
handleRequest(endpoint: ApiEndpoint<ZodType | undefined>, request: Request, response: Response, next: NextFunction): Promise<void>;
|
|
6
|
-
}
|
|
7
|
-
export type { ApiExpressEndpointAdapter };
|
|
8
|
-
//# sourceMappingURL=apiExpressEndpointAdapter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiExpressEndpointAdapter.d.ts","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressEndpointAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,UAAU,yBAAyB;IAClC,aAAa,CACZ,QAAQ,EAAE,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,EAC1C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB;AAED,YAAY,EAAE,yBAAyB,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiExpressEndpointAdapter.js","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressEndpointAdapter.ts"],"names":[],"mappings":""}
|
package/dist/errorHandler.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type ProsopoApiError } from "@prosopo/common";
|
|
2
|
-
import type { NextFunction, Request, Response } from "express";
|
|
3
|
-
import type { ZodError } from "zod";
|
|
4
|
-
export declare const handleErrors: (err: ProsopoApiError | SyntaxError | ZodError, request: Request, response: Response, next: NextFunction) => void;
|
|
5
|
-
//# sourceMappingURL=errorHandler.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../src/errorHandler.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,eAAe,EAAe,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAEpC,eAAO,MAAM,YAAY,QACnB,eAAe,GAAG,WAAW,GAAG,QAAQ,WACpC,OAAO,YACN,QAAQ,QACZ,YAAY,SAQlB,CAAC"}
|
package/dist/errorHandler.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../src/errorHandler.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAwB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAIpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAC3B,GAA6C,EAC7C,OAAgB,EAChB,QAAkB,EAClB,IAAkB,EACjB,EAAE;IACH,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IACjD,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC,CAAC"}
|
package/dist/index.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { LogLevel } from "@prosopo/common";
|
|
2
|
-
import { ApiExpressRouterFactory } from "./apiExpressRouterFactory.js";
|
|
3
|
-
import type { ApiExpressEndpointAdapter } from "./endpointAdapter/apiExpressEndpointAdapter.js";
|
|
4
|
-
declare const apiExpressRouterFactory: ApiExpressRouterFactory;
|
|
5
|
-
declare const createApiExpressDefaultEndpointAdapter: (logLevel: LogLevel, errorStatusCode?: number) => ApiExpressEndpointAdapter;
|
|
6
|
-
export { apiExpressRouterFactory, createApiExpressDefaultEndpointAdapter, type ApiExpressEndpointAdapter, };
|
|
7
|
-
export * from "./errorHandler.js";
|
|
8
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAEhG,QAAA,MAAM,uBAAuB,yBAAgC,CAAC;AAE9D,QAAA,MAAM,sCAAsC,aACjC,QAAQ,+BAEhB,yBAEF,CAAC;AAEF,OAAO,EACN,uBAAuB,EACvB,sCAAsC,EACtC,KAAK,yBAAyB,GAC9B,CAAC;AAEF,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uDAAuD,CAAC;AAGzG,MAAM,uBAAuB,GAAG,IAAI,uBAAuB,EAAE,CAAC;AAE9D,MAAM,sCAAsC,GAAG,CAC9C,QAAkB,EAClB,eAAe,GAAG,GAAG,EACO,EAAE;IAC9B,OAAO,IAAI,gCAAgC,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,OAAO,EACN,uBAAuB,EACvB,sCAAsC,GAEtC,CAAC;AAEF,cAAc,mBAAmB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.unit.test.d.ts","sourceRoot":"","sources":["../../../src/tests/unit/errorHandler.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { ProsopoApiError, ProsopoEnvError } from "@prosopo/common";
|
|
2
|
-
import { loadI18next } from "@prosopo/locale";
|
|
3
|
-
import { describe, expect, it, vi } from "vitest";
|
|
4
|
-
import { ZodError } from "zod";
|
|
5
|
-
import { handleErrors } from "../../errorHandler.js";
|
|
6
|
-
describe("handleErrors", async () => {
|
|
7
|
-
const i18n = await loadI18next(true);
|
|
8
|
-
await i18n.changeLanguage("en");
|
|
9
|
-
it("should handle ProsopoApiError", async () => {
|
|
10
|
-
const mockRequest = { i18n };
|
|
11
|
-
const mockResponse = {
|
|
12
|
-
writeHead: vi.fn().mockReturnThis(),
|
|
13
|
-
set: vi.fn().mockReturnThis(),
|
|
14
|
-
status: vi.fn().mockReturnThis(),
|
|
15
|
-
send: vi.fn(),
|
|
16
|
-
end: vi.fn(),
|
|
17
|
-
};
|
|
18
|
-
const mockNext = vi.fn();
|
|
19
|
-
const error = new ProsopoApiError("CONTRACT.INVALID_DATA_FORMAT", {
|
|
20
|
-
context: { code: 400 },
|
|
21
|
-
i18n,
|
|
22
|
-
});
|
|
23
|
-
console.log(error);
|
|
24
|
-
handleErrors(error, mockRequest, mockResponse, mockNext);
|
|
25
|
-
expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
|
|
26
|
-
expect(mockResponse.send).toHaveBeenCalledWith({
|
|
27
|
-
error: {
|
|
28
|
-
code: 400,
|
|
29
|
-
key: "CONTRACT.INVALID_DATA_FORMAT",
|
|
30
|
-
message: "Invalid data format",
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
expect(mockResponse.status).toHaveBeenCalledWith(400);
|
|
34
|
-
expect(mockResponse.end).toHaveBeenCalled();
|
|
35
|
-
});
|
|
36
|
-
it("should handle SyntaxError", async () => {
|
|
37
|
-
const mockRequest = { i18n };
|
|
38
|
-
const mockResponse = {
|
|
39
|
-
writeHead: vi.fn().mockReturnThis(),
|
|
40
|
-
set: vi.fn().mockReturnThis(),
|
|
41
|
-
status: vi.fn().mockReturnThis(),
|
|
42
|
-
send: vi.fn(),
|
|
43
|
-
end: vi.fn(),
|
|
44
|
-
};
|
|
45
|
-
const mockNext = vi.fn();
|
|
46
|
-
const [len, max] = [100, 50];
|
|
47
|
-
const message = `Input length: ${len}, exceeds maximum allowed length: ${max}`;
|
|
48
|
-
const error = new SyntaxError(message);
|
|
49
|
-
handleErrors(error, mockRequest, mockResponse, mockNext);
|
|
50
|
-
expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
|
|
51
|
-
expect(mockResponse.status).toHaveBeenCalledWith(400);
|
|
52
|
-
expect(mockResponse.send).toHaveBeenCalledWith({
|
|
53
|
-
error: {
|
|
54
|
-
message,
|
|
55
|
-
code: 400,
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
expect(mockResponse.end).toHaveBeenCalled();
|
|
59
|
-
});
|
|
60
|
-
it("should handle ZodError", () => {
|
|
61
|
-
const mockRequest = { i18n };
|
|
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
|
-
};
|
|
69
|
-
const mockNext = vi.fn();
|
|
70
|
-
const zodError = {
|
|
71
|
-
code: "custom",
|
|
72
|
-
message: "Invalid input",
|
|
73
|
-
path: ["some", "variable"],
|
|
74
|
-
};
|
|
75
|
-
const error = new ZodError([zodError]);
|
|
76
|
-
handleErrors(error, mockRequest, mockResponse, mockNext);
|
|
77
|
-
expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
|
|
78
|
-
expect(mockResponse.status).toHaveBeenCalledWith(400);
|
|
79
|
-
expect(mockResponse.send).toHaveBeenCalledWith({
|
|
80
|
-
error: { code: 400, message: [zodError] },
|
|
81
|
-
});
|
|
82
|
-
expect(mockResponse.end).toHaveBeenCalled();
|
|
83
|
-
});
|
|
84
|
-
it("should unwrap nested ProsopoBaseError", async () => {
|
|
85
|
-
const mockRequest = { i18n };
|
|
86
|
-
const mockResponse = {
|
|
87
|
-
writeHead: vi.fn().mockReturnThis(),
|
|
88
|
-
set: vi.fn().mockReturnThis(),
|
|
89
|
-
status: vi.fn().mockReturnThis(),
|
|
90
|
-
send: vi.fn(),
|
|
91
|
-
end: vi.fn(),
|
|
92
|
-
};
|
|
93
|
-
const mockNext = vi.fn();
|
|
94
|
-
const envError = new ProsopoEnvError("GENERAL.ENVIRONMENT_NOT_READY", {
|
|
95
|
-
i18n,
|
|
96
|
-
});
|
|
97
|
-
const apiError = new ProsopoApiError(envError);
|
|
98
|
-
handleErrors(apiError, mockRequest, mockResponse, mockNext);
|
|
99
|
-
expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
|
|
100
|
-
expect(mockResponse.status).toHaveBeenCalledWith(500);
|
|
101
|
-
expect(mockResponse.send).toHaveBeenCalledWith({
|
|
102
|
-
error: {
|
|
103
|
-
code: 500,
|
|
104
|
-
key: "GENERAL.ENVIRONMENT_NOT_READY",
|
|
105
|
-
message: "Environment not ready",
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
expect(mockResponse.end).toHaveBeenCalled();
|
|
109
|
-
});
|
|
110
|
-
it("should unwrap nested ProsopoBaseErrors but not an Error that is nested inside them", async () => {
|
|
111
|
-
const mockRequest = { i18n };
|
|
112
|
-
const mockResponse = {
|
|
113
|
-
writeHead: vi.fn().mockReturnThis(),
|
|
114
|
-
set: vi.fn().mockReturnThis(),
|
|
115
|
-
status: vi.fn().mockReturnThis(),
|
|
116
|
-
send: vi.fn(),
|
|
117
|
-
end: vi.fn(),
|
|
118
|
-
};
|
|
119
|
-
const mockNext = vi.fn();
|
|
120
|
-
const code = 400;
|
|
121
|
-
const key = "API.UNKNOWN";
|
|
122
|
-
const error = new Error("Some error");
|
|
123
|
-
const apiError = new ProsopoApiError(key, {
|
|
124
|
-
context: { code, error },
|
|
125
|
-
i18n,
|
|
126
|
-
});
|
|
127
|
-
handleErrors(apiError, mockRequest, mockResponse, mockNext);
|
|
128
|
-
expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
|
|
129
|
-
expect(mockResponse.status).toHaveBeenCalledWith(code);
|
|
130
|
-
expect(mockResponse.send).toHaveBeenCalledWith({
|
|
131
|
-
error: {
|
|
132
|
-
code,
|
|
133
|
-
key,
|
|
134
|
-
message: "Unknown API error",
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
expect(mockResponse.end).toHaveBeenCalled();
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
//# sourceMappingURL=errorHandler.unit.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.unit.test.js","sourceRoot":"","sources":["../../../src/tests/unit/errorHandler.unit.test.ts"],"names":[],"mappings":"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"}
|