@prosopo/api-express-router 3.1.50 → 3.1.52
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/.turbo/turbo-build$colon$cjs.log +14 -12
- package/.turbo/turbo-build$colon$tsc.log +21 -21
- package/.turbo/turbo-build.log +16 -13
- package/CHANGELOG.md +23 -0
- package/dist/_virtual/_rolldown/runtime.js +3 -0
- package/dist/apiExpressRouterFactory.js +17 -27
- package/dist/cjs/apiExpressRouterFactory.cjs +18 -28
- package/dist/cjs/endpointAdapter/apiExpressDefaultEndpointAdapter.cjs +29 -35
- package/dist/cjs/errorHandler.cjs +10 -10
- package/dist/cjs/index.cjs +14 -13
- package/dist/cjs/middlewares/authMiddleware.cjs +54 -56
- package/dist/cjs/middlewares/requestLoggerMiddleware.cjs +57 -59
- package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js +26 -33
- package/dist/errorHandler.js +10 -10
- package/dist/index.js +8 -12
- package/dist/middlewares/authMiddleware.js +54 -57
- package/dist/middlewares/requestLoggerMiddleware.js +56 -58
- package/dist/tests/apiExpressRouter.test-d.d.ts +2 -0
- package/dist/tests/apiExpressRouter.test-d.d.ts.map +1 -0
- package/dist/tests/apiExpressRouter.test-d.js +76 -0
- package/dist/tests/apiExpressRouter.test-d.js.map +1 -0
- package/dist/tests/unit/apiExpressDefaultEndpointAdapter.unit.test.d.ts +2 -0
- package/dist/tests/unit/apiExpressDefaultEndpointAdapter.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/apiExpressDefaultEndpointAdapter.unit.test.js +197 -0
- package/dist/tests/unit/apiExpressDefaultEndpointAdapter.unit.test.js.map +1 -0
- package/dist/tests/unit/apiExpressRouterFactory.unit.test.d.ts +2 -0
- package/dist/tests/unit/apiExpressRouterFactory.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/apiExpressRouterFactory.unit.test.js +108 -0
- package/dist/tests/unit/apiExpressRouterFactory.unit.test.js.map +1 -0
- package/dist/tests/unit/index.unit.test.d.ts +2 -0
- package/dist/tests/unit/index.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/index.unit.test.js +44 -0
- package/dist/tests/unit/index.unit.test.js.map +1 -0
- package/dist/tests/unit/middlewares/authMiddleware.unit.test.js +210 -136
- package/dist/tests/unit/middlewares/authMiddleware.unit.test.js.map +1 -1
- package/dist/tests/unit/middlewares/requestLoggerMiddleware.unit.test.d.ts +2 -0
- package/dist/tests/unit/middlewares/requestLoggerMiddleware.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/middlewares/requestLoggerMiddleware.unit.test.js +242 -0
- package/dist/tests/unit/middlewares/requestLoggerMiddleware.unit.test.js.map +1 -0
- package/dist/tests/unit/testDoubles.d.ts +8 -0
- package/dist/tests/unit/testDoubles.d.ts.map +1 -0
- package/dist/tests/unit/testDoubles.js +11 -0
- package/dist/tests/unit/testDoubles.js.map +1 -0
- package/package.json +10 -10
- package/src/tests/apiExpressRouter.test-d.ts +190 -0
- package/src/tests/unit/apiExpressDefaultEndpointAdapter.unit.test.ts +395 -0
- package/src/tests/unit/apiExpressRouterFactory.unit.test.ts +215 -0
- package/src/tests/unit/index.unit.test.ts +95 -0
- package/src/tests/unit/middlewares/authMiddleware.unit.test.ts +318 -159
- package/src/tests/unit/middlewares/requestLoggerMiddleware.unit.test.ts +368 -0
- package/src/tests/unit/testDoubles.ts +39 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,63 +1,61 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (headerName in req.headers && req.headers[headerName]) {
|
|
7
|
-
return req.headers[headerName].toString();
|
|
8
|
-
}
|
|
9
|
-
return void 0;
|
|
1
|
+
let _prosopo_logger = require("@prosopo/logger");
|
|
2
|
+
let uuid = require("uuid");
|
|
3
|
+
//#region src/middlewares/requestLoggerMiddleware.ts
|
|
4
|
+
var getHeaderValue = (req, headerName) => {
|
|
5
|
+
if (headerName in req.headers && req.headers[headerName]) return req.headers[headerName].toString();
|
|
10
6
|
};
|
|
11
|
-
|
|
7
|
+
var HEALTH_CHECK_PATHS = /* @__PURE__ */ new Set([
|
|
8
|
+
"/healthz",
|
|
9
|
+
"/health",
|
|
10
|
+
"/readyz"
|
|
11
|
+
]);
|
|
12
12
|
function requestLoggerMiddleware(env) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
res.on("close", () => emitFinish("close"));
|
|
60
|
-
next();
|
|
61
|
-
};
|
|
13
|
+
return (req, res, next) => {
|
|
14
|
+
const requestId = req.headers["x-request-id"] || `e-${(0, uuid.v4)()}`;
|
|
15
|
+
const user = getHeaderValue(req, "prosopo-user");
|
|
16
|
+
const siteKey = getHeaderValue(req, "prosopo-site-key");
|
|
17
|
+
const sessionId = req.body?.sessionId ? req.body.sessionId : void 0;
|
|
18
|
+
const logger = (0, _prosopo_logger.getLogger)((0, _prosopo_logger.parseLogLevel)(env.config.logLevel), "provider:request").with({
|
|
19
|
+
requestId,
|
|
20
|
+
...user ? { user } : {},
|
|
21
|
+
...siteKey ? { siteKey } : {},
|
|
22
|
+
...sessionId ? { sessionId } : {}
|
|
23
|
+
});
|
|
24
|
+
req.logger = logger;
|
|
25
|
+
req.requestId = requestId;
|
|
26
|
+
res.setHeader("x-request-id", requestId);
|
|
27
|
+
if (HEALTH_CHECK_PATHS.has(req.path)) {
|
|
28
|
+
next();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const startNs = process.hrtime.bigint();
|
|
32
|
+
logger.info(() => ({
|
|
33
|
+
msg: "Request received",
|
|
34
|
+
data: {
|
|
35
|
+
method: req.method,
|
|
36
|
+
path: req.path
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
39
|
+
let finished = false;
|
|
40
|
+
const emitFinish = (outcome) => {
|
|
41
|
+
if (finished) return;
|
|
42
|
+
finished = true;
|
|
43
|
+
const durationMs = Number(process.hrtime.bigint() - startNs) / 1e6;
|
|
44
|
+
logger.info(() => ({
|
|
45
|
+
msg: "Response sent",
|
|
46
|
+
data: {
|
|
47
|
+
method: req.method,
|
|
48
|
+
path: req.path,
|
|
49
|
+
status: res.statusCode,
|
|
50
|
+
durationMs,
|
|
51
|
+
outcome
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
};
|
|
55
|
+
res.on("finish", () => emitFinish("finish"));
|
|
56
|
+
res.on("close", () => emitFinish("close"));
|
|
57
|
+
next();
|
|
58
|
+
};
|
|
62
59
|
}
|
|
60
|
+
//#endregion
|
|
63
61
|
exports.requestLoggerMiddleware = requestLoggerMiddleware;
|
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
import { ProsopoApiError } from "@prosopo/common";
|
|
2
2
|
import { stringifyBigInts } from "@prosopo/util";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
request.logger.error(() => ({
|
|
28
|
-
err: error
|
|
29
|
-
}));
|
|
30
|
-
response.status(500).send("An internal server error occurred.");
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
export {
|
|
35
|
-
ApiExpressDefaultEndpointAdapter
|
|
3
|
+
//#region src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts
|
|
4
|
+
var ApiExpressDefaultEndpointAdapter = class {
|
|
5
|
+
constructor(logLevel, errorStatusCode) {
|
|
6
|
+
this.logLevel = logLevel;
|
|
7
|
+
this.errorStatusCode = errorStatusCode;
|
|
8
|
+
}
|
|
9
|
+
async handleRequest(endpoint, request, response, next) {
|
|
10
|
+
let args;
|
|
11
|
+
try {
|
|
12
|
+
args = endpoint.getRequestArgsSchema()?.parse(request.body);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
return next(new ProsopoApiError("API.PARSE_ERROR", { context: {
|
|
15
|
+
code: 400,
|
|
16
|
+
error
|
|
17
|
+
} }));
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const responseObject = stringifyBigInts(await endpoint.processRequest(args, request.logger));
|
|
21
|
+
response.json(responseObject);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
request.logger.error(() => ({ err: error }));
|
|
24
|
+
response.status(500).send("An internal server error occurred.");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
36
27
|
};
|
|
28
|
+
//#endregion
|
|
29
|
+
export { ApiExpressDefaultEndpointAdapter };
|
package/dist/errorHandler.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { unwrapError } from "@prosopo/common";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
handleErrors
|
|
2
|
+
//#region src/errorHandler.ts
|
|
3
|
+
var handleErrors = (err, request, response, next) => {
|
|
4
|
+
const { code, statusMessage, jsonError } = unwrapError(err, request.i18n);
|
|
5
|
+
response.statusMessage = statusMessage;
|
|
6
|
+
response.set("content-type", "application/json");
|
|
7
|
+
response.status(code);
|
|
8
|
+
response.send({ error: jsonError });
|
|
9
|
+
response.end();
|
|
12
10
|
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { handleErrors };
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
|
+
import "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { handleErrors } from "./errorHandler.js";
|
|
1
3
|
import { ApiExpressRouterFactory } from "./apiExpressRouterFactory.js";
|
|
2
4
|
import { ApiExpressDefaultEndpointAdapter } from "./endpointAdapter/apiExpressDefaultEndpointAdapter.js";
|
|
3
|
-
import { handleErrors } from "./errorHandler.js";
|
|
4
5
|
import { authMiddleware, verifySignature } from "./middlewares/authMiddleware.js";
|
|
5
6
|
import { requestLoggerMiddleware } from "./middlewares/requestLoggerMiddleware.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
apiExpressRouterFactory,
|
|
12
|
-
authMiddleware,
|
|
13
|
-
createApiExpressDefaultEndpointAdapter,
|
|
14
|
-
handleErrors,
|
|
15
|
-
requestLoggerMiddleware,
|
|
16
|
-
verifySignature
|
|
7
|
+
//#region src/index.ts
|
|
8
|
+
var apiExpressRouterFactory = new ApiExpressRouterFactory();
|
|
9
|
+
var createApiExpressDefaultEndpointAdapter = (logLevel, errorStatusCode = 500) => {
|
|
10
|
+
return new ApiExpressDefaultEndpointAdapter(logLevel, errorStatusCode);
|
|
17
11
|
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { apiExpressRouterFactory, authMiddleware, createApiExpressDefaultEndpointAdapter, handleErrors, requestLoggerMiddleware, verifySignature };
|
|
@@ -1,61 +1,58 @@
|
|
|
1
|
+
import { ProsopoApiError, ProsopoEnvError } from "@prosopo/common";
|
|
1
2
|
import { hexToU8a } from "@polkadot/util";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
3
|
+
//#region src/middlewares/authMiddleware.ts
|
|
4
|
+
var authMiddleware = (pair, authAccount) => {
|
|
5
|
+
return async (req, res, next) => {
|
|
6
|
+
try {
|
|
7
|
+
const jwt = extractJWT(req);
|
|
8
|
+
if (authAccount?.jwtVerify(jwt).isValid) {
|
|
9
|
+
next();
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (pair?.jwtVerify(jwt).isValid) {
|
|
13
|
+
next();
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
res.status(401).json({ error: new ProsopoEnvError("API.UNAUTHORIZED", { context: {
|
|
17
|
+
i18n: req.i18n,
|
|
18
|
+
code: 401
|
|
19
|
+
} }) });
|
|
20
|
+
return;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
req.logger.error(() => ({
|
|
23
|
+
err,
|
|
24
|
+
msg: "Auth Middleware Error"
|
|
25
|
+
}));
|
|
26
|
+
res.status(401).json({
|
|
27
|
+
error: "Unauthorized",
|
|
28
|
+
message: err
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
28
33
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
return jwt;
|
|
34
|
+
var extractJWT = (req) => {
|
|
35
|
+
const authHeader = req.headers.Authorization || req.headers.authorization;
|
|
36
|
+
if (!authHeader || typeof authHeader !== "string") throw new ProsopoApiError("GENERAL.MISSING_AUTH_HEADER", { context: {
|
|
37
|
+
error: "Missing Authorization header",
|
|
38
|
+
code: 401
|
|
39
|
+
} });
|
|
40
|
+
const jwt = authHeader.replace("Bearer ", "");
|
|
41
|
+
if (!jwt) throw new ProsopoApiError("GENERAL.INVALID_JWT", { context: {
|
|
42
|
+
error: "Missing JWT",
|
|
43
|
+
code: 400
|
|
44
|
+
} });
|
|
45
|
+
return jwt;
|
|
43
46
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
signature
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
export {
|
|
59
|
-
authMiddleware,
|
|
60
|
-
verifySignature
|
|
47
|
+
var verifySignature = (signature, message, pair) => {
|
|
48
|
+
const u8Sig = hexToU8a(signature);
|
|
49
|
+
if (!pair.verify(message, u8Sig, pair.publicKey)) throw new ProsopoApiError("GENERAL.INVALID_SIGNATURE", { context: {
|
|
50
|
+
error: "Signature verification failed",
|
|
51
|
+
code: 401,
|
|
52
|
+
account: pair.address,
|
|
53
|
+
message,
|
|
54
|
+
signature
|
|
55
|
+
} });
|
|
61
56
|
};
|
|
57
|
+
//#endregion
|
|
58
|
+
export { authMiddleware, verifySignature };
|
|
@@ -1,63 +1,61 @@
|
|
|
1
1
|
import { getLogger, parseLogLevel } from "@prosopo/logger";
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
return void 0;
|
|
3
|
+
//#region src/middlewares/requestLoggerMiddleware.ts
|
|
4
|
+
var getHeaderValue = (req, headerName) => {
|
|
5
|
+
if (headerName in req.headers && req.headers[headerName]) return req.headers[headerName].toString();
|
|
8
6
|
};
|
|
9
|
-
|
|
7
|
+
var HEALTH_CHECK_PATHS = /* @__PURE__ */ new Set([
|
|
8
|
+
"/healthz",
|
|
9
|
+
"/health",
|
|
10
|
+
"/readyz"
|
|
11
|
+
]);
|
|
10
12
|
function requestLoggerMiddleware(env) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
res.on("close", () => emitFinish("close"));
|
|
58
|
-
next();
|
|
59
|
-
};
|
|
13
|
+
return (req, res, next) => {
|
|
14
|
+
const requestId = req.headers["x-request-id"] || `e-${v4()}`;
|
|
15
|
+
const user = getHeaderValue(req, "prosopo-user");
|
|
16
|
+
const siteKey = getHeaderValue(req, "prosopo-site-key");
|
|
17
|
+
const sessionId = req.body?.sessionId ? req.body.sessionId : void 0;
|
|
18
|
+
const logger = getLogger(parseLogLevel(env.config.logLevel), "provider:request").with({
|
|
19
|
+
requestId,
|
|
20
|
+
...user ? { user } : {},
|
|
21
|
+
...siteKey ? { siteKey } : {},
|
|
22
|
+
...sessionId ? { sessionId } : {}
|
|
23
|
+
});
|
|
24
|
+
req.logger = logger;
|
|
25
|
+
req.requestId = requestId;
|
|
26
|
+
res.setHeader("x-request-id", requestId);
|
|
27
|
+
if (HEALTH_CHECK_PATHS.has(req.path)) {
|
|
28
|
+
next();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const startNs = process.hrtime.bigint();
|
|
32
|
+
logger.info(() => ({
|
|
33
|
+
msg: "Request received",
|
|
34
|
+
data: {
|
|
35
|
+
method: req.method,
|
|
36
|
+
path: req.path
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
39
|
+
let finished = false;
|
|
40
|
+
const emitFinish = (outcome) => {
|
|
41
|
+
if (finished) return;
|
|
42
|
+
finished = true;
|
|
43
|
+
const durationMs = Number(process.hrtime.bigint() - startNs) / 1e6;
|
|
44
|
+
logger.info(() => ({
|
|
45
|
+
msg: "Response sent",
|
|
46
|
+
data: {
|
|
47
|
+
method: req.method,
|
|
48
|
+
path: req.path,
|
|
49
|
+
status: res.statusCode,
|
|
50
|
+
durationMs,
|
|
51
|
+
outcome
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
};
|
|
55
|
+
res.on("finish", () => emitFinish("finish"));
|
|
56
|
+
res.on("close", () => emitFinish("close"));
|
|
57
|
+
next();
|
|
58
|
+
};
|
|
60
59
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { requestLoggerMiddleware };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiExpressRouter.test-d.d.ts","sourceRoot":"","sources":["../../src/tests/apiExpressRouter.test-d.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { assertType, describe, expectTypeOf, test } from "vitest";
|
|
2
|
+
import { apiExpressRouterFactory, authMiddleware, createApiExpressDefaultEndpointAdapter, handleErrors, requestLoggerMiddleware, verifySignature, } from "../index.js";
|
|
3
|
+
describe("the barrel's shape", () => {
|
|
4
|
+
test("exports exactly the intended names", () => {
|
|
5
|
+
expectTypeOf().toEqualTypeOf();
|
|
6
|
+
});
|
|
7
|
+
});
|
|
8
|
+
describe("createApiExpressDefaultEndpointAdapter", () => {
|
|
9
|
+
test("takes a log level and an optional status code", () => {
|
|
10
|
+
expectTypeOf(createApiExpressDefaultEndpointAdapter).parameters.toEqualTypeOf();
|
|
11
|
+
});
|
|
12
|
+
test("returns the interface, not the concrete class", () => {
|
|
13
|
+
expectTypeOf(createApiExpressDefaultEndpointAdapter).returns.toEqualTypeOf();
|
|
14
|
+
});
|
|
15
|
+
test("rejects a log level that is not one of the known levels", () => {
|
|
16
|
+
createApiExpressDefaultEndpointAdapter("chatty");
|
|
17
|
+
});
|
|
18
|
+
test("rejects a non-numeric status code", () => {
|
|
19
|
+
createApiExpressDefaultEndpointAdapter("info", "500");
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
describe("the router factory", () => {
|
|
23
|
+
test("takes a routes provider and an adapter, and returns a Router", () => {
|
|
24
|
+
expectTypeOf(apiExpressRouterFactory.createRouter).toEqualTypeOf();
|
|
25
|
+
});
|
|
26
|
+
test("rejects a bare routes object in place of a provider", () => {
|
|
27
|
+
const adapter = {
|
|
28
|
+
handleRequest: async () => undefined,
|
|
29
|
+
};
|
|
30
|
+
apiExpressRouterFactory.createRouter({}, adapter);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe("the endpoint adapter interface", () => {
|
|
34
|
+
test("takes the endpoint and the express trio and resolves to void", () => {
|
|
35
|
+
expectTypeOf().toEqualTypeOf();
|
|
36
|
+
});
|
|
37
|
+
test("is satisfied by any object with a matching handleRequest", () => {
|
|
38
|
+
assertType({
|
|
39
|
+
handleRequest: async () => undefined,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe("the middleware", () => {
|
|
44
|
+
test("authMiddleware takes an optional pair and an optional auth account", () => {
|
|
45
|
+
expectTypeOf(authMiddleware).parameters.toEqualTypeOf();
|
|
46
|
+
});
|
|
47
|
+
test("authMiddleware returns an async express handler", () => {
|
|
48
|
+
expectTypeOf(authMiddleware).returns.toEqualTypeOf();
|
|
49
|
+
});
|
|
50
|
+
test("authMiddleware still requires the first argument to be passed", () => {
|
|
51
|
+
authMiddleware();
|
|
52
|
+
});
|
|
53
|
+
test("requestLoggerMiddleware returns a synchronous express handler", () => {
|
|
54
|
+
expectTypeOf(requestLoggerMiddleware).returns.toEqualTypeOf();
|
|
55
|
+
});
|
|
56
|
+
test("the handler each factory builds is usable as express middleware", () => {
|
|
57
|
+
assertType(requestLoggerMiddleware({}));
|
|
58
|
+
assertType(authMiddleware(undefined));
|
|
59
|
+
});
|
|
60
|
+
test("verifySignature takes a signature, a message and a pair, and returns void", () => {
|
|
61
|
+
expectTypeOf(verifySignature).parameters.toEqualTypeOf();
|
|
62
|
+
expectTypeOf(verifySignature).returns.toEqualTypeOf();
|
|
63
|
+
});
|
|
64
|
+
test("verifySignature rejects a byte-array signature", () => {
|
|
65
|
+
verifySignature(new Uint8Array([1]), "msg", {});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe("the error handler", () => {
|
|
69
|
+
test("takes an error first, which is what makes express treat it as one", () => {
|
|
70
|
+
expectTypeOf(handleErrors).parameters.toMatchTypeOf();
|
|
71
|
+
});
|
|
72
|
+
test("rejects being mounted as an ordinary handler", () => {
|
|
73
|
+
assertType(handleErrors);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=apiExpressRouter.test-d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiExpressRouter.test-d.js","sourceRoot":"","sources":["../../src/tests/apiExpressRouter.test-d.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiExpressDefaultEndpointAdapter.unit.test.d.ts","sourceRoot":"","sources":["../../../src/tests/unit/apiExpressDefaultEndpointAdapter.unit.test.ts"],"names":[],"mappings":""}
|