대충이런느낌
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
import { ngGET } from "../defs";
|
||||||
|
import type { structure } from "../../apiStructure/sammoRootAPI";
|
||||||
|
import type { ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
||||||
|
|
||||||
|
type BaseAPI = typeof structure.Login.ReqNonce;
|
||||||
|
type RType = ExtractResponse<BaseAPI>;
|
||||||
|
type EType = ExtractError<BaseAPI>;
|
||||||
|
type QType = ExtractQuery<BaseAPI>;
|
||||||
|
const argValidator = undefined;
|
||||||
|
const procDecorator = [] as const;
|
||||||
|
|
||||||
|
export const ReqNonce = ngGET<RType, EType, QType>(argValidator)(procDecorator)(
|
||||||
|
(query, ctx, req, res) => {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -1,24 +1,55 @@
|
|||||||
import { POST } from "../defs";
|
import { POST, ngPOST } from "../defs";
|
||||||
import type { structure } from "../../apiStructure/sammoRootAPI";
|
import type { structure } from "../../apiStructure/sammoRootAPI";
|
||||||
import type { ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
import type { ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
||||||
|
import { StartSession } from "../ProcDecorator/StartSession";
|
||||||
|
import { IsString } from "class-validator";
|
||||||
|
import { delay } from "../../util/delay";
|
||||||
|
|
||||||
type BaseAPI = typeof structure.Login.LoginByID;
|
type BaseAPI = typeof structure.Login.LoginByID;
|
||||||
type RType = ExtractResponse<BaseAPI>;
|
type RType = ExtractResponse<BaseAPI>;
|
||||||
type EType = ExtractError<BaseAPI>;
|
type EType = ExtractError<BaseAPI>;
|
||||||
type QType = ExtractQuery<BaseAPI>;
|
type QType = ExtractQuery<BaseAPI>;
|
||||||
|
class ArgValidator implements QType {
|
||||||
class Q implements QType {
|
@IsString()
|
||||||
username!: string;
|
username!: string;
|
||||||
|
@IsString()
|
||||||
password!: string;
|
password!: string;
|
||||||
}
|
}
|
||||||
|
const procDecorator = [
|
||||||
|
StartSession,
|
||||||
|
] as const;
|
||||||
|
|
||||||
const procDecorator = [] as const;
|
export const LoginByID = ngPOST<RType, EType, QType>(ArgValidator)(procDecorator)(
|
||||||
|
async (query, ctx, req, res) => {
|
||||||
|
const username = query.username;
|
||||||
|
const password = query.password;
|
||||||
|
|
||||||
export class LoginByID extends POST<RType, EType, QType, typeof procDecorator>{
|
//TODO: DB에서 뭔가 가져와야 함
|
||||||
readonly argValidator = Q;
|
await delay(1);
|
||||||
readonly procDecorator = procDecorator;
|
|
||||||
protected LoginByID = Symbol("LoginByID");//TODO: remove this
|
if(Math.random() < 0.3){
|
||||||
protected override async api(query: QType, ctx,): Promise<RType | EType | true> {
|
return {
|
||||||
throw new Error("Method not implemented.");
|
result: false,
|
||||||
|
reason: "로그인 실패",
|
||||||
|
reqOTP: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Math.random() < 0.5){
|
||||||
|
return {
|
||||||
|
result: false,
|
||||||
|
reason: "OTP 인증 필요",
|
||||||
|
reqOTP: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const userID = 1;
|
||||||
|
const nextToken: [number, string] = [1, "1234567890"];
|
||||||
|
|
||||||
|
await ctx.setValue("userID", userID);
|
||||||
|
return {
|
||||||
|
result: true,
|
||||||
|
nextToken,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
@@ -1,16 +1,42 @@
|
|||||||
import { POST } from "../defs";
|
import { ngPOST } from "../defs";
|
||||||
import type { structure } from "../../apiStructure/sammoRootAPI";
|
import type { structure } from "../../apiStructure/sammoRootAPI";
|
||||||
import type { ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
import type { ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
||||||
|
import { StartSession } from "../ProcDecorator/StartSession";
|
||||||
|
import { IsNumber, IsString } from "class-validator";
|
||||||
|
import { delay } from "../../util/delay";
|
||||||
type BaseAPI = typeof structure.Login.LoginByToken;
|
type BaseAPI = typeof structure.Login.LoginByToken;
|
||||||
type RType = ExtractResponse<BaseAPI>;
|
type RType = ExtractResponse<BaseAPI>;
|
||||||
type EType = ExtractError<BaseAPI>;
|
type EType = ExtractError<BaseAPI>;
|
||||||
type QType = ExtractQuery<BaseAPI>;
|
type QType = ExtractQuery<BaseAPI>;
|
||||||
|
class ArgValidator implements QType {
|
||||||
|
@IsNumber()
|
||||||
|
token_id!: number;
|
||||||
|
@IsString()
|
||||||
|
hashedToken!: string;
|
||||||
|
}
|
||||||
|
const procDecorator = [
|
||||||
|
StartSession,
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export const LoginByToken = ngPOST<RType, EType, QType>(ArgValidator)(procDecorator)(
|
||||||
|
async (query, ctx) => {
|
||||||
|
query.hashedToken;
|
||||||
|
ctx.clearSession();
|
||||||
|
|
||||||
|
await delay(1);
|
||||||
|
//무언가 로그인
|
||||||
|
//TODO: DB는 어디서 들고옴?
|
||||||
|
|
||||||
|
const userID = 1;
|
||||||
|
const nextToken: [number, string] = [1, "1234567890"];
|
||||||
|
await ctx.setValue("userID", userID);
|
||||||
|
|
||||||
|
|
||||||
|
//throw new Error("Method not implemented.");
|
||||||
|
return {
|
||||||
|
result: true,
|
||||||
|
nextToken,
|
||||||
|
}
|
||||||
|
|
||||||
export class LoginByToken extends POST<RType, EType, QType>{
|
|
||||||
readonly argValidator = undefined;
|
|
||||||
protected LoginByToken = Symbol("LoginByToken");//TODO: remove this
|
|
||||||
protected override async api(query: QType): Promise<RType | EType | true> {
|
|
||||||
throw new Error("Method not implemented.");
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
@@ -1,23 +1,35 @@
|
|||||||
import { ngGET } from "../defs";
|
import { APINamespace, APINamespaceType, ngGET } from "../defs";
|
||||||
import type { structure } from "../../apiStructure/sammoRootAPI";
|
import type { structure } from "../../apiStructure/sammoRootAPI";
|
||||||
import type { ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
import type { DefAPINamespace, ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
||||||
|
import { StartSession } from "../ProcDecorator/StartSession";
|
||||||
|
|
||||||
type BaseAPI = typeof structure.Login.ReqNonce;
|
type BaseAPI = typeof structure.Login.ReqNonce;
|
||||||
type RType = ExtractResponse<BaseAPI>;
|
type RType = ExtractResponse<BaseAPI>;
|
||||||
type EType = ExtractError<BaseAPI>;
|
type EType = ExtractError<BaseAPI>;
|
||||||
type QType = ExtractQuery<BaseAPI>;
|
type QType = ExtractQuery<BaseAPI>;
|
||||||
|
const argValidator = undefined;
|
||||||
|
const procDecorator = [
|
||||||
|
StartSession,
|
||||||
|
] as const;
|
||||||
|
|
||||||
/*export class ReqNonce extends GET<RType, EType, QType>{
|
export const ReqNonce = ngGET<RType, EType, QType>(argValidator)(procDecorator)(
|
||||||
readonly argValidator = undefined;
|
async (query, ctx) => {
|
||||||
readonly procDecorator = [] as const;
|
const nonce = await ctx.getValue<string>("nonce");
|
||||||
protected ReqNonce = Symbol("ReqNonce");//TODO: remove this
|
if(nonce !== undefined){
|
||||||
protected override async api(query: QType): Promise<RType | EType | true> {
|
return {
|
||||||
throw new Error("Method not implemented.");
|
loginNonce: nonce,
|
||||||
}
|
result: true,
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const ReqNonce = ngGET<RType, EType, QType>(undefined)([] as const)(
|
const newNonce = "1234567890";
|
||||||
(query, ctx, req, res) => {
|
await ctx.setValue("nonce", newNonce);
|
||||||
throw new Error("Method not implemented.");
|
return {
|
||||||
|
loginNonce: newNonce,
|
||||||
|
result: true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
type BaseAPI2 = APINamespaceType<typeof structure.Login>['ReqNonce'];
|
||||||
|
type A = typeof ReqNonce;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GET } from "../defs";
|
import { GET, ngGET } from "../defs";
|
||||||
import type { structure } from "../../apiStructure/sammoRootAPI";
|
import type { structure } from "../../apiStructure/sammoRootAPI";
|
||||||
import type { ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
import type { ExtractError, ExtractQuery, ExtractResponse } from "../../apiStructure/defs";
|
||||||
|
|
||||||
@@ -7,13 +7,8 @@ type RType = ExtractResponse<BaseAPI>;
|
|||||||
type EType = ExtractError<BaseAPI>;
|
type EType = ExtractError<BaseAPI>;
|
||||||
type QType = ExtractQuery<BaseAPI>;
|
type QType = ExtractQuery<BaseAPI>;
|
||||||
|
|
||||||
export class test extends GET<RType, EType, QType>{
|
export const test = ngGET<RType, EType, QType>(undefined)(undefined)(
|
||||||
readonly argValidator = undefined;
|
(query, ctx, req, res) => {
|
||||||
protected ReqNonce = Symbol("ReqNonce");//TODO: remove this
|
throw new Error("Method not implemented.");
|
||||||
protected override async api(query: QType): Promise<RType | EType | true> {
|
|
||||||
return {
|
|
||||||
hello: "world",
|
|
||||||
result: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { LoginCtx } from "./ReqLogin";
|
import { LoginCtx } from "./ReqLogin";
|
||||||
|
import { SessionCtx } from "./StartSession";
|
||||||
import type { ProcDecoratorGenerator } from "./base";
|
import type { ProcDecoratorGenerator } from "./base";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
|
|
||||||
@@ -7,10 +8,12 @@ export interface UserLevelCtx {
|
|||||||
userLevel: number;
|
userLevel: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ParseUserLevel<Q extends LoginCtx>(): ProcDecoratorGenerator<UserLevelCtx, Q> {
|
export function ParseUserLevel<Q extends LoginCtx & SessionCtx>(): ProcDecoratorGenerator<UserLevelCtx, Q> {
|
||||||
return (inCtx) => {
|
return (inCtx) => {
|
||||||
|
const userLevel = 123;
|
||||||
|
inCtx.setValue('userLevel', userLevel);
|
||||||
return {
|
return {
|
||||||
userLevel: 123,
|
userLevel,
|
||||||
...inCtx,
|
...inCtx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,30 @@
|
|||||||
import { LoginCtx } from "./ReqLogin";
|
import { LoginCtx } from "./ReqLogin";
|
||||||
|
import { SessionCtx } from "./StartSession";
|
||||||
import type { ProcDecoratorGenerator } from "./base";
|
import type { ProcDecoratorGenerator } from "./base";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
|
import { delay } from "../../util/delay.js";
|
||||||
|
|
||||||
export type GameLoginCtx = {
|
export type GameLoginCtx = {
|
||||||
generalID: number;
|
generalID: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ReqGameLogin<Q extends LoginCtx>(): ProcDecoratorGenerator<GameLoginCtx, Q> {
|
export function ReqGameLogin<Q extends LoginCtx & SessionCtx>(): ProcDecoratorGenerator<GameLoginCtx, Q> {
|
||||||
return (inCtx) => {
|
return async (inCtx) => {
|
||||||
|
const ctx: Q & Partial<GameLoginCtx> = inCtx;
|
||||||
|
if (ctx.generalID !== undefined) {
|
||||||
|
return {
|
||||||
|
generalID: ctx.generalID,
|
||||||
|
...inCtx,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Something GameLogin');
|
||||||
|
await delay(0);
|
||||||
|
|
||||||
|
inCtx.setValue('generalID', ctx.userID * 4);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
generalID: inCtx.userID * 4,
|
generalID: ctx.userID * 4,
|
||||||
...inCtx,
|
...inCtx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
import type { Empty, ProcDecoratorPrePostGenerator } from "./base";
|
import { SessionCtx } from "./StartSession";
|
||||||
|
import type { InvalidProc, ProcDecoratorGenerator } from "./base";
|
||||||
|
|
||||||
export type LoginCtx = {
|
export type LoginCtx = {
|
||||||
userID: number;
|
userID: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ReqLogin<Q extends object = Empty>(): ProcDecoratorPrePostGenerator<LoginCtx, Q> {
|
export function ReqLogin<Q extends SessionCtx>(): ProcDecoratorGenerator<LoginCtx, Q> {
|
||||||
return [
|
return (inCtx) => {
|
||||||
(inCtx) => {
|
const ctx: Q & Partial<LoginCtx> = inCtx;
|
||||||
|
const userID = ctx.userID;
|
||||||
|
|
||||||
|
if (userID === undefined) {
|
||||||
return {
|
return {
|
||||||
userID: 999,
|
result: false,
|
||||||
...inCtx,
|
reason: 'Required Login',
|
||||||
};
|
invalidProcSymbol: 'ReqLogin'
|
||||||
},
|
} satisfies InvalidProc;
|
||||||
(inCtx) => {
|
|
||||||
console.log('ReqLogin post');
|
|
||||||
return inCtx;
|
|
||||||
}
|
}
|
||||||
]
|
|
||||||
|
return ctx as LoginCtx & Q;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import type { Empty, ProcDecoratorGenerator } from "./base";
|
||||||
|
|
||||||
|
export type SessionCtx = {
|
||||||
|
clearSession: () => Promise<void>;
|
||||||
|
deleteValue: (key: string) => Promise<void>;
|
||||||
|
getValue: <T>(key: string) => Promise<T | undefined>;
|
||||||
|
setValue: (key: string, value: unknown) => Promise<void>;
|
||||||
|
sessionRaw: {
|
||||||
|
raw: object;
|
||||||
|
changed: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StartSession<Q extends object = Empty>(): ProcDecoratorGenerator<SessionCtx, Q> {
|
||||||
|
return (inCtx) => {
|
||||||
|
const raw: object = {};
|
||||||
|
return {
|
||||||
|
clearSession: () => Promise.resolve(),
|
||||||
|
deleteValue: async (key: string) => {
|
||||||
|
console.log('deleteValue', key);
|
||||||
|
if (raw[key] !== undefined) {
|
||||||
|
delete raw[key];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getValue: async <T>(key: string) => {
|
||||||
|
return raw[key] as T | undefined;
|
||||||
|
},
|
||||||
|
setValue: async (key: string, value: unknown) => {
|
||||||
|
console.log('setValue', key, value);
|
||||||
|
raw[key] = value;
|
||||||
|
},
|
||||||
|
sessionRaw: {
|
||||||
|
raw,
|
||||||
|
changed: false,
|
||||||
|
},
|
||||||
|
...inCtx,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
+96
-34
@@ -94,14 +94,14 @@ export abstract class APIExecuter<R extends ValidResponse, E extends InvalidResp
|
|||||||
}
|
}
|
||||||
|
|
||||||
let isValidRoute = true;
|
let isValidRoute = true;
|
||||||
if(index !== -1 && index !== this.postDecorator.length){
|
if (index !== -1 && index !== this.postDecorator.length) {
|
||||||
isValidRoute = false;
|
isValidRoute = false;
|
||||||
index = clamp(index, 0, this.postDecorator.length);
|
index = clamp(index, 0, this.postDecorator.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = index - 1; i >= 0; i--) {
|
for (let i = index - 1; i >= 0; i--) {
|
||||||
const proc = this.postDecorator[i];
|
const proc = this.postDecorator[i];
|
||||||
if(!proc){
|
if (!proc) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ export abstract class APIExecuter<R extends ValidResponse, E extends InvalidResp
|
|||||||
const ctx = await this.preCtx(expressReq, expressRes);
|
const ctx = await this.preCtx(expressReq, expressRes);
|
||||||
if (Array.isArray(ctx)) {
|
if (Array.isArray(ctx)) {
|
||||||
const [invalidProc, errCtx, idx] = ctx;
|
const [invalidProc, errCtx, idx] = ctx;
|
||||||
if (idx == 0){
|
if (idx == 0) {
|
||||||
expressRes.json(invalidProc);
|
expressRes.json(invalidProc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ export abstract class APIExecuter<R extends ValidResponse, E extends InvalidResp
|
|||||||
const result = await this.api(query, ctx, expressReq, expressRes);
|
const result = await this.api(query, ctx, expressReq, expressRes);
|
||||||
const postResult = await this.postCtx(ctx, expressReq, expressRes);
|
const postResult = await this.postCtx(ctx, expressReq, expressRes);
|
||||||
if (postResult !== undefined) {
|
if (postResult !== undefined) {
|
||||||
if(result === true){
|
if (result === true) {
|
||||||
//NOTE: 이미 api에서 response를 보낸 특이 케이스.
|
//NOTE: 이미 api에서 response를 보낸 특이 케이스.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ export abstract class APIExecuter<R extends ValidResponse, E extends InvalidResp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ngAPIExecuter<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain>{
|
interface ngAPIExecuter<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>;
|
(query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response): Promise<R | E | true>;
|
||||||
httpMethod: HttpMethod;
|
httpMethod: HttpMethod;
|
||||||
argValidator?: ValidatorType<Q>;
|
argValidator?: ValidatorType<Q>;
|
||||||
@@ -171,19 +171,38 @@ interface ngAPIExecuter<R extends ValidResponse, E extends InvalidResponse, Q ex
|
|||||||
postDecorator: (ProcDecorator<any, any> | undefined)[];
|
postDecorator: (ProcDecorator<any, any> | undefined)[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ngAPIGenerator<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>{
|
export interface iAPI_GET<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD> {
|
||||||
<PD extends ProcDecoratorChain>(procDecoratorChain: PD): ngAPIExecuter<R, E, Q, PD>;
|
httpMethod: 'get';
|
||||||
}
|
}
|
||||||
|
|
||||||
function ngGenerateAPI<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain>(httpMethod: HttpMethod, args: {
|
export interface iAPI_POST<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD> {
|
||||||
argValidator?: ValidatorType<Q>,
|
httpMethod: 'post';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface iAPI_PUT<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD> {
|
||||||
|
httpMethod: 'put';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface iAPI_DELETE<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD> {
|
||||||
|
httpMethod: 'delete';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface iAPI_PATCH<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD> {
|
||||||
|
httpMethod: 'patch';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface iAPI_HEAD<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD> {
|
||||||
|
httpMethod: 'head';
|
||||||
|
}
|
||||||
|
|
||||||
|
function ngGenerateAPI<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain>(httpMethod: HttpMethod,
|
||||||
|
argValidator: ValidatorType<Q> | undefined,
|
||||||
procDecoratorChain: PD,
|
procDecoratorChain: PD,
|
||||||
callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>,
|
callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>,
|
||||||
}): ngAPIExecuter<R, E, Q, PD>{
|
): ngAPIExecuter<R, E, Q, PD> {
|
||||||
const { argValidator, procDecoratorChain, callback } = args;
|
|
||||||
const preDecorator: ProcDecorator<any, any>[] = [];
|
const preDecorator: ProcDecorator<any, any>[] = [];
|
||||||
const postDecorator: (ProcDecorator<any, any> | undefined)[] = [];
|
const postDecorator: (ProcDecorator<any, any> | undefined)[] = [];
|
||||||
if(procDecoratorChain){
|
if (procDecoratorChain) {
|
||||||
for (const procGen of procDecoratorChain) {
|
for (const procGen of procDecoratorChain) {
|
||||||
const proc = procGen();
|
const proc = procGen();
|
||||||
if (Array.isArray(proc)) {
|
if (Array.isArray(proc)) {
|
||||||
@@ -208,41 +227,84 @@ function ngGenerateAPI<R extends ValidResponse, E extends InvalidResponse, Q ext
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ngGET<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>){
|
export function ngGET<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||||
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||||
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||||
return ngGenerateAPI<R, E, Q, PD>('get', {
|
return ngGenerateAPI<R, E, Q, PD>(
|
||||||
|
'get',
|
||||||
argValidator,
|
argValidator,
|
||||||
procDecoratorChain,
|
procDecoratorChain,
|
||||||
callback,
|
callback,
|
||||||
});
|
) as iAPI_GET<R, E, Q, PD>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ngGET<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD>{
|
export function ngPOST<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||||
httpMethod: 'get';
|
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||||
|
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||||
|
return ngGenerateAPI<R, E, Q, PD>(
|
||||||
|
'post',
|
||||||
|
argValidator,
|
||||||
|
procDecoratorChain,
|
||||||
|
callback,
|
||||||
|
) as iAPI_POST<R, E, Q, PD>;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ngPOST<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD>{
|
export function ngPUT<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||||
httpMethod: 'post';
|
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||||
|
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||||
|
return ngGenerateAPI<R, E, Q, PD>(
|
||||||
|
'put',
|
||||||
|
argValidator,
|
||||||
|
procDecoratorChain,
|
||||||
|
callback,
|
||||||
|
) as iAPI_PUT<R, E, Q, PD>;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ngPUT<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD>{
|
export function ngDELETE<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||||
httpMethod: 'put';
|
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||||
|
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||||
|
return ngGenerateAPI<R, E, Q, PD>(
|
||||||
|
'delete',
|
||||||
|
argValidator,
|
||||||
|
procDecoratorChain,
|
||||||
|
callback,
|
||||||
|
) as iAPI_DELETE<R, E, Q, PD>;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ngDELETE<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD>{
|
export function ngPATCH<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||||
httpMethod: 'delete';
|
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||||
|
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||||
|
return ngGenerateAPI<R, E, Q, PD>(
|
||||||
|
'patch',
|
||||||
|
argValidator,
|
||||||
|
procDecoratorChain,
|
||||||
|
callback,
|
||||||
|
) as iAPI_PATCH<R, E, Q, PD>;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ngPATCH<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD>{
|
export function ngHEAD<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType>(argValidator?: ValidatorType<Q>) {
|
||||||
httpMethod: 'patch';
|
return <PD extends ProcDecoratorChain>(procDecoratorChain: PD) => {
|
||||||
|
return (callback: (query: Q, ctx: ResolveChain<PD>, expressReq: Request, expressRes: Response) => Promise<R | E | true>) => {
|
||||||
|
return ngGenerateAPI<R, E, Q, PD>(
|
||||||
|
'head',
|
||||||
|
argValidator,
|
||||||
|
procDecoratorChain,
|
||||||
|
callback,
|
||||||
|
) as iAPI_HEAD<R, E, Q, PD>;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ngHEAD<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends ngAPIExecuter<R, E, Q, PD>{
|
|
||||||
httpMethod: 'head';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export abstract class APIBodyParseExecuter<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends APIExecuter<R, E, Q, PD>{
|
export abstract class APIBodyParseExecuter<R extends ValidResponse, E extends InvalidResponse, Q extends RawArgType, PD extends ProcDecoratorChain> extends APIExecuter<R, E, Q, PD>{
|
||||||
@@ -321,17 +383,17 @@ export type ClassType<T> = new (...args: any[]) => T;
|
|||||||
|
|
||||||
export type APIServerType<T extends Callable> =
|
export type APIServerType<T extends Callable> =
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
T extends GetAPICallT<infer Q, infer R, infer E> ? ClassType<GET<R, E, Q, any>> :
|
T extends GetAPICallT<infer Q, infer R, infer E> ? iAPI_GET<R, E, Q, any> :
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
T extends PostAPICallT<infer Q, infer R, infer E> ? ClassType<POST<R, E, Q, any>> :
|
T extends PostAPICallT<infer Q, infer R, infer E> ? iAPI_POST<R, E, Q, any> :
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
T extends PutAPICallT<infer Q, infer R, infer E> ? ClassType<PUT<R, E, Q, any>> :
|
T extends PutAPICallT<infer Q, infer R, infer E> ? iAPI_PUT<R, E, Q, any> :
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
T extends DeleteAPICallT<infer Q, infer R, infer E> ? ClassType<DELETE<R, E, Q, any>> :
|
T extends DeleteAPICallT<infer Q, infer R, infer E> ? iAPI_DELETE<R, E, Q, any> :
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
T extends PatchAPICallT<infer Q, infer R, infer E> ? ClassType<PATCH<R, E, Q, any>> :
|
T extends PatchAPICallT<infer Q, infer R, infer E> ? iAPI_PATCH<R, E, Q, any> :
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
T extends HeadAPICallT<infer Q, infer R, infer E> ? ClassType<HEAD<R, E, Q, any>> :
|
T extends HeadAPICallT<infer Q, infer R, infer E> ? iAPI_HEAD<R, E, Q, any> :
|
||||||
never;
|
never;
|
||||||
export type APINamespaceType<T extends DefAPINamespace> = {
|
export type APINamespaceType<T extends DefAPINamespace> = {
|
||||||
[K in keyof T]:
|
[K in keyof T]:
|
||||||
|
|||||||
Reference in New Issue
Block a user