refactor(core): Effect type definition
MODIFY
packages/@integration/src/middlewares/auth.middleware.ts
packages/@integration/src/middlewares/auth.middleware.ts
-import { Effect, HttpError, HttpRequest, HttpStatus } from '@marblejs/core';
+import { HttpError, HttpStatus, Middleware } from '@marblejs/core';
import { iif, of, throwError } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { isAuthorized } from '../fakes/auth.fake';
-export const authorize$: Effect<HttpRequest> = request$ =>
- request$.pipe(
+export const authorize$: Middleware = req$ =>
+ req$.pipe(
switchMap(req => iif(
() => !isAuthorized(req),
throwError(new HttpError('Unauthorized', HttpStatus.UNAUTHORIZED)),

MODIFY
packages/core/src/effects/effects.factory.ts
packages/core/src/effects/effects.factory.ts
import { HttpMethod, HttpMethodType } from '../http.interface';
-import { Effect, EffectResponse } from './effects.interface';
+import { Effect } from './effects.interface';
import { RouteEffect } from '../router/router.interface';
import { coreErrorFactory, CoreErrorOptions } from '../error/error.factory';
import { getArrayFromEnum } from '../+internal';
@@ -32,7 +32,7 @@ export namespace EffectFactory {
return { use: use(path)(method) };
};
- const use = (path: string) => (method: HttpMethod) => (effect: Effect<EffectResponse>): RouteEffect => {
+ const use = (path: string) => (method: HttpMethod) => (effect: Effect): RouteEffect => {
if (!effect) {
throw coreErrorFactory('Effect needs to be provided', coreErrorOptions);
}

MODIFY
packages/core/src/effects/effects.interface.ts
packages/core/src/effects/effects.interface.ts
@@ -7,16 +7,18 @@ export interface EffectResponse {
headers?: Record<string, string>;
}
-export type Middleware<
+export interface Middleware<
TBody = any,
TParams = any,
TQuery = any,
-> = Effect<HttpRequest<TBody, TParams, TQuery>>;
+> extends Effect<
+ HttpRequest<TBody, TParams, TQuery>,
+ HttpRequest<TBody, TParams, TQuery>
+> {}
-export type ErrorEffect = Effect<EffectResponse, Error>;
+export interface ErrorEffect<T extends Error = Error>
+ extends Effect<HttpRequest, EffectResponse, T> {}
-export type Effect<T = EffectResponse, U = any> = (
- request$: Observable<HttpRequest>,
- response: HttpResponse,
- metadata: U
-) => Observable<T>;
+export interface Effect<T extends HttpRequest = HttpRequest, U = EffectResponse, V = any> {
+ (req$: Observable<T>, res: HttpResponse, meta: V): Observable<U>;
+}

MODIFY
packages/core/src/error/error.effect.ts
packages/core/src/error/error.effect.ts
import { map } from 'rxjs/operators';
-import { Effect, EffectResponse } from '../effects/effects.interface';
+import { ErrorEffect } from '../effects/effects.interface';
import { HttpStatus } from '../http.interface';
import { HttpError, isHttpError } from './error.model';
export type ThrownError = HttpError & Error;
-export const errorEffectProvider = (customError$?: Effect<EffectResponse, ThrownError>) => !!customError$
+export const errorEffectProvider = (customError$?: ErrorEffect<ThrownError>) => !!customError$
? customError$
: error$;
@@ -17,13 +17,12 @@ const errorFactory = (message: string, status: HttpStatus, data?: any) => ({
error: { status, message, data }
});
-export const error$: Effect<EffectResponse, ThrownError> = (request$, _, error) => request$
+export const error$: ErrorEffect<ThrownError> = (req$, _, error) => req$
.pipe(
map(() => {
const { message, data } = error;
const status = getStatusCode(error);
const body = errorFactory(message, status, data);
-
return { status, body };
}),
);

MODIFY
packages/core/src/error/specs/error.effect.spec.ts
packages/core/src/error/specs/error.effect.spec.ts
@@ -7,9 +7,8 @@ import { HttpError } from '../error.model';
const createMockRes = () => ({} as HttpResponse);
const createMockReq = (url = '/') => ({ url } as HttpRequest);
-describe('Error effect', () => {
-
- it('error$ maps HttpError', () => {
+describe('error$', () => {
+ test('maps HttpError', () => {
const error = new HttpError('test-message', 400);
const expectedResponse = {
status: 400,
@@ -25,7 +24,7 @@ describe('Error effect', () => {
], { response: createMockRes(), error });
});
- it('error$ maps other errors', () => {
+ test('maps other errors', () => {
const error = new Error('test-message');
const expectedResponse = {
status: 500,
@@ -40,16 +39,17 @@ describe('Error effect', () => {
['-a-', { a: expectedResponse }],
], { response: createMockRes(), error });
});
+});
- it('#errorEffectProvider provides error handler implementation', () => {
+describe('#errorEffectProvider', () => {
+ test('provides error handler implementation', () => {
const customError$ = req$ => req$.pipe(mapTo({ status: 500, body: 'error' }));
const effect = errorEffectProvider(customError$);
expect(effect).toBe(customError$);
});
- it('#errorEffectProvider provides default error handler implementation if not passed', () => {
+ test('provides default error handler implementation if not passed', () => {
const effect = errorEffectProvider();
expect(effect).toBe(error$);
});
-
});

MODIFY
packages/core/src/http.interface.ts
packages/core/src/http.interface.ts
@@ -27,7 +27,7 @@ export interface HttpResponse extends http.ServerResponse {
send: (effect: EffectResponse) => Observable<never>;
}
-export type HttpHeaders = Record<string, string>;
+export interface HttpHeaders extends Record<string, string> {}
export enum HttpMethodType {
POST,

MODIFY
packages/core/src/operators/use/use.operator.spec.ts
packages/core/src/operators/use/use.operator.spec.ts
import { tap } from 'rxjs/operators';
import { Marbles } from '../../+internal';
-import { Effect } from '../../effects/effects.interface';
+import { Middleware } from '../../effects/effects.interface';
import { HttpRequest } from '../../http.interface';
import { use } from './use.operator';
const createMockReq = (test = 0) => ({ test } as any as HttpRequest);
-const middleware$: Effect<HttpRequest> = request$ => request$
- .pipe(tap(req => req.test++));
+const middleware$: Middleware = req$ =>
+ req$.pipe(tap(req => req.test++));
describe('Use operator', () => {

MODIFY
packages/core/src/router/router.factory.ts
packages/core/src/router/router.factory.ts
-import { Effect } from '../effects/effects.interface';
-import { HttpRequest } from '../http.interface';
+import { Middleware } from '../effects/effects.interface';
import { isRouteEffectGroup, isRouteCombinerConfig } from './router.helpers';
import {
Routing,
@@ -14,7 +13,7 @@ import { combineMiddlewares } from '../effects/effects.combiner';
export const factorizeRouting = (
routes: (RouteEffect | RouteEffectGroup)[],
- middleware: Effect<HttpRequest>[] = [],
+ middleware: Middleware[] = [],
parentPath = '',
): Routing => {
const routing: Routing = [];
@@ -74,4 +73,3 @@ export function combineRoutes(
: [],
};
}
-

MODIFY
packages/core/src/router/router.interface.ts
packages/core/src/router/router.interface.ts
-import { HttpMethod } from '../http.interface';
-import { Effect, Middleware } from '../effects/effects.interface';
+import { HttpMethod, HttpRequest } from '../http.interface';
+import { Effect, Middleware, EffectResponse } from '../effects/effects.interface';
// Route
-export interface RouteEffect {
+export interface RouteEffect<T extends HttpRequest = HttpRequest> {
path: string;
method: HttpMethod;
- effect: Effect;
+ effect: Effect<T, EffectResponse>;
+ middleware?: Middleware;
}
export interface RouteEffectGroup {

refactor(core): Effect type definition