diff --git a/packages/core/src/http/server/http.server.spec.ts b/packages/core/src/http/server/http.server.spec.ts index b9e92040..9a0554a6 100644 --- a/packages/core/src/http/server/http.server.spec.ts +++ b/packages/core/src/http/server/http.server.spec.ts @@ -4,9 +4,11 @@ import * as https from 'https'; import { EventEmitter } from 'events'; import { forkJoin } from 'rxjs'; import { tap, filter, take } from 'rxjs/operators'; +import { pipe, constant } from 'fp-ts/lib/function'; import { HttpServer } from '../http.interface'; -import { lookup } from '../../context/context'; +import { lookup, bindTo } from '../../context/context'; import { useContext } from '../../context/context.hook'; +import { createContextToken } from '../../context/context.token.factory'; import { HttpServerClientToken } from './internal-dependencies/httpServerClient.reader'; import { httpListener } from './http.server.listener'; import { createServer } from './http.server'; @@ -99,20 +101,45 @@ describe('#createServer', () => { expect(boundServer).toBeDefined(); }); + test('can register `nullable` context dependency', async () => { + // given - context dependency + const someToken = createContextToken(); + const someDependency = 'test'; + + // given - server + const app = await createServer({ + listener: httpListener(), + dependencies: [ + bindTo(someToken)(constant(someDependency)), + undefined, + ], + }); + + // when + server = await app(); + + // then + const ask = lookup(app.context); + const boundDependency = useContext(someToken)(ask); + + expect(boundDependency).toEqual(someDependency); + }); + test(`emits server events`, async done => { const app = await createServer({ listener: httpListener(), - event$: event$ => forkJoin( - event$.pipe(filter(isErrorEvent), take(1)), - event$.pipe(filter(isClientErrorEvent), take(1)), - event$.pipe(filter(isCloseEvent), take(1)), - event$.pipe(filter(isConnectEvent), take(1)), - event$.pipe(filter(isConnectionEvent), take(1)), - event$.pipe(filter(isListeningEvent), take(1)), - event$.pipe(filter(isUpgradeEvent), take(1)), - event$.pipe(filter(isCheckContinueEvent), take(1)), - event$.pipe(filter(isCheckExpectationEvent), take(1)), - ).pipe( + event$: event$ => pipe( + forkJoin([ + event$.pipe(filter(isErrorEvent), take(1)), + event$.pipe(filter(isClientErrorEvent), take(1)), + event$.pipe(filter(isCloseEvent), take(1)), + event$.pipe(filter(isConnectEvent), take(1)), + event$.pipe(filter(isConnectionEvent), take(1)), + event$.pipe(filter(isListeningEvent), take(1)), + event$.pipe(filter(isUpgradeEvent), take(1)), + event$.pipe(filter(isCheckContinueEvent), take(1)), + event$.pipe(filter(isCheckExpectationEvent), take(1)), + ]), tap(() => done()), ), }); diff --git a/packages/core/src/http/server/http.server.ts b/packages/core/src/http/server/http.server.ts index 3dc04945..361172e4 100644 --- a/packages/core/src/http/server/http.server.ts +++ b/packages/core/src/http/server/http.server.ts @@ -2,11 +2,12 @@ import * as http from 'http'; import * as https from 'https'; import { merge, EMPTY } from 'rxjs'; import { takeWhile } from 'rxjs/operators'; -import { pipe } from 'fp-ts/lib/pipeable'; +import { pipe } from 'fp-ts/lib/function'; +import { filter } from 'fp-ts/lib/Array'; import { lookup, bindTo, bindEagerlyTo } from '../../context/context'; import { createEffectContext } from '../../effects/effectsContext.factory'; import { isTestingMetadataOn } from '../../+internal/testing'; -import { insertIf } from '../../+internal/utils'; +import { insertIf, isNonNullable } from '../../+internal/utils'; import { HttpServer } from '../http.interface'; import { logContext } from '../../context/context.logger'; import { contextFactory } from '../../context/context.helper'; @@ -40,7 +41,7 @@ export const createServer = async (config: CreateServerConfig) => { boundHttpServerEvent, boundHttpRequestBus, ...insertIf(isTestingMetadataOn())(boundHttpRequestMetadataStorage), - ...dependencies, + ...filter(isNonNullable)(dependencies), ); logContext(LoggerTag.HTTP)(context); diff --git a/packages/core/src/listener/listener.interface.ts b/packages/core/src/listener/listener.interface.ts index 0e2ed753..ed5c750a 100644 --- a/packages/core/src/listener/listener.interface.ts +++ b/packages/core/src/listener/listener.interface.ts @@ -29,5 +29,5 @@ export interface ServerConfig< > { event$?: T; listener: U; - dependencies?: BoundDependency[]; + dependencies?: (BoundDependency | undefined | null)[]; } diff --git a/packages/messaging/src/server/messaging.server.ts b/packages/messaging/src/server/messaging.server.ts index 71142287..35c6b0d0 100644 --- a/packages/messaging/src/server/messaging.server.ts +++ b/packages/messaging/src/server/messaging.server.ts @@ -1,10 +1,10 @@ import * as E from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; +import { identity, pipe } from 'fp-ts/lib/function'; +import { filter } from 'fp-ts/lib/Array'; import { Subject } from 'rxjs'; import { takeWhile, takeUntil, take } from 'rxjs/operators'; import { bindTo, createEffectContext, combineEffects, ServerIO, lookup, logContext, LoggerTag, contextFactory } from '@marblejs/core'; -import { throwException, maskUriComponent } from '@marblejs/core/dist/+internal/utils'; +import { throwException, maskUriComponent, isNonNullable } from '@marblejs/core/dist/+internal/utils'; import { provideTransportLayer } from '../transport/transport.provider'; import { statusLogger$ } from '../middlewares/messaging.statusLogger.middleware'; import { TransportLayerConnection } from '../transport/transport.interface'; @@ -35,7 +35,7 @@ export const createMicroservice = async (config: CreateMicroserviceConfig) => { boundEventTimerStore, boundTransportLayer, boundServerEvents, - ...dependencies, + ...filter(isNonNullable)(dependencies), ); logContext(LoggerTag.MESSAGING)(context); diff --git a/packages/websockets/src/server/websocket.server.ts b/packages/websockets/src/server/websocket.server.ts index b6cf3fc5..d6916e94 100644 --- a/packages/websockets/src/server/websocket.server.ts +++ b/packages/websockets/src/server/websocket.server.ts @@ -3,8 +3,9 @@ import * as net from 'net'; import * as WebSocket from 'ws'; import { Observable, of } from 'rxjs'; import { map, takeWhile } from 'rxjs/operators'; +import { filter } from 'fp-ts/lib/Array'; import { Context, contextFactory, createEffectContext, ServerIO, LoggerTag, lookup, logContext, combineEffects } from '@marblejs/core'; -import { createUuid, isNullable } from '@marblejs/core/dist/+internal/utils'; +import { createUuid, isNonNullable, isNullable } from '@marblejs/core/dist/+internal/utils'; import { createServer, handleServerBrokenConnections, handleClientBrokenConnection } from '../server/websocket.server.helper'; import { WebSocketConnectionError } from '../error/websocket.error.model'; import { statusLogger$ } from '../middlewares/websockets.statusLogger.middleware'; @@ -34,7 +35,7 @@ export const createWebSocketServer = async (config: WebSocketServerConfig) => { ); }; - const context = await contextFactory(...dependencies); + const context = await contextFactory(...filter(isNonNullable)(dependencies)); logContext(LoggerTag.WEBSOCKETS)(context);