feat(middleware-logger): filter incoming requests
MODIFY
packages/middleware-logger/src/logger.handler.ts
packages/middleware-logger/src/logger.handler.ts
import { HttpRequest, HttpResponse } from '@marblejs/core';
import { fromEvent, Timestamp } from 'rxjs';
-import { take, filter, mapTo } from 'rxjs/operators';
+import { take, filter, mapTo, map } from 'rxjs/operators';
import { factorizeLog } from './logger.factory';
import { LoggerOptions } from './logger.model';
import { writeToStream, isNotSilent, filterResponse } from './logger.util';
@@ -9,7 +9,8 @@ export const loggerHandler = (res: HttpResponse, opts: LoggerOptions) => (stamp:
fromEvent(res, 'finish')
.pipe(
take(1),
- mapTo(res),
+ mapTo(stamp.value),
+ map(req => ({ req, res })),
filter(isNotSilent(opts)),
filter(filterResponse(opts)),
)

MODIFY
packages/middleware-logger/src/logger.model.ts
packages/middleware-logger/src/logger.model.ts
import { WriteStream } from 'fs';
-import { HttpResponse } from '@marblejs/core';
+import { HttpResponse, HttpRequest } from '@marblejs/core';
+
+export type LoggerCtx = {
+ req: HttpRequest;
+ res: HttpResponse;
+};
export interface LoggerOptions {
silent?: boolean;
stream?: WriteStream;
- filter?: (req: HttpResponse) => boolean;
+ filter?: (res: HttpResponse, req: HttpRequest) => boolean;
}
export interface LogParams {

MODIFY
packages/middleware-logger/src/logger.util.ts
packages/middleware-logger/src/logger.util.ts
import { WriteStream } from 'fs';
import { fromNullable } from 'fp-ts/lib/Option';
-import { HttpResponse } from '@marblejs/core';
import { compose } from '@marblejs/core/dist/+internal';
-import { LoggerOptions } from './logger.model';
+import { LoggerOptions, LoggerCtx } from './logger.model';
-export const isNotSilent = (opts: LoggerOptions) => () =>
+export const isNotSilent = (opts: LoggerOptions) => (ctx: LoggerCtx) =>
!opts.silent;
-export const filterResponse = (opts: LoggerOptions) => (res: HttpResponse) =>
+export const filterResponse = (opts: LoggerOptions) => (ctx: LoggerCtx) =>
fromNullable(opts.filter)
- .map(filter => filter(res))
+ .map(filter => filter(ctx.res, ctx.req))
.getOrElse(true);
export const writeToStream = (stream: WriteStream, chunk: string) =>

MODIFY
packages/middleware-logger/src/spec/logger.factory.spec.ts
packages/middleware-logger/src/spec/logger.factory.spec.ts
-import { HttpResponse, HttpRequest } from '@marblejs/core';
import { prepareLogString, factorizeLog } from '../logger.factory';
+import { createHttpResponse, createHttpRequest } from '@marblejs/core/dist/+internal';
describe('Logger factory', () => {
let loggerFactoryModule;
@@ -48,8 +48,8 @@ describe('Logger factory', () => {
test('#factorizeLog factorizes logger message', () => {
// given
- const res = { statusCode: 200 } as HttpResponse;
- const req = { method: 'GET', url: '/api/v1' } as HttpRequest;
+ const res = createHttpResponse({ statusCode: 200 });
+ const req = createHttpRequest({ method: 'GET', url: '/api/v1' });
const stamp = { value: req, timestamp: 1539031930521 };
const opts = { colorize: false, timestamp: true };
const date = 1540145853 * 1000;
@@ -72,8 +72,8 @@ describe('Logger factory', () => {
test('#factorizeLog factorizes logger message without timestamp', () => {
// given
- const res = { statusCode: 200 } as HttpResponse;
- const req = { method: 'GET', url: '/api/v1' } as HttpRequest;
+ const res = createHttpResponse({ statusCode: 200 });
+ const req = createHttpRequest({ method: 'GET', url: '/api/v1' });
const stamp = { value: req, timestamp: 1539031930521 };
// when

MODIFY
packages/middleware-logger/src/spec/logger.util.spec.ts
packages/middleware-logger/src/spec/logger.util.spec.ts
import { join } from 'path';
import { createWriteStream } from 'fs';
-import { HttpResponse } from '@marblejs/core';
+import { createHttpRequest, createHttpResponse } from '@marblejs/core/dist/+internal/testing';
import { formatTime, getTimeDifferenceInMs, filterResponse, isNotSilent, writeToStream } from '../logger.util';
describe('Logger util', () => {
@@ -30,14 +30,30 @@ describe('Logger util', () => {
expect(timeDifference).toBe(2000 - 1000);
});
- test('#filterResponse filters request by given predicate function', () => {
+ test('#filterResponse filters response by given predicate function', () => {
// given
- const res = { status: 404 } as any as HttpResponse;
+ const req = createHttpRequest({ url: '/bar' });
+ const res = createHttpResponse({ statusCode: 404 });
const predicate = res => res.status < 400;
// when
- const resultWithPredicateFunction = filterResponse({ filter: predicate })(res);
- const resultWithoutPredicateFunction = filterResponse({})(res);
+ const resultWithPredicateFunction = filterResponse({ filter: predicate })({ req, res });
+ const resultWithoutPredicateFunction = filterResponse({})({ req, res });
+
+ // then
+ expect(resultWithPredicateFunction).toEqual(false);
+ expect(resultWithoutPredicateFunction).toEqual(true);
+ });
+
+ test('#filterResponse filters request by given predicate function', () => {
+ // given
+ const req = createHttpRequest({ url: '/bar' });
+ const res = createHttpResponse({ statusCode: 404 });
+ const predicate = (res, req) => req.url.includes('/foo');
+
+ // when
+ const resultWithPredicateFunction = filterResponse({ filter: predicate })({ req, res });
+ const resultWithoutPredicateFunction = filterResponse({})({ req, res });
// then
expect(resultWithPredicateFunction).toEqual(false);
@@ -46,14 +62,16 @@ describe('Logger util', () => {
test('#isNotSilent checks if options "silent" flag is set', () => {
// given
+ const req = createHttpRequest();
+ const res = createHttpResponse();
const optsSilent = isNotSilent({ silent: true });
const optsNotSilent = isNotSilent({ silent: false });
const optsWithoutSilent = isNotSilent({});
// then
- expect(optsSilent()).toEqual(false);
- expect(optsNotSilent()).toEqual(true);
- expect(optsWithoutSilent()).toEqual(true);
+ expect(optsSilent({ req, res })).toEqual(false);
+ expect(optsNotSilent({ req, res })).toEqual(true);
+ expect(optsWithoutSilent({ req, res })).toEqual(true);
});
test('#writeToStream writes to stream passed data chunk', () => {

feat(middleware-logger): filter incoming requests