import type { Request, Response } from 'express'; export interface ValidResponse { result: true; } export type recoveryMethod = 'refreshEntirePage' | 'retryAPI' | 'gameLogin' | 'gatewayLogin' | 'gatewayPIN'; export interface InvalidResponse { result: false; reason: string; recovery?: recoveryMethod; } export const treatedSpecial = Symbol('treatedSpecial'); export type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'; export type RawArgType = Record | Record[] | undefined; export type APINamespace = { [key: string]: APINamespace | GET | POST | PUT | DELETE | PATCH | HEAD ; } export abstract class APIExecuter{ readonly reqType: HttpMethod | HttpMethod[]; protected abstract parseQuery(expressReq: Request): Promise; protected abstract api(query: Q, expressReq: Request, expressRes: Response): Promise; public async run(expressReq: Request, expressRes: Response): Promise { const query = await this.parseQuery(expressReq); //TODO: middleware (인증, 요구사항, 아마도 decorator) const result = await this.api(query, expressReq, expressRes); if (result === treatedSpecial) { return; } expressRes.json(result); } } export abstract class APIBodyParseExecuter extends APIExecuter{ protected async parseQuery(expressReq: Request): Promise { throw new Error('Not implemented'); return expressReq.body; } } export abstract class GET extends APIExecuter{ readonly reqType = 'get'; protected async parseQuery(expressReq: Request): Promise { expressReq.query; throw new Error('Not implemented'); return expressReq.query as unknown as Q; } } export abstract class POST extends APIBodyParseExecuter{ readonly reqType = 'post'; } export abstract class PUT extends APIBodyParseExecuter{ readonly reqType = 'put'; } export abstract class DELETE extends APIBodyParseExecuter{ readonly reqType = 'delete'; } export abstract class PATCH extends APIBodyParseExecuter{ readonly reqType = 'patch'; } export abstract class HEAD extends APIBodyParseExecuter{ readonly reqType = 'head'; }