refac: api 시스템 교체
- procDecorator의 타입 복잡도를 낮춤 - 타입 에러가 살짝 더 깔끔함
This commit is contained in:
+52
-61
@@ -6,7 +6,7 @@ import {
|
||||
type ValidatorOptions,
|
||||
} from "class-validator";
|
||||
import { type ClassTransformOptions, plainToInstance } from "class-transformer";
|
||||
import type { InvalidProc, ProcDecorator, ProcDecoratorChain, ResolveChain } from './ProcDecorator/base.js';
|
||||
import type { Empty, ParseOutType, PostProcDecoratorRunner, ProcDecorator, ProcDecoratorChain, ProcDecoratorRunner, ResolveChain } from './ProcDecorator/base.js';
|
||||
import { clamp } from 'lodash-es';
|
||||
|
||||
export type APINamespace = {
|
||||
@@ -31,59 +31,44 @@ type ValidatorType<T> = T extends undefined ? undefined : ClassType<T>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type AnyAPIExecuter = APIExecuter<any, any, any, any>;
|
||||
|
||||
interface APIExecuter<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> {
|
||||
(query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response): Promise<R | E | true>;
|
||||
interface APIExecuter<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, CTX extends object> {
|
||||
(query: Q, ctx: CTX, expressReq: Request, expressRes: Response): Promise<R | E | true>;
|
||||
httpMethod: HttpMethod;
|
||||
argValidator?: ValidatorType<Q>;
|
||||
preDecorator: ProcDecorator<any, any>[];
|
||||
postDecorator: (ProcDecorator<any, any> | undefined)[];
|
||||
preDecorator: ProcDecoratorRunner<CTX, Empty>;
|
||||
postDecorator: PostProcDecoratorRunner<CTX>;
|
||||
}
|
||||
|
||||
export interface iAPI_GET<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends APIExecuter<R, E, Q, PD> {
|
||||
export interface iAPI_GET<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, CTX extends object> extends APIExecuter<R, E, Q, CTX> {
|
||||
httpMethod: 'get';
|
||||
}
|
||||
|
||||
export interface iAPI_POST<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends APIExecuter<R, E, Q, PD> {
|
||||
export interface iAPI_POST<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, CTX extends object> extends APIExecuter<R, E, Q, CTX> {
|
||||
httpMethod: 'post';
|
||||
}
|
||||
|
||||
export interface iAPI_PUT<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends APIExecuter<R, E, Q, PD> {
|
||||
export interface iAPI_PUT<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, CTX extends object> extends APIExecuter<R, E, Q, CTX> {
|
||||
httpMethod: 'put';
|
||||
}
|
||||
|
||||
export interface iAPI_DELETE<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends APIExecuter<R, E, Q, PD> {
|
||||
export interface iAPI_DELETE<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, CTX extends object> extends APIExecuter<R, E, Q, CTX> {
|
||||
httpMethod: 'delete';
|
||||
}
|
||||
|
||||
export interface iAPI_PATCH<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends APIExecuter<R, E, Q, PD> {
|
||||
export interface iAPI_PATCH<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, CTX extends object> extends APIExecuter<R, E, Q, CTX> {
|
||||
httpMethod: 'patch';
|
||||
}
|
||||
|
||||
export interface iAPI_HEAD<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends APIExecuter<R, E, Q, PD> {
|
||||
export interface iAPI_HEAD<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, CTX extends object> extends APIExecuter<R, E, Q, CTX> {
|
||||
httpMethod: 'head';
|
||||
}
|
||||
|
||||
function generateAPI<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain>(httpMethod: HttpMethod,
|
||||
function generateAPI<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, CTX extends object>(httpMethod: HttpMethod,
|
||||
argValidator: ValidatorType<Q> | undefined,
|
||||
procDecoratorChain: PD,
|
||||
callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>,
|
||||
): APIExecuter<R, E, Q, PD> {
|
||||
const preDecorator: ProcDecorator<any, any>[] = [];
|
||||
const postDecorator: (ProcDecorator<any, any> | undefined)[] = [];
|
||||
if (procDecoratorChain) {
|
||||
for (const procGen of procDecoratorChain) {
|
||||
const proc = procGen();
|
||||
if (Array.isArray(proc)) {
|
||||
preDecorator.push(proc[0]);
|
||||
postDecorator.push(undefined);
|
||||
}
|
||||
else {
|
||||
preDecorator.push(proc);
|
||||
postDecorator.push(proc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preDecorator: ProcDecoratorRunner<CTX, Empty>,
|
||||
postDecorator: PostProcDecoratorRunner<CTX>,
|
||||
callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise<R | E | true>,
|
||||
): APIExecuter<R, E, Q, CTX> {
|
||||
return Object.assign(
|
||||
callback,
|
||||
{
|
||||
@@ -96,79 +81,85 @@ function generateAPI<R extends ValidResponse, E extends InvalidResponse, Q exten
|
||||
}
|
||||
|
||||
export function GET<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, PD>(
|
||||
return <CTX extends object>([preDecorator, postDecorator]: readonly [ProcDecoratorRunner<CTX, Empty>, PostProcDecoratorRunner<CTX>]) => {
|
||||
return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, CTX>(
|
||||
'get',
|
||||
argValidator,
|
||||
procDecoratorChain,
|
||||
preDecorator,
|
||||
postDecorator,
|
||||
callback,
|
||||
) as iAPI_GET<R, E, Q, PD>;
|
||||
) as iAPI_GET<R, E, Q, CTX>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function POST<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, PD>(
|
||||
return <CTX extends object>([preDecorator, postDecorator]: readonly [ProcDecoratorRunner<CTX, Empty>, PostProcDecoratorRunner<CTX>]) => {
|
||||
return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, CTX>(
|
||||
'post',
|
||||
argValidator,
|
||||
procDecoratorChain,
|
||||
preDecorator,
|
||||
postDecorator,
|
||||
callback,
|
||||
) as iAPI_POST<R, E, Q, PD>;
|
||||
) as iAPI_POST<R, E, Q, CTX>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function PUT<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, PD>(
|
||||
return <CTX extends object>([preDecorator, postDecorator]: readonly [ProcDecoratorRunner<CTX, Empty>, PostProcDecoratorRunner<CTX>]) => {
|
||||
return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, CTX>(
|
||||
'put',
|
||||
argValidator,
|
||||
procDecoratorChain,
|
||||
preDecorator,
|
||||
postDecorator,
|
||||
callback,
|
||||
) as iAPI_PUT<R, E, Q, PD>;
|
||||
) as iAPI_PUT<R, E, Q, CTX>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function DELETE<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, PD>(
|
||||
return <CTX extends object>([preDecorator, postDecorator]: readonly [ProcDecoratorRunner<CTX, Empty>, PostProcDecoratorRunner<CTX>]) => {
|
||||
return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, CTX>(
|
||||
'delete',
|
||||
argValidator,
|
||||
procDecoratorChain,
|
||||
preDecorator,
|
||||
postDecorator,
|
||||
callback,
|
||||
) as iAPI_DELETE<R, E, Q, PD>;
|
||||
) as iAPI_DELETE<R, E, Q, CTX>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function PATCH<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, PD>(
|
||||
return <CTX extends object>([preDecorator, postDecorator]: readonly [ProcDecoratorRunner<CTX, Empty>, PostProcDecoratorRunner<CTX>]) => {
|
||||
return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, CTX>(
|
||||
'patch',
|
||||
argValidator,
|
||||
procDecoratorChain,
|
||||
preDecorator,
|
||||
postDecorator,
|
||||
callback,
|
||||
) as iAPI_PATCH<R, E, Q, PD>;
|
||||
) as iAPI_PATCH<R, E, Q, CTX>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function HEAD<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, PD>(
|
||||
return <CTX extends object>([preDecorator, postDecorator]: readonly [ProcDecoratorRunner<CTX, Empty>, PostProcDecoratorRunner<CTX>]) => {
|
||||
return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||
return generateAPI<R, E, Q, CTX>(
|
||||
'head',
|
||||
argValidator,
|
||||
procDecoratorChain,
|
||||
preDecorator,
|
||||
postDecorator,
|
||||
callback,
|
||||
) as iAPI_HEAD<R, E, Q, PD>;
|
||||
) as iAPI_HEAD<R, E, Q, CTX>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user