@nestia/core
Version:
Super-fast validation decorators of NestJS
77 lines (72 loc) • 2.21 kB
text/typescript
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");