Skip to content

Commit f703e46

Browse files
committed
fix(platform-http): update the adapter configuration to be aligned with DI convention
1 parent 0623033 commit f703e46

File tree

12 files changed

+86
-136
lines changed

12 files changed

+86
-136
lines changed

packages/platform/platform-express/src/components/PlatformExpress.ts

+6-12
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,6 @@ declare global {
6464
export class PlatformExpress extends PlatformAdapter<Express.Application> {
6565
readonly NAME = "express";
6666

67-
readonly providers = [
68-
{
69-
token: PlatformHandler,
70-
useClass: PlatformExpressHandler
71-
},
72-
{token: PlatformResponse},
73-
{token: PlatformRequest},
74-
{token: PlatformApplication},
75-
{token: Platform}
76-
];
77-
7867
#multer: typeof multer;
7968

8069
constructor() {
@@ -286,4 +275,9 @@ export class PlatformExpress extends PlatformAdapter<Express.Application> {
286275
}
287276
}
288277

289-
adapter(PlatformExpress);
278+
adapter(PlatformExpress, [
279+
{
280+
token: PlatformHandler,
281+
useClass: PlatformExpressHandler
282+
}
283+
]);

packages/platform/platform-express/vitest.config.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ export default defineConfig(
1010
coverage: {
1111
...presets.test.coverage,
1212
thresholds: {
13-
statements: 96.63,
13+
statements: 96.61,
1414
branches: 95,
1515
functions: 100,
16-
lines: 96.63
16+
lines: 96.61
1717
}
1818
}
1919
}
2020
}
21-
);
21+
);

packages/platform/platform-http/src/common/fn/adapter.ts

+23-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
import {Type} from "@tsed/core";
2-
import {refValue} from "@tsed/di";
2+
import {GlobalProviders, injector, ProviderOpts, refValue} from "@tsed/di";
33

4-
import type {PlatformAdapter} from "../services/PlatformAdapter.js";
4+
import {PlatformAdapter} from "../services/PlatformAdapter.js";
55

66
const ADAPTER = "platform.adapter";
77

88
let globalAdapter: Type<PlatformAdapter<any>>;
99

1010
/**
11-
* Set the platform adapter
11+
* Set the platform adapter token and his dependencies
1212
*/
13-
export function adapter(adapter?: Type<PlatformAdapter<any>>): Type<PlatformAdapter<any>> {
13+
export function adapter(adapter: Type<PlatformAdapter<any>>, imports?: ProviderOpts[]): Type<PlatformAdapter<any>>;
14+
/**
15+
* Get the platform adapter token
16+
*/
17+
export function adapter(): Type<PlatformAdapter<any>>;
18+
export function adapter(adapter?: Type<PlatformAdapter<any>>, imports: ProviderOpts[] = []): Type<PlatformAdapter<any>> {
1419
const ref = refValue<Type<PlatformAdapter<any>>>(ADAPTER);
1520

1621
if (adapter) {
1722
globalAdapter ||= adapter;
23+
24+
imports?.forEach(({token, useClass}) => {
25+
const provider = GlobalProviders.get(token);
26+
if (useClass && provider) {
27+
provider.useClass = useClass;
28+
injector().set(token, provider);
29+
}
30+
});
31+
32+
injector()
33+
.addProvider(PlatformAdapter, {
34+
useClass: adapter
35+
})
36+
.alias(PlatformAdapter, "PlatformAdapter");
1837
}
1938

2039
ref.value ||= globalAdapter;

packages/platform/platform-http/src/common/middlewares/PlatformMulterMiddleware.spec.ts

+12-14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import {catchAsyncError} from "@tsed/core";
2+
import {inject} from "@tsed/di";
23
import {Exception} from "@tsed/exceptions";
34
import {MulterError} from "multer";
45

56
import {PlatformTest} from "../../testing/PlatformTest.js";
67
import {MulterOptions} from "../decorators/multer/multerOptions.js";
78
import {MultipartFile} from "../decorators/multer/multipartFile.js";
89
import {EndpointMetadata} from "../domain/EndpointMetadata.js";
10+
import {PlatformAdapter} from "../services/PlatformAdapter.js";
911
import {PlatformApplication} from "../services/PlatformApplication.js";
1012
import {PlatformMulterMiddleware} from "./PlatformMulterMiddleware.js";
1113

@@ -19,20 +21,16 @@ async function build(options = {}) {
1921
const multer = {
2022
fields: vi.fn().mockReturnValue(multerMiddleware)
2123
};
22-
const app = {
23-
multer: vi.fn().mockReturnValue(multer)
24-
};
2524

26-
const middleware = await PlatformTest.invoke<PlatformMulterMiddleware>(PlatformMulterMiddleware, [
27-
{
28-
token: PlatformApplication,
29-
use: app
30-
}
31-
]);
25+
const middleware = inject(PlatformMulterMiddleware);
3226
const ctx: any = PlatformTest.createRequestContext();
3327
ctx.endpoint = EndpointMetadata.get(Test, "upload");
3428

35-
return {middleware, ctx, multer, app, multerMiddleware};
29+
const adapter = inject(PlatformAdapter);
30+
31+
vi.spyOn(adapter, "multipart").mockReturnValue(multer as any);
32+
33+
return {middleware, ctx, multer, adapter, multerMiddleware};
3634
}
3735

3836
describe("PlatformMulterMiddleware", () => {
@@ -45,24 +43,24 @@ describe("PlatformMulterMiddleware", () => {
4543
);
4644
afterEach(() => PlatformTest.reset());
4745
it("should create middleware", async () => {
48-
const {middleware, ctx, multer, app, multerMiddleware} = await build({});
46+
const {middleware, ctx, multer, adapter, multerMiddleware} = await build({});
4947

5048
await middleware.use(ctx);
5149

52-
expect(app.multer).toHaveBeenCalledWith({
50+
expect(adapter.multipart).toHaveBeenCalledWith({
5351
dest: "/dest"
5452
});
5553
expect(multer.fields).toHaveBeenCalledWith([{maxCount: undefined, name: "file1"}]);
5654
expect(multerMiddleware).toHaveBeenCalledWith(ctx.request.raw, ctx.response.raw);
5755
});
5856
it("should create middleware with storage", async () => {
59-
const {middleware, ctx, multer, app, multerMiddleware} = await build({
57+
const {middleware, ctx, multer, adapter, multerMiddleware} = await build({
6058
storage: "storage"
6159
});
6260

6361
await middleware.use(ctx);
6462

65-
expect(app.multer).toHaveBeenCalledWith({
63+
expect(adapter.multipart).toHaveBeenCalledWith({
6664
storage: "storage"
6765
});
6866
expect(multer.fields).toHaveBeenCalledWith([{maxCount: undefined, name: "file1"}]);

packages/platform/platform-http/src/common/middlewares/PlatformMulterMiddleware.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {MulterError} from "multer";
66

77
import {PlatformMulterField, PlatformMulterSettings} from "../config/interfaces/PlatformMulterSettings.js";
88
import {PlatformContext} from "../domain/PlatformContext.js";
9+
import {PlatformAdapter} from "../services/PlatformAdapter.js";
910
import {PlatformApplication} from "../services/PlatformApplication.js";
1011

1112
export interface MulterInputOptions {
@@ -24,8 +25,6 @@ export class MulterException extends BadRequest {
2425
* @middleware
2526
*/
2627
export class PlatformMulterMiddleware implements MiddlewareMethods {
27-
protected app = inject(PlatformApplication);
28-
2928
async use(@Context() ctx: PlatformContext) {
3029
try {
3130
const {fields, options = {}} = ctx.endpoint.get(PlatformMulterMiddleware);
@@ -39,7 +38,7 @@ export class PlatformMulterMiddleware implements MiddlewareMethods {
3938
delete settings.dest;
4039
}
4140

42-
const multer = this.app.multer(settings);
41+
const multer = inject(PlatformAdapter).multipart(settings);
4342

4443
if (multer) {
4544
const middleware: any = multer.fields(this.getFields({fields}));

packages/platform/platform-http/src/common/services/PlatformAdapter.ts

+18-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {IncomingMessage, ServerResponse} from "node:http";
22

33
import {Type} from "@tsed/core";
4-
import {injectable, ProviderOpts} from "@tsed/di";
4+
import {configuration, constant, inject, injectable} from "@tsed/di";
5+
import {$on} from "@tsed/hooks";
56
import {PlatformHandlerMetadata, PlatformLayer} from "@tsed/platform-router";
67

78
import {PlatformMulter, PlatformMulterSettings} from "../config/interfaces/PlatformMulterSettings.js";
@@ -10,17 +11,25 @@ import {application} from "../fn/application.js";
1011
import {createHttpServer} from "../utils/createHttpServer.js";
1112
import {createHttpsServer} from "../utils/createHttpsServer.js";
1213
import {CreateServerReturn} from "../utils/createServer.js";
13-
import type {PlatformApplication} from "./PlatformApplication.js";
14+
import {Platform} from "./Platform.js";
15+
import {PlatformApplication} from "./PlatformApplication.js";
16+
import {PlatformHandler} from "./PlatformHandler.js";
1417

1518
export abstract class PlatformAdapter<App = TsED.Application> {
1619
abstract readonly NAME: string;
17-
/**
18-
* Load providers in top priority
19-
*/
20-
providers: ProviderOpts[] = [];
2120

22-
get app(): PlatformApplication<App> {
23-
return application();
21+
readonly app = inject<PlatformApplication<App>>(PlatformApplication);
22+
23+
constructor() {
24+
const platformApp = inject(PlatformApplication);
25+
26+
const {app, callback} = this.createApp();
27+
platformApp.rawApp = app as any;
28+
platformApp.rawCallback = callback;
29+
30+
$on("$afterInvoke", PlatformAdapter, () => {
31+
configuration().set("PLATFORM_NAME", constant("PLATFORM_NAME") || this.NAME);
32+
});
2433
}
2534

2635
getServers(): CreateServerReturn[] {
@@ -87,4 +96,4 @@ export interface PlatformBuilderSettings<App = TsED.Application> extends Partial
8796
adapter?: Type<PlatformAdapter<App>>;
8897
}
8998

90-
injectable(PlatformAdapter).alias("PlatformAdapter");
99+
injectable(PlatformAdapter).imports([PlatformApplication, Platform, PlatformHandler]).alias("PlatformAdapter");

packages/platform/platform-http/src/common/services/PlatformApplication.spec.ts

-12
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ async function getPlatformApp() {
3333
]);
3434
configuration().logger = {};
3535
platformApp.rawApp = createDriver() as any;
36-
vi.spyOn(platformApp, "multer").mockReturnValue({} as never);
3736

3837
return {platformApp, platformHandler};
3938
}
@@ -63,17 +62,6 @@ describe("PlatformApplication", () => {
6362
platformApp.statics("/", {root: "/root"});
6463
});
6564
});
66-
describe("multer()", () => {
67-
it("should call statics", async () => {
68-
// GIVEN
69-
const {platformApp} = await getPlatformApp();
70-
71-
vi.spyOn(console, "warn");
72-
73-
// WHEN
74-
platformApp.multer({});
75-
});
76-
});
7765

7866
describe("callback()", () => {
7967
it("should return the callback", async () => {

packages/platform/platform-http/src/common/services/PlatformApplication.ts

+2-19
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import {IncomingMessage, ServerResponse} from "node:http";
22

3-
import {inject, injectable, ProviderScope} from "@tsed/di";
3+
import {injectable, ProviderScope} from "@tsed/di";
44
import {PlatformRouter} from "@tsed/platform-router";
55

6-
import {PlatformMulterSettings} from "../config/interfaces/PlatformMulterSettings.js";
7-
import {PlatformAdapter} from "./PlatformAdapter.js";
8-
96
declare global {
107
namespace TsED {
118
// @ts-ignore
@@ -19,28 +16,14 @@ declare global {
1916
* @platform
2017
*/
2118
export class PlatformApplication<App = TsED.Application> extends PlatformRouter {
22-
adapter: PlatformAdapter<App> = inject(PlatformAdapter<App>);
23-
2419
rawApp: App;
25-
rawCallback: () => any;
2620

27-
constructor() {
28-
super();
29-
30-
const {app, callback} = this.adapter.createApp();
31-
32-
this.rawApp = app;
33-
this.rawCallback = callback;
34-
}
21+
rawCallback(): any {}
3522

3623
getApp(): App {
3724
return this.rawApp;
3825
}
3926

40-
multer(options: PlatformMulterSettings) {
41-
return this.adapter.multipart(options);
42-
}
43-
4427
callback(): (req: IncomingMessage, res: ServerResponse) => any;
4528
callback(req: IncomingMessage, res: ServerResponse): any;
4629
callback(req?: IncomingMessage, res?: ServerResponse) {

packages/platform/platform-http/src/common/services/PlatformHandler.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {JsonOperationRoute} from "@tsed/schema";
1515
import {AnyToPromiseWithCtx} from "../domain/AnyToPromiseWithCtx.js";
1616
import {PlatformContext} from "../domain/PlatformContext.js";
1717
import {setResponseHeaders} from "../utils/setResponseHeaders.js";
18-
import {PlatformApplication} from "./PlatformApplication.js";
18+
import {PlatformAdapter} from "./PlatformAdapter.js";
1919
import {PlatformMiddlewaresChain} from "./PlatformMiddlewaresChain.js";
2020

2121
/**
@@ -26,7 +26,6 @@ export class PlatformHandler {
2626
protected responseFilter = inject(PlatformResponseFilter);
2727
protected platformParams = inject(PlatformParams);
2828
protected platformExceptions = inject(PlatformExceptions);
29-
protected platformApplication = inject(PlatformApplication);
3029
protected platformMiddlewaresChain = inject(PlatformMiddlewaresChain);
3130
protected platformRouters = inject(PlatformRouters);
3231

@@ -43,7 +42,7 @@ export class PlatformHandler {
4342
.on("alterHandler", (handlerMetadata: PlatformHandlerMetadata) => {
4443
const handler = handlerMetadata.isInjectable() ? this.createHandler(handlerMetadata) : handlerMetadata.handler;
4544

46-
return this.platformApplication.adapter.mapHandler(handler, handlerMetadata);
45+
return inject(PlatformAdapter).mapHandler(handler, handlerMetadata);
4746
});
4847
}
4948

packages/platform/platform-http/src/common/services/PlatformMiddlewaresChain.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import {isClass} from "@tsed/core";
2-
import {constant, inject, injectable} from "@tsed/di";
2+
import {constant, injectable} from "@tsed/di";
33
import {ParamTypes} from "@tsed/platform-params";
44
import {AlterEndpointHandlersArg} from "@tsed/platform-router";
55
import {JsonEntityStore, JsonOperationRoute} from "@tsed/schema";
66

77
import {PlatformAcceptMimesMiddleware} from "../middlewares/PlatformAcceptMimesMiddleware.js";
88
import {PlatformMulterMiddleware} from "../middlewares/PlatformMulterMiddleware.js";
9-
import {PlatformAdapter} from "./PlatformAdapter.js";
109

1110
export class PlatformMiddlewaresChain {
1211
protected acceptMimes = constant<string[]>("acceptMimes", []);
13-
protected adapter = inject(PlatformAdapter);
1412

1513
get(handlers: AlterEndpointHandlersArg, operationRoute: JsonOperationRoute): AlterEndpointHandlersArg {
1614
const {ACCEPT_MIMES, FILE} = this.getParamTypes(handlers, operationRoute);

0 commit comments

Comments
 (0)