diff --git a/server/apiStructure/defs.ts b/server/apiStructure/defs.ts index 48b563f..75452d1 100644 --- a/server/apiStructure/defs.ts +++ b/server/apiStructure/defs.ts @@ -5,61 +5,253 @@ export type RawArgType = Record | Record[] | u export interface BasicAPICallT< - ArgType extends RawArgType, - ResultType extends ValidResponse, - ErrorType extends InvalidResponse + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse > { - (args: ArgType): Promise; - (args: ArgType, returnError: false): Promise; - (args: ArgType, returnError: true): Promise; + (args: ArgType): Promise; + (args: ArgType, returnError: false): Promise; + (args: ArgType, returnError: true): Promise; + readonly reqType: HttpMethod; } +export type BasicGetAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = BasicAPICallT & { readonly reqType: 'get' }; + +export type BasicPostAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = BasicAPICallT & { readonly reqType: 'post' }; + +export type BasicPutAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = BasicAPICallT & { readonly reqType: 'put' }; + +export type BasicDeleteAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = BasicAPICallT & { readonly reqType: 'delete' }; + +export type BasicPatchAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = BasicAPICallT & { readonly reqType: 'patch' }; + +export type BasicHeadAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = BasicAPICallT & { readonly reqType: 'head' }; + export interface EmptyAPICallT { - (): Promise; - (args: undefined): Promise; - (args: undefined, returnError: false): Promise; - (args: undefined, returnError: true): Promise; + (): Promise; + (args?: undefined): Promise; + (args: undefined, returnError: false): Promise; + (args: undefined, returnError: true): Promise; + readonly reqType: HttpMethod; } +export type EmptyGetAPICallT< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = EmptyAPICallT & { readonly reqType: 'get' }; + +export type EmptyPostAPICallT< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = EmptyAPICallT & { readonly reqType: 'post' }; + +export type EmptyPutAPICallT< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = EmptyAPICallT & { readonly reqType: 'put' }; + +export type EmptyDeleteAPICallT< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = EmptyAPICallT & { readonly reqType: 'delete' }; + +export type EmptyPatchAPICallT< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = EmptyAPICallT & { readonly reqType: 'patch' }; + +export type EmptyHeadAPICallT< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse +> = EmptyAPICallT & { readonly reqType: 'head' }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any export type ArgTypeOf = T extends APICallT ? A : never; export type APICallT< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse + ArgType extends RawArgType, + ResultType extends ValidResponse = ValidResponse, + ErrorType extends InvalidResponse = InvalidResponse > = ArgType extends undefined ? EmptyAPICallT : BasicAPICallT; -export type APITail = typeof GET | typeof POST | typeof PUT | typeof PATCH | typeof HEAD | typeof DELETE; +export type GetAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse = ValidResponse, + ErrorType extends InvalidResponse = InvalidResponse +> = ArgType extends undefined ? EmptyGetAPICallT : BasicGetAPICallT; -const httpMethodMap = new Map([ - [GET, "get"], - [POST, "post"], - [PUT, "put"], - [PATCH, "patch"], - [HEAD, "head"], - [DELETE, "delete"], - ]); +export type PostAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse = ValidResponse, + ErrorType extends InvalidResponse = InvalidResponse +> = ArgType extends undefined ? EmptyPostAPICallT : BasicPostAPICallT; - export function extractHttpMethod(tail: APITail): HttpMethod { - return httpMethodMap.get(tail) ?? "post"; - } +export type PutAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse = ValidResponse, + ErrorType extends InvalidResponse = InvalidResponse +> = ArgType extends undefined ? EmptyPutAPICallT : BasicPutAPICallT; +export type DeleteAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse = ValidResponse, + ErrorType extends InvalidResponse = InvalidResponse +> = ArgType extends undefined ? EmptyDeleteAPICallT : BasicDeleteAPICallT; -export async function GET( - args?: ArgType -): Promise; -export async function GET( - args: ArgType | undefined, - returnError: false -): Promise; -export async function GET< +export type PatchAPICallT< + ArgType extends RawArgType, + ResultType extends ValidResponse = ValidResponse, + ErrorType extends InvalidResponse = InvalidResponse +> = ArgType extends undefined ? EmptyPatchAPICallT : BasicPatchAPICallT; + +export type APITail = ReturnType | ReturnType | ReturnType | ReturnType | ReturnType | ReturnType; + +export function GET< ResultType extends ValidResponse, ErrorType extends InvalidResponse, - ArgType extends undefined = undefined ->(args: ArgType | undefined, returnError: true): Promise; -export async function GET< +>(): EmptyGetAPICallT +export function GET< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicGetAPICallT; +export function GET< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicGetAPICallT | EmptyGetAPICallT { + return Object.assign( + fakeGET, + { reqType: 'get' } as const + ) +} + +export function POST< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): EmptyPostAPICallT +export function POST< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicPostAPICallT; +export function POST< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicPostAPICallT | EmptyPostAPICallT { + return Object.assign( + fakePOST, + { reqType: 'post' } as const + ) +} + +export function PUT< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): EmptyPutAPICallT +export function PUT< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicPutAPICallT; +export function PUT< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicPutAPICallT | EmptyPutAPICallT { + return Object.assign( + fakePUT, + { reqType: 'put' } as const + ) +} + +export function DELETE< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): EmptyDeleteAPICallT +export function DELETE< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicDeleteAPICallT; +export function DELETE< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicDeleteAPICallT | EmptyDeleteAPICallT { + return Object.assign( + fakeDELETE, + { reqType: 'delete' } as const + ) +} + +export function PATCH< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): EmptyPatchAPICallT +export function PATCH< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicPatchAPICallT; +export function PATCH< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicPatchAPICallT | EmptyPatchAPICallT { + return Object.assign( + fakePATCH, + { reqType: 'patch' } as const + ) +} + +export function HEAD< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): EmptyHeadAPICallT +export function HEAD< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicHeadAPICallT; +export function HEAD< + ArgType extends RawArgType, + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, +>(): BasicHeadAPICallT | EmptyHeadAPICallT { + return Object.assign( + fakeHEAD, + { reqType: 'head' } as const + ) +} + +export async function fakeGET< ResultType extends ValidResponse, ErrorType extends InvalidResponse, ArgType extends undefined = undefined @@ -67,106 +259,45 @@ export async function GET< throw `Can't directly call GET. ${args}, ${returnError}. Use auto-generated path API.` } -export async function POST( - args?: ArgType -): Promise; -export async function POST( - args: ArgType | undefined, - returnError: false -): Promise; -export async function POST< +export async function fakePOST< ResultType extends ValidResponse, ErrorType extends InvalidResponse, - ArgType extends RawArgType = RawArgType ->(args: ArgType | undefined, returnError: true): Promise; -export async function POST< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - ArgType extends RawArgType = RawArgType ->(args?: ArgType, returnError = false): Promise { + ArgType extends RawArgType = undefined +>(args: ArgType, returnError = false): Promise { throw `Can't directly call POST. ${args}, ${returnError}. Use auto-generated path API.` } -export async function PUT( - args?: ArgType -): Promise; -export async function PUT( - args: ArgType | undefined, - returnError: false -): Promise; -export async function PUT< +export async function fakePUT< ResultType extends ValidResponse, ErrorType extends InvalidResponse, - ArgType extends RawArgType = RawArgType ->(args: ArgType | undefined, returnError: true): Promise; -export async function PUT< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - ArgType extends RawArgType = RawArgType ->(args?: ArgType, returnError = false): Promise { + ArgType extends RawArgType = undefined +>(args: ArgType, returnError = false): Promise { throw `Can't directly call PUT. ${args}, ${returnError}. Use auto-generated path API.`; } -export async function PATCH( - args?: ArgType -): Promise; -export async function PATCH( - args: ArgType | undefined, - returnError: false -): Promise; -export async function PATCH< +export async function fakeDELETE< ResultType extends ValidResponse, ErrorType extends InvalidResponse, - ArgType extends RawArgType = RawArgType ->(args: ArgType | undefined, returnError: true): Promise; -export async function PATCH< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - ArgType extends RawArgType = RawArgType ->(args?: ArgType, returnError = false): Promise { - throw `Can't directly call PATCH. ${args}, ${returnError}. Use auto-generated path API.` -} - -export async function HEAD( - args?: ArgType -): Promise; -export async function HEAD( - args: ArgType | undefined, - returnError: false -): Promise; -export async function HEAD< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - ArgType extends undefined = undefined ->(args: ArgType | undefined, returnError: true): Promise; -export async function HEAD< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - ArgType extends undefined = undefined ->(args?: ArgType, returnError = false): Promise { - throw `Can't directly call HEAD. ${args}, ${returnError}. Use auto-generated path API.`; -} - -export async function DELETE( - args?: ArgType -): Promise; -export async function DELETE( - args: ArgType | undefined, - returnError: false -): Promise; -export async function DELETE< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - ArgType extends RawArgType = RawArgType ->(args: ArgType | undefined, returnError: true): Promise; -export async function DELETE< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - ArgType extends RawArgType = RawArgType ->(args?: ArgType, returnError = false): Promise { + ArgType extends RawArgType = undefined +>(args: ArgType, returnError = false): Promise { throw `Can't directly call DELETE. ${args}, ${returnError}. Use auto-generated path API.`; } +export async function fakePATCH< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, + ArgType extends RawArgType = undefined +>(args: ArgType, returnError = false): Promise { + throw `Can't directly call PATCH. ${args}, ${returnError}. Use auto-generated path API.` +} + +export async function fakeHEAD< + ResultType extends ValidResponse, + ErrorType extends InvalidResponse, + ArgType extends RawArgType = undefined +>(args?: ArgType, returnError = false): Promise { + throw `Can't directly call HEAD. ${args}, ${returnError}. Use auto-generated path API.`; +} export interface ValidResponse { result: true; @@ -182,7 +313,7 @@ export interface InvalidResponse { type ExtractValid = T extends ValidResponse ? T : never; type ExtractInvalid = T extends InvalidResponse ? T : never; -export type Callable = (...args: any)=>any; +export type Callable = (...args: any) => any; export type ExtractResponse = ExtractValid>>; export type ExtractError = ExtractInvalid>>; @@ -190,12 +321,18 @@ export type ExtractQuery = Parameters[0]; export type DefAPINamespace = { [key: string]: DefAPINamespace - | typeof GET - | typeof POST - | typeof PUT - | typeof DELETE - | typeof PATCH - | typeof HEAD + | BasicGetAPICallT + | BasicPostAPICallT + | BasicPutAPICallT + | BasicDeleteAPICallT + | BasicPatchAPICallT + | BasicHeadAPICallT + | EmptyGetAPICallT + | EmptyPostAPICallT + | EmptyPutAPICallT + | EmptyDeleteAPICallT + | EmptyPatchAPICallT + | EmptyHeadAPICallT ; } diff --git a/server/apiStructure/sammoRootAPI.ts b/server/apiStructure/sammoRootAPI.ts index 69399c7..cd2add5 100644 --- a/server/apiStructure/sammoRootAPI.ts +++ b/server/apiStructure/sammoRootAPI.ts @@ -1,4 +1,4 @@ -import { type APICallT, GET, POST } from "./defs"; +import { DefAPINamespace, GET, POST } from "./defs"; export type LoginResponse = { result: true, @@ -32,14 +32,15 @@ export type AutoLoginFailed = { /** @internal */ export const structure = { Login: { - LoginByID: POST as APICallT<{ + LoginByID: POST<{ username: string, password: string, - }, LoginResponse, LoginFailed>, - LoginByToken: POST as APICallT<{ + }, LoginResponse, LoginFailed>(), + LoginByToken: POST<{ hashedToken: string, token_id: number, - }, AutoLoginResponse, AutoLoginFailed>, - ReqNonce: GET as APICallT + }, AutoLoginResponse, AutoLoginFailed>(), + Test: POST(), + ReqNonce: GET() }, -} as const; \ No newline at end of file +} satisfies DefAPINamespace; \ No newline at end of file diff --git a/server/clientAPI/sammoRootAPI.ts b/server/clientAPI/sammoRootAPI.ts index daa6c6f..ea658c1 100644 --- a/server/clientAPI/sammoRootAPI.ts +++ b/server/clientAPI/sammoRootAPI.ts @@ -1,11 +1,10 @@ import { APIPathGen } from "./APIPathGen"; -import { extractHttpMethod } from "../apiStructure/defs"; import type { APITail, RawArgType } from "../apiStructure/defs"; import { structure } from "../apiStructure/sammoRootAPI"; import { callClientAPI } from "./generator"; export const SammoRootAPI = APIPathGen(structure, (path: string[], tail: APITail, pathParam) => { - const method = extractHttpMethod(tail); + const method = tail.reqType; return (args?: RawArgType, returnError?: boolean) => { if (returnError) { return callClientAPI(method, path.join('/'), args, pathParam, true); diff --git a/server/index.ts b/server/index.ts index b39b5a7..31f7588 100644 --- a/server/index.ts +++ b/server/index.ts @@ -1,6 +1,5 @@ import 'dotenv/config'; import 'reflect-metadata'; -import { BasicQueryDTO } from './api/serverImpl.js'; import { validate } from 'class-validator'; import express, { type Request, type Response } from "express" import { AppDataSource } from "./data_source.js" @@ -8,19 +7,12 @@ import session from "express-session"; import path from 'node:path'; import { LiteHashDRBG } from './util/LiteHashDRBG.js'; import { simpleSerialize } from './util/simpleSerialize.js'; +import { SammoRootAPI } from './clientAPI/sammoRootAPI.js'; export async function test() { console.log("Hello World!"); console.log(process.env.GAME_DB_HOST); - const dto = new BasicQueryDTO(); - dto.command = 'None'; - dto.generalID = 1.1; - - const result = await validate(dto); - console.log(result); - //must be integer가 나타나야함 - const abc= { a: 1, b: 2,