UNPKG

@nestia/core

Version:

Super-fast validation decorators of NestJS

77 lines (72 loc) 2.21 kB
import { BadRequestException, ExecutionContext, createParamDecorator, } from "@nestjs/common"; import type express from "express"; import type { FastifyRequest } from "fastify"; import { get_text_body } from "./internal/get_text_body"; import { is_request_body_undefined } from "./internal/is_request_body_undefined"; import { validate_request_body } from "./internal/validate_request_body"; /** * Plain body decorator. * * `PlainBody` is a decorator function getting full body text from the HTTP * request. * * If you adjust the regular {@link Body} decorator function to the body * parameter, you can't get the full body text because the {@link Body} tries to * convert the body text to JSON object. Therefore, `@nestia/core` provides this * `PlainBody` decorator function to get the full body text. * * ```typescript * \@TypedRoute.Post("memo") * public store * ( * \@PlainBody() body: string * ): void; * ``` * * @author Jeongho Nam - https://github.com/samchon * @returns Parameter decorator */ export function PlainBody(): ParameterDecorator; /** @internal */ export function PlainBody( assert?: (input: unknown) => string, ): ParameterDecorator { const checker = assert ? validate_request_body("PlainBody")({ type: "assert", assert, }) : null; return createParamDecorator(async function PlainBody( _data: any, context: ExecutionContext, ) { const request: express.Request | FastifyRequest = context .switchToHttp() .getRequest(); if ( is_request_body_undefined(request) && (checker ?? (() => null))(undefined as any) === null ) return undefined; else if (!isTextPlain(request.headers["content-type"])) throw new BadRequestException(`Request body type is not "text/plain".`); const value: string = await get_text_body(request); if (checker) { const error: Error | null = checker(value); if (error !== null) throw error; } return value; })(); } /** @internal */ const isTextPlain = (text?: string): boolean => text !== undefined && text .split(";") .map((str) => str.trim()) .some((str) => str === "text/plain");