Skip to content

Commit

Permalink
Merge pull request #13 from medishen/dev/v2
Browse files Browse the repository at this point in the history
feat: Refactor module and context handling with new redirect method a…
  • Loading branch information
0xii00 authored Jan 16, 2025
2 parents c32557b + ddb19a0 commit 7191af7
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 47 deletions.
3 changes: 1 addition & 2 deletions lib/common/interfaces/context.interface.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Stream } from 'stream';
import { IncomingMessage, ServerResponse } from 'http';
import { Context } from 'mocha';
import { HttpStatus } from '../enums';
import { GlobalCache, ParsedBody } from '../types';
import { AppConfig } from './app-settings.interface';
import { RouteDefinition } from './router.interface';
import { Application } from '../../core/Application';
export type ServerRequest = Context & {
export type ServerRequest = {
req: IncomingMessage;
res: ServerResponse;
status: HttpStatus;
Expand Down
6 changes: 6 additions & 0 deletions lib/context/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class Context {
this.ctx.send = this.send.bind(this);
this.ctx.status = this.status;
this.ctx.language = this.lang;
this.ctx.redirect = this.redirect.bind(this);
}
get status() {
return this.ctx.res.statusCode;
Expand Down Expand Up @@ -106,4 +107,9 @@ export class Context {
);
}
}
redirect(url: string, status: HttpStatus = HttpStatus.MOVED_PERMANENTLY): void {
this.status = status;
this.res.setHeader('Location', url);
this.res.end();
}
}
44 changes: 2 additions & 42 deletions lib/core/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,51 +205,11 @@ export class Application {
return this.settings[key];
}

// Create the application instance
static create(rootModule: Constructor<any>, config?: AppConfig) {
const moduleMetadata = Reflector.get(ModuleMetadataKeys.MODULE, rootModule);
if (!moduleMetadata) {
throw new Error(`The provided class is not a valid module. Ensure it is decorated with @Module.`);
}
const app = new Application(config);
// Initialize the injector
const injector = Application.injector;
// Register all providers from the root module
this.registerModuleProviders(rootModule, injector);

// Resolve and instantiate controllers
const controllers = moduleMetadata.controllers || [];
controllers.forEach((controller: Constructor<any>) => {
const controllerPrefix = Reflector.get(RouterMetadataKeys.CONTROLLER_PREFIX, controller);
const routes = Reflector.get(RouterMetadataKeys.ROUTES, controller) || [];
const controllerInstance = Application.instantiateController(controller, injector);
routes.forEach((route: RouteDefinition) => {
route.path = `${controllerPrefix}${route.path}`;
route.action = route.action.bind(controllerInstance);
});
});
const injector = Application.injector;
injector.initializeModule(rootModule);
return app;
}
/**
* Recursively register providers from the module and its imports.
*/
private static registerModuleProviders(module: Constructor<any>, injector: Injector) {
const moduleMetadata = Reflector.get(ModuleMetadataKeys.MODULE, module);
if (!moduleMetadata) return;

// Register module's own providers
(moduleMetadata.providers ?? []).forEach((provider: Provider) => {
injector.register(provider);
});

// Recursively register imported modules
(moduleMetadata.imports ?? []).forEach((importedModule: Constructor<any>) => {
this.registerModuleProviders(importedModule, injector);
});
}
private static instantiateController(controller: Constructor<any>, injector: Injector) {
const dependencies = Reflector.get(ModuleMetadataKeys.PARAM_DEPENDENCIES, controller) || [];
const resolvedDeps = dependencies.map((dep: any) => injector.resolve(dep.param));
return new controller(...resolvedDeps);
}
}
39 changes: 37 additions & 2 deletions lib/decorator/module/Injector.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ModuleMetadataKeys } from '../../common/enums';
import { ClassProvider, ValueProvider, FactoryProvider, ExistingProvider, Constructor } from '../../common/interfaces';
import { ModuleMetadataKeys, RouterMetadataKeys } from '../../common/enums';
import { ClassProvider, ValueProvider, FactoryProvider, ExistingProvider, Constructor, RouteDefinition } from '../../common/interfaces';
import { InjectionToken, Provider } from '../../common/types';
import Reflector from '../../metadata';

Expand Down Expand Up @@ -79,4 +79,39 @@ export class Injector {
private isExistingProvider(provider: Provider): provider is ExistingProvider {
return (provider as ExistingProvider).useExisting !== undefined;
}
private registerModuleDependencies(module: Constructor<any>) {
const moduleMetadata = Reflector.get(ModuleMetadataKeys.MODULE, module);
if (!moduleMetadata) return;

(moduleMetadata.providers ?? []).forEach((provider: Provider) => {
this.register(provider);
});

(moduleMetadata.imports ?? []).forEach((importedModule: Constructor<any>) => {
this.registerModuleDependencies(importedModule);
});
}
private createControllerInstance(controller: Constructor<any>) {
const dependencies = Reflector.get(ModuleMetadataKeys.PARAM_DEPENDENCIES, controller) || [];
const resolvedDeps = dependencies.map((dep: any) => this.resolve(dep.param));
return new controller(...resolvedDeps);
}
public initializeModule(rootModule: Constructor<any>) {
const moduleMetadata = Reflector.get(ModuleMetadataKeys.MODULE, rootModule);
if (!moduleMetadata) {
throw new Error(`The provided class is not a valid module. Ensure it is decorated with @Module.`);
}
this.registerModuleDependencies(rootModule);

const controllers = moduleMetadata.controllers || [];
controllers.forEach((controller: Constructor<any>) => {
const controllerPrefix = Reflector.get(RouterMetadataKeys.CONTROLLER_PREFIX, controller);
const routes = Reflector.get(RouterMetadataKeys.ROUTES, controller) || [];
const controllerInstance = this.createControllerInstance(controller);
routes.forEach((route: RouteDefinition) => {
route.path = `${controllerPrefix}${route.path}`;
route.action = route.action.bind(controllerInstance);
});
});
}
}
1 change: 0 additions & 1 deletion lib/decorator/module/Module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export function Inject(token?: InjectionToken): PropertyDecorator & ParameterDec
const injectCallHasArguments = arguments.length > 0;
return (target: object, key: string | symbol | undefined, index?: number) => {
let type = token || Reflector.get(ModuleMetadataKeys.PARAM_DEPENDENCIES, target, key!);
console.log('type', type);

if (!type && !injectCallHasArguments) {
type = Reflector.get(ModuleMetadataKeys.PARAM_DEPENDENCIES, target, key!)?.[index!];
Expand Down

0 comments on commit 7191af7

Please sign in to comment.