Skip to content

Commit

Permalink
feat: add @Render decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
rsaz committed Jul 23, 2024
1 parent a879f96 commit 522d6e2
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/adapter-express/express-utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export const HTTP_CODE_METADATA = {
path: "inversify-express-utils:path",
};

export const RENDER_METADATA_KEY = Symbol("Render");

export enum PARAMETER_TYPE {
REQUEST,
RESPONSE,
Expand Down
24 changes: 24 additions & 0 deletions src/adapter-express/express-utils/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
PARAMETER_TYPE,
HTTP_VERBS_ENUM,
HTTP_CODE_METADATA,
RENDER_METADATA_KEY,
} from "./constants";
import type {
Controller,
Expand Down Expand Up @@ -383,6 +384,29 @@ export function params(type: PARAMETER_TYPE, parameterName?: string): ParameterD
};
}

/**
* Render decorator to define the template and default data for a route
* @param template The template to render
* @param defaultData The default data to pass to the template
* @returns
*/
export function Render(template: string, defaultData?: Record<string, unknown>): MethodDecorator {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void => {
Reflect.defineMetadata(RENDER_METADATA_KEY, { template, defaultData }, target, propertyKey);
};
}

export function getRenderMetadata(
target: object,
propertyKey: string | symbol,
): {
template?: string;
defaultData?: Record<string, unknown>;
} {
return Reflect.getMetadata(RENDER_METADATA_KEY, target, propertyKey) || {};
}

/**
* Converts a string value to the specified type.
* @param value The value to convert.
Expand Down
22 changes: 14 additions & 8 deletions src/adapter-express/express-utils/inversify-express-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import type {
RoutingConfig,
} from "./interfaces";
import type { OutgoingHttpHeaders } from "node:http";
import { getRenderMetadata } from "./decorators";

export class InversifyExpressServer {
private _router: Router;
Expand Down Expand Up @@ -245,21 +246,26 @@ export class InversifyExpressServer {
controllerName: string,
key: string,
parameterMetadata: Array<ParameterMetadata>,
): express.RequestHandler {
): RequestHandler {
return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const args = this.extractParameters(req, res, next, parameterMetadata);
const httpContext = this._getHttpContext(req);
httpContext.container.bind<HttpContext>(TYPE.HttpContext).toConstantValue(httpContext);

// invoke controller's action
const value = await (
httpContext.container.getNamed<BaseController>(TYPE.Controller, controllerName)[
key
] as ControllerHandler
)(...args);

if (value instanceof HttpResponseMessage) {
const controller = httpContext.container.getNamed<BaseController>(
TYPE.Controller,
controllerName,
);
const value = await (controller[key] as ControllerHandler)(...args);

const { template, defaultData } = getRenderMetadata(controller, key);

if (template) {
const data = value || defaultData || {};
res.render(template, data as Record<string, unknown>);
} else if (value instanceof HttpResponseMessage) {
await this.handleHttpResponseMessage(value, res);
} else if (instanceOfIHttpActionResult(value)) {
const httpResponseMessage = await value.executeAsync();
Expand Down

0 comments on commit 522d6e2

Please sign in to comment.