@takaro/http 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/middleware/errorHandler.d.ts +1 -1
- package/dist/middleware/errorHandler.js +4 -2
- package/dist/middleware/errorHandler.js.map +1 -1
- package/dist/middleware/logger.d.ts +4 -1
- package/dist/middleware/logger.js.map +1 -1
- package/package.json +2 -2
- package/src/controllers/__tests__/meta.integration.test.ts +2 -9
- package/src/middleware/__tests__/rateLimit.integration.test.ts +13 -12
- package/src/middleware/errorHandler.ts +4 -2
- package/src/middleware/logger.ts +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
|
-
export declare function ErrorHandler(originalError: Error, req: Request, res: Response, _next: NextFunction): Promise<
|
|
2
|
+
export declare function ErrorHandler(originalError: Error, req: Request, res: Response, _next: NextFunction): Promise<void>;
|
|
@@ -11,7 +11,9 @@ export async function ErrorHandler(originalError, req, res, _next) {
|
|
|
11
11
|
// @ts-expect-error Error typing is weird in ts... but we validate during runtime so should be OK
|
|
12
12
|
const validationErrors = originalError['errors'];
|
|
13
13
|
parsedError = new errors.ValidationError('Validation error', validationErrors);
|
|
14
|
-
log.warn('⚠️ Validation errror', {
|
|
14
|
+
log.warn('⚠️ Validation errror', {
|
|
15
|
+
details: validationErrors.map((e) => JSON.stringify(e.constraints, null, 2)),
|
|
16
|
+
});
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
if (originalError instanceof MulterError) {
|
|
@@ -61,6 +63,6 @@ export async function ErrorHandler(originalError, req, res, _next) {
|
|
|
61
63
|
log.warn(`⚠️ FAIL ${req.method} ${req.originalUrl}`, parsedError);
|
|
62
64
|
}
|
|
63
65
|
res.status(status).json(apiResponse({}, { error: parsedError, req, res }));
|
|
64
|
-
|
|
66
|
+
res.end();
|
|
65
67
|
}
|
|
66
68
|
//# sourceMappingURL=errorHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAEnC,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,aAAoB,EACpB,GAAY,EACZ,GAAa,EAEb,KAAmB;IAEnB,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,IAAI,WAAW,GAAG,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;IAEnD,IAAI,aAAa,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC7C,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,CAAC;YAClE,iGAAiG;YACjG,MAAM,gBAAgB,GAAG,aAAa,CAAC,QAAQ,CAAsB,CAAC;YACtE,WAAW,GAAG,IAAI,MAAM,CAAC,eAAe,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;YAC/E,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { NextFunction, Request, Response } from 'express';
|
|
1
2
|
/**
|
|
2
3
|
* This middleware is called very early in the request lifecycle, so it's
|
|
3
4
|
* we leverage this fact to inject the context tracking at this stage
|
|
4
5
|
*/
|
|
5
|
-
export declare const LoggingMiddleware:
|
|
6
|
+
export declare const LoggingMiddleware: typeof loggingMiddleware;
|
|
7
|
+
declare function loggingMiddleware(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
8
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/middleware/logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,sBAAsB,GAAG,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAC3D,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;AACrG,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/middleware/logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,sBAAsB,GAAG,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAC3D,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;AACrG,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAA6B,CAAC;AAEjG,KAAK,UAAU,iBAAiB,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IAC9E,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACrE,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAElC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9G,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,EAAE;QAC/C,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,GAAG,CAAC,WAAW;QACrB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI;KACxD,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7C,IAAI,IAAI,EAAE,CAAC;QACT,2DAA2D;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC;QAC3C,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,6CAA6C;IAC7C,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC;QAEjD,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,EAAE;YAC9C,YAAY;YACZ,aAAa,EAAE,GAAG,CAAC,MAAM;YACzB,UAAU,EAAE,GAAG,CAAC,WAAW;YAC3B,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC;YAC1C,MAAM,EAAE,GAAG,CAAC,UAAU;YACtB,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC;YAC7C,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC;YAChC,QAAQ,EAAE,GAAG,CAAC,EAAE;YAChB,QAAQ,EAAE,WAAW;YACrB,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC;YAC3B,WAAW,EAAE,KAAK;YAClB,QAAQ,EAAE,KAAK;YACf,8BAA8B,EAAE,KAAK;YACrC,QAAQ,EAAE,GAAG,CAAC,QAAQ;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC;AACT,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takaro/http",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "An opinionated http server",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"types": "dist/main.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/cookie-parser": "1.4.7",
|
|
29
29
|
"@types/cors": "2.8.17",
|
|
30
|
-
"@types/express": "
|
|
30
|
+
"@types/express": "5.0.0",
|
|
31
31
|
"supertest": "6.3.4"
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { HTTP } from '../../app.js';
|
|
2
2
|
import supertest from 'supertest';
|
|
3
|
-
import { expect } from '@takaro/test';
|
|
4
3
|
|
|
5
4
|
describe('app', () => {
|
|
6
5
|
let http: HTTP;
|
|
@@ -14,16 +13,10 @@ describe('app', () => {
|
|
|
14
13
|
});
|
|
15
14
|
|
|
16
15
|
it('Serves a health status', async () => {
|
|
17
|
-
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
const response = await supertest(http.expressInstance).get('/healthz');
|
|
20
|
-
expect(response.status).to.be.equal(200);
|
|
16
|
+
await supertest(http.expressInstance).get('/healthz').expect(200);
|
|
21
17
|
});
|
|
22
18
|
|
|
23
19
|
it('Serves a open api spec', async () => {
|
|
24
|
-
|
|
25
|
-
// @ts-ignore
|
|
26
|
-
const response = await supertest(http.expressInstance).get('/openapi.json');
|
|
27
|
-
expect(response.status).to.be.equal(200);
|
|
20
|
+
await supertest(http.expressInstance).get('/openapi.json').expect(200);
|
|
28
21
|
});
|
|
29
22
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Response, NextFunction, Request } from 'express';
|
|
2
2
|
import { Redis } from '@takaro/db';
|
|
3
|
-
import { expect } from '@takaro/test';
|
|
4
3
|
import { Controller, UseBefore, Get } from 'routing-controllers';
|
|
5
4
|
import { HTTP } from '../../main.js';
|
|
6
5
|
import { createRateLimitMiddleware } from '../rateLimit.js';
|
|
@@ -112,17 +111,19 @@ describe('rateLimit middleware', () => {
|
|
|
112
111
|
const agent = supertest(http.expressInstance);
|
|
113
112
|
|
|
114
113
|
for (let i = 1; i < 5; i++) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
await agent
|
|
115
|
+
.get('/low-limit')
|
|
116
|
+
.expect(200)
|
|
117
|
+
.expect('x-ratelimit-remaining', (5 - i).toString())
|
|
118
|
+
.expect('x-ratelimit-limit', '5')
|
|
119
|
+
.expect('x-ratelimit-reset', /\d+/);
|
|
121
120
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
|
|
122
|
+
agent
|
|
123
|
+
.get('/low-limit')
|
|
124
|
+
.expect(429)
|
|
125
|
+
.expect('x-ratelimit-remaining', '0')
|
|
126
|
+
.expect('x-ratelimit-limit', '5')
|
|
127
|
+
.expect('x-ratelimit-reset', /\d+/);
|
|
127
128
|
});
|
|
128
129
|
});
|
|
@@ -22,7 +22,9 @@ export async function ErrorHandler(
|
|
|
22
22
|
// @ts-expect-error Error typing is weird in ts... but we validate during runtime so should be OK
|
|
23
23
|
const validationErrors = originalError['errors'] as ValidationError[];
|
|
24
24
|
parsedError = new errors.ValidationError('Validation error', validationErrors);
|
|
25
|
-
log.warn('⚠️ Validation errror', {
|
|
25
|
+
log.warn('⚠️ Validation errror', {
|
|
26
|
+
details: validationErrors.map((e) => JSON.stringify(e.constraints, null, 2)),
|
|
27
|
+
});
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -83,5 +85,5 @@ export async function ErrorHandler(
|
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
res.status(status).json(apiResponse({}, { error: parsedError, req, res }));
|
|
86
|
-
|
|
88
|
+
res.end();
|
|
87
89
|
}
|
package/src/middleware/logger.ts
CHANGED
|
@@ -10,7 +10,7 @@ const log = logger('http');
|
|
|
10
10
|
* This middleware is called very early in the request lifecycle, so it's
|
|
11
11
|
* we leverage this fact to inject the context tracking at this stage
|
|
12
12
|
*/
|
|
13
|
-
export const LoggingMiddleware = ctx.wrap('HTTP', loggingMiddleware);
|
|
13
|
+
export const LoggingMiddleware = ctx.wrap('HTTP', loggingMiddleware) as typeof loggingMiddleware;
|
|
14
14
|
|
|
15
15
|
async function loggingMiddleware(req: Request, res: Response, next: NextFunction) {
|
|
16
16
|
if (HIDDEN_ROUTES.some((route) => req.originalUrl.startsWith(route))) {
|