diff --git a/packages/framework/tests/provider-visibility-issue/auth-listener.ts b/packages/framework/tests/provider-visibility-issue/auth-listener.ts new file mode 100644 index 000000000..7c759fee6 --- /dev/null +++ b/packages/framework/tests/provider-visibility-issue/auth-listener.ts @@ -0,0 +1,18 @@ +import { eventDispatcher } from '@deepkit/event'; +import { httpWorkflow } from '@deepkit/http'; +import { AuthenticationModule } from './auth-module.js'; +import { SessionForRequest } from './session-for-request.dto.js'; + +export class AuthenticationListener { + @eventDispatcher.listen(httpWorkflow.onAuth) + onAuth(event: typeof httpWorkflow.onAuth.event, module: AuthenticationModule) { + event.injectorContext.set( + SessionForRequest, + new SessionForRequest( + 'sidValue', + 'uidValue', + ), + module + ); + } +} diff --git a/packages/framework/tests/provider-visibility-issue/auth-module.ts b/packages/framework/tests/provider-visibility-issue/auth-module.ts new file mode 100644 index 000000000..a7758f4aa --- /dev/null +++ b/packages/framework/tests/provider-visibility-issue/auth-module.ts @@ -0,0 +1,23 @@ +import { createModule } from '@deepkit/app'; +import { SessionForRequest } from './session-for-request.dto.js'; +import { AuthenticationListener } from './auth-listener.js'; +import { http } from '@deepkit/http'; + + +@http.controller('/auth') +class OAuth2Controller { + @http.GET('/whoami') + whoami(sess: SessionForRequest) { + // Trying to consume "SessionForRequest" within the same module it's provided – no luck + return sess; + } +} + +export class AuthenticationModule extends createModule({ + providers: [ + { provide: SessionForRequest, scope: 'http', useValue: undefined }, + ], + controllers: [OAuth2Controller], + listeners: [AuthenticationListener], + exports: [SessionForRequest], +}) { } diff --git a/packages/framework/tests/provider-visibility-issue/provider-visibility-issue.spec.ts b/packages/framework/tests/provider-visibility-issue/provider-visibility-issue.spec.ts new file mode 100644 index 000000000..078daae4a --- /dev/null +++ b/packages/framework/tests/provider-visibility-issue/provider-visibility-issue.spec.ts @@ -0,0 +1,59 @@ +import { expect, test } from '@jest/globals'; +import { http, HttpKernel, HttpRequest } from '@deepkit/http'; +import { App, createModule } from '@deepkit/app'; +import { FrameworkModule } from '../../src/module.js'; +import { SessionForRequest } from './session-for-request.dto.js'; +import { AuthenticationModule } from './auth-module.js'; + +test('provider-visibility-issue', async () => { + class IAMModule extends createModule({ exports: [AuthenticationModule] }) { + imports = [new AuthenticationModule()]; + } + + + @http.controller('/another') + class AnotherDomainModuleController { + @http.GET('/action') + action(sess: SessionForRequest) { + // Trying to consume "SessionForRequest" within another module – still no luck + return sess; + } + } + class AnotherDomainModule extends createModule({}) { + controllers = [AnotherDomainModuleController]; + } + + class DomainModule extends createModule({ exports: [IAMModule] }) { + imports = [new IAMModule(), new AnotherDomainModule()]; + } + + class InfrastructureModule extends createModule({ + // The whole issue gets "fixed" if DomainModule gets exported here, but what if I don't need to export it? + exports: [], + }) { + imports = [new DomainModule()]; + } + + const app = new App({ + imports: [ + new FrameworkModule({ debug: true }), + new InfrastructureModule(), + ], + providers: [], + }); + + /** + * These fail due to the following error: + * + * Controller for route /auth/whoami parameter resolving error: + * DependenciesUnmetError: Parameter sess is required but provider returned undefined. + */ + expect((await app.get(HttpKernel).request(HttpRequest.GET('/auth/whoami'))).json).toMatchObject({ + sessionId: 'sidValue', + userId: 'uidValue' + }); + expect((await app.get(HttpKernel).request(HttpRequest.GET('/another/action'))).json).toMatchObject({ + sessionId: 'sidValue', + userId: 'uidValue' + }); +}); diff --git a/packages/framework/tests/provider-visibility-issue/session-for-request.dto.ts b/packages/framework/tests/provider-visibility-issue/session-for-request.dto.ts new file mode 100644 index 000000000..b66fd65fe --- /dev/null +++ b/packages/framework/tests/provider-visibility-issue/session-for-request.dto.ts @@ -0,0 +1,6 @@ +export class SessionForRequest { + constructor( + public readonly sessionId: string, + public readonly userId: string, + ) {} +} diff --git a/packages/framework/tests/service-container.spec.ts b/packages/framework/tests/service-container.spec.ts index 90e1cd1a8..ba5793bc6 100644 --- a/packages/framework/tests/service-container.spec.ts +++ b/packages/framework/tests/service-container.spec.ts @@ -3,8 +3,9 @@ import { rpc } from '@deepkit/rpc'; import { App, AppModule, createModule, ServiceContainer } from '@deepkit/app'; import { FrameworkModule } from '../src/module.js'; import { Database, DatabaseEvent, DatabaseRegistry, MemoryDatabaseAdapter, Query } from '@deepkit/orm'; -import { EventDispatcher } from '@deepkit/event'; +import { eventDispatcher, EventDispatcher } from '@deepkit/event'; import { PrimaryKey } from '@deepkit/type'; +import { http, HttpKernel, HttpRequest, httpWorkflow } from '@deepkit/http'; test('controller', () => { class MyService {