diff --git a/env.d.ts b/@sammo/client/env.d.ts similarity index 100% rename from env.d.ts rename to @sammo/client/env.d.ts diff --git a/@sammo/client/package.json b/@sammo/client/package.json new file mode 100644 index 0000000..42d677a --- /dev/null +++ b/@sammo/client/package.json @@ -0,0 +1,27 @@ +{ + "name": "@sammo/api_def", + "version": "1.0.1", + "description": "", + "main": "dist/index.js", + "exports": { + ".": "./dist/index.js", + "./gateway": "./dist/gateway.js", + "./def": "./dist/def/index.js" + }, + "scripts": { + "build": "tsc --build" + }, + "author": "", + "type": "module", + "license": "MIT", + "dependencies": { + "@sammo/util": "workspace:^", + "@strpc/def": "workspace:^" + }, + "devDependencies": { + "zod": "^3.22.2" + }, + "peerDependencies": { + "zod": "^3.22.2" + } +} diff --git a/public/favicon.ico b/@sammo/client/public/favicon.ico similarity index 100% rename from public/favicon.ico rename to @sammo/client/public/favicon.ico diff --git a/src/App.vue b/@sammo/client/src/App.vue similarity index 100% rename from src/App.vue rename to @sammo/client/src/App.vue diff --git a/src/assets/base.css b/@sammo/client/src/assets/base.css similarity index 100% rename from src/assets/base.css rename to @sammo/client/src/assets/base.css diff --git a/src/assets/logo.svg b/@sammo/client/src/assets/logo.svg similarity index 100% rename from src/assets/logo.svg rename to @sammo/client/src/assets/logo.svg diff --git a/src/assets/main.css b/@sammo/client/src/assets/main.css similarity index 100% rename from src/assets/main.css rename to @sammo/client/src/assets/main.css diff --git a/src/components/HelloWorld.vue b/@sammo/client/src/components/HelloWorld.vue similarity index 100% rename from src/components/HelloWorld.vue rename to @sammo/client/src/components/HelloWorld.vue diff --git a/src/components/TheWelcome.vue b/@sammo/client/src/components/TheWelcome.vue similarity index 100% rename from src/components/TheWelcome.vue rename to @sammo/client/src/components/TheWelcome.vue diff --git a/src/components/WelcomeItem.vue b/@sammo/client/src/components/WelcomeItem.vue similarity index 100% rename from src/components/WelcomeItem.vue rename to @sammo/client/src/components/WelcomeItem.vue diff --git a/src/components/icons/IconCommunity.vue b/@sammo/client/src/components/icons/IconCommunity.vue similarity index 100% rename from src/components/icons/IconCommunity.vue rename to @sammo/client/src/components/icons/IconCommunity.vue diff --git a/src/components/icons/IconDocumentation.vue b/@sammo/client/src/components/icons/IconDocumentation.vue similarity index 100% rename from src/components/icons/IconDocumentation.vue rename to @sammo/client/src/components/icons/IconDocumentation.vue diff --git a/src/components/icons/IconEcosystem.vue b/@sammo/client/src/components/icons/IconEcosystem.vue similarity index 100% rename from src/components/icons/IconEcosystem.vue rename to @sammo/client/src/components/icons/IconEcosystem.vue diff --git a/src/components/icons/IconSupport.vue b/@sammo/client/src/components/icons/IconSupport.vue similarity index 100% rename from src/components/icons/IconSupport.vue rename to @sammo/client/src/components/icons/IconSupport.vue diff --git a/src/components/icons/IconTooling.vue b/@sammo/client/src/components/icons/IconTooling.vue similarity index 100% rename from src/components/icons/IconTooling.vue rename to @sammo/client/src/components/icons/IconTooling.vue diff --git a/src/main.ts b/@sammo/client/src/main.ts similarity index 84% rename from src/main.ts rename to @sammo/client/src/main.ts index 5dcad83..24c9c4b 100644 --- a/src/main.ts +++ b/@sammo/client/src/main.ts @@ -4,7 +4,7 @@ import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' -import router from './router' +import router from './router/index.js' const app = createApp(App) diff --git a/src/router/index.ts b/@sammo/client/src/router/index.ts similarity index 100% rename from src/router/index.ts rename to @sammo/client/src/router/index.ts diff --git a/src/stores/counter.ts b/@sammo/client/src/stores/counter.ts similarity index 100% rename from src/stores/counter.ts rename to @sammo/client/src/stores/counter.ts diff --git a/src/views/AboutView.vue b/@sammo/client/src/views/AboutView.vue similarity index 100% rename from src/views/AboutView.vue rename to @sammo/client/src/views/AboutView.vue diff --git a/src/views/HomeView.vue b/@sammo/client/src/views/HomeView.vue similarity index 100% rename from src/views/HomeView.vue rename to @sammo/client/src/views/HomeView.vue diff --git a/@sammo/client/tsconfig.json b/@sammo/client/tsconfig.json new file mode 100644 index 0000000..13cbd6d --- /dev/null +++ b/@sammo/client/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + }, + "references": [ + { + + "path": "../util" + }, + { + "path": "../secure_token" + }, + { + "path": "../../@strpc/def" + } + ] + } diff --git a/tsconfig.node.json b/@sammo/client/tsconfig.node.json similarity index 100% rename from tsconfig.node.json rename to @sammo/client/tsconfig.node.json diff --git a/vite.config.ts b/@sammo/client/vite.config.ts similarity index 100% rename from vite.config.ts rename to @sammo/client/vite.config.ts diff --git a/@sammo/game_logic/package.json b/@sammo/game_logic/package.json new file mode 100644 index 0000000..3030291 --- /dev/null +++ b/@sammo/game_logic/package.json @@ -0,0 +1,23 @@ +{ + "name": "@sammo/game_logic", + "version": "1.0.0", + "description": "", + "main": "dist/index.js", + "scripts": { + "build": "tsc --build" + }, + "author": "", + "type": "module", + "license": "MIT", + "dependencies": { + "@sammo/api_def": "workspace:^", + "@sammo/server_util": "workspace:^", + "@sammo/util": "workspace:^", + "@strpc/express": "workspace:^", + "dotenv": "^16.3.1", + "mongoose": "^7.4.3" + }, + "devDependencies": { + "@types/node": "^20.6.3" + } +} diff --git a/server/util/generalStats.ts b/@sammo/game_logic/src/generalStats.ts similarity index 100% rename from server/util/generalStats.ts rename to @sammo/game_logic/src/generalStats.ts diff --git a/@sammo/game_logic/src/index.ts b/@sammo/game_logic/src/index.ts new file mode 100644 index 0000000..7212077 --- /dev/null +++ b/@sammo/game_logic/src/index.ts @@ -0,0 +1 @@ +export * from "./generalStats.js"; \ No newline at end of file diff --git a/@sammo/game_logic/tsconfig.json b/@sammo/game_logic/tsconfig.json new file mode 100644 index 0000000..ebff90d --- /dev/null +++ b/@sammo/game_logic/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + }, + "references": [ + { + "path": "../../@strpc/express" + }, + { + "path": "../util" + }, + { + "path": "../crypto" + }, + { + "path": "../server_util" + }, + ] +} diff --git a/@sammo/server/package.json b/@sammo/server/package.json index 974ede2..829a1a9 100644 --- a/@sammo/server/package.json +++ b/@sammo/server/package.json @@ -10,14 +10,26 @@ "type": "module", "license": "MIT", "dependencies": { + "@esfx/async-readerwriterlock": "^1.0.0", "@sammo/api_def": "workspace:^", + "@sammo/game_logic": "workspace:^", "@sammo/server_util": "workspace:^", "@sammo/util": "workspace:^", "@strpc/express": "workspace:^", + "date-fns": "^2.30.0", "dotenv": "^16.3.1", - "mongoose": "^7.4.3" + "eventemitter3": "^5.0.1", + "express": "^4.18.2", + "express-session": "^1.17.3", + "ky": "^1.0.1", + "lodash-es": "^4.17.21", + "mongoose": "^7.4.3", + "reflect-metadata": "^0.1.13", + "tslib": "^2.6.2", + "zod": "^3.22.2" }, "devDependencies": { + "@sammo/gateway": "workspace:^", "@types/node": "^20.6.3" } } diff --git a/@sammo/server/src/api/index.ts b/@sammo/server/src/api/index.ts new file mode 100644 index 0000000..c0fead8 --- /dev/null +++ b/@sammo/server/src/api/index.ts @@ -0,0 +1,5 @@ +import type { structure } from "@sammo/api_def"; +import type { APINamespaceType } from "@strpc/express"; + +export const sammoAPI = { +} satisfies APINamespaceType; \ No newline at end of file diff --git a/@sammo/server/src/index.ts b/@sammo/server/src/index.ts index eaf526f..0bca319 100644 --- a/@sammo/server/src/index.ts +++ b/@sammo/server/src/index.ts @@ -1,21 +1,19 @@ +import './dotenv.js' import 'reflect-metadata'; import connectDB from './connectDB.js'; import express, { type Request, type Response } from "express" import session from "express-session"; -import path from 'node:path'; -import { LiteHashDRBG } from './util/LiteHashDRBG.js'; -import { simpleSerialize } from './util/simpleSerialize.js'; -import { buildAPISystem } from './api/generator.js'; -import { unwrap } from './util/unwrap.js'; -import { sammoAPI } from './api/api.js'; -import { ownConfig } from './serverConfig.js'; +import { buildAPISystem } from '@strpc/express/generator'; +import { sammoAPI } from './api/index.js'; +import { unwrap } from '@sammo/util';; +import { serverConfig } from './serverConfig.js'; connectDB.then(async (db) => { // create express app const app = express() app.use(express.json()); app.use(session({ - secret: unwrap(ownConfig.sessionSecret), + secret: unwrap(serverConfig.sessionSecret), resave: false, saveUninitialized: false, })) @@ -24,9 +22,9 @@ connectDB.then(async (db) => { app.use('/api', buildAPISystem(sammoAPI)); // start express server - app.listen(ownConfig.port) + app.listen(serverConfig.port) - console.log(`Express server has started on port ${ownConfig.port}`) + console.log(`Express server has started on port ${serverConfig.port}`) }).catch(error => console.log(error)); diff --git a/@sammo/server/src/serverConfig.ts b/@sammo/server/src/serverConfig.ts index 6806321..269afc6 100644 --- a/@sammo/server/src/serverConfig.ts +++ b/@sammo/server/src/serverConfig.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; -import { unwrap } from './util/unwrap.js'; +import { unwrap } from '@sammo/util'; -export const ownConfig = { +export const serverConfig = { sessionSecret: unwrap(process.env.SESSION_SECRET), port: Number(unwrap(process.env.SERVER_PORT)), gatewayHost: unwrap(process.env.GATEWAY_HOST), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 657aa97..2334931 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -210,6 +210,31 @@ importers: specifier: ^5.2.2 version: 5.2.2 + '@sammo/game_logic': + dependencies: + '@sammo/api_def': + specifier: workspace:^ + version: link:../api_def + '@sammo/server_util': + specifier: workspace:^ + version: link:../server_util + '@sammo/util': + specifier: workspace:^ + version: link:../util + '@strpc/express': + specifier: workspace:^ + version: link:../../@strpc/express + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + mongoose: + specifier: ^7.4.3 + version: 7.4.3 + devDependencies: + '@types/node': + specifier: ^20.6.3 + version: 20.6.3 + '@sammo/gateway': dependencies: '@sammo/api_def': @@ -254,6 +279,67 @@ importers: specifier: ^3.22.2 version: 3.22.2 + '@sammo/server': + dependencies: + '@esfx/async-readerwriterlock': + specifier: ^1.0.0 + version: 1.0.0 + '@sammo/api_def': + specifier: workspace:^ + version: link:../api_def + '@sammo/game_logic': + specifier: workspace:^ + version: link:../game_logic + '@sammo/server_util': + specifier: workspace:^ + version: link:../server_util + '@sammo/util': + specifier: workspace:^ + version: link:../util + '@strpc/express': + specifier: workspace:^ + version: link:../../@strpc/express + date-fns: + specifier: ^2.30.0 + version: 2.30.0 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + eventemitter3: + specifier: ^5.0.1 + version: 5.0.1 + express: + specifier: ^4.18.2 + version: 4.18.2 + express-session: + specifier: ^1.17.3 + version: 1.17.3 + ky: + specifier: ^1.0.1 + version: 1.0.1 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + mongoose: + specifier: ^7.4.3 + version: 7.4.3 + reflect-metadata: + specifier: ^0.1.13 + version: 0.1.13 + tslib: + specifier: ^2.6.2 + version: 2.6.2 + zod: + specifier: ^3.22.2 + version: 3.22.2 + devDependencies: + '@sammo/gateway': + specifier: workspace:^ + version: link:../gateway + '@types/node': + specifier: ^20.6.3 + version: 20.6.3 + '@sammo/server_util': dependencies: '@sammo/api_def': @@ -4267,7 +4353,6 @@ packages: /ky@1.0.1: resolution: {integrity: sha512-UvcwpQO0LOuZwG0Ti3VDo6w57KYt+r4bWEYlNaMt82hgyFtse86QtOGum1RzsZni31FndXQl6NvtDArfunt2JQ==} engines: {node: '>=18'} - dev: true /leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -5543,7 +5628,6 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - dev: true /tsutils@3.21.0(typescript@5.1.6): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -5940,4 +6024,3 @@ packages: /zod@3.22.2: resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==} - dev: true diff --git a/server/api/api.ts b/server/api/api.ts deleted file mode 100644 index aa88013..0000000 --- a/server/api/api.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { structure } from "../apiStructure/sammoAPI.js"; -import type { APINamespaceType } from "./defs.js"; - -export const sammoAPI = { -} satisfies APINamespaceType; \ No newline at end of file diff --git a/server/api/defs.ts b/server/api/defs.ts deleted file mode 100644 index e048840..0000000 --- a/server/api/defs.ts +++ /dev/null @@ -1,199 +0,0 @@ - -import type { Request, Response } from 'express'; -import type { Callable, DefAPINamespace, DeleteAPICallT, GetAPICallT, HeadAPICallT, HttpMethod, InvalidResponse, PatchAPICallT, PostAPICallT, PutAPICallT, RawArgType, ValidResponse, recoveryMethod } from '../apiStructure/defs.js'; -import type { Empty, PostProcDecoratorRunner, ProcDecoratorRunner } from '../ProcDecorator/base.js'; -import type { ZodType } from 'zod'; - -export type APINamespace = { - [key: string]: APINamespace - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | iAPI_GET - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | iAPI_POST - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | iAPI_PUT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | iAPI_DELETE - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | iAPI_PATCH - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | iAPI_HEAD - ; -} - -type ValidatorType = T extends undefined ? undefined : ZodType; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type AnyAPIExecuter = APIExecuter; - -interface APIExecuter { - (query: Q, ctx: CTX, expressReq: Request, expressRes: Response): Promise; - httpMethod: HttpMethod; - argValidator?: ValidatorType; - preDecorator: ProcDecoratorRunner; - postDecorator: PostProcDecoratorRunner; -} - -export interface iAPI_GET extends APIExecuter { - httpMethod: 'get'; -} - -export interface iAPI_POST extends APIExecuter { - httpMethod: 'post'; -} - -export interface iAPI_PUT extends APIExecuter { - httpMethod: 'put'; -} - -export interface iAPI_DELETE extends APIExecuter { - httpMethod: 'delete'; -} - -export interface iAPI_PATCH extends APIExecuter { - httpMethod: 'patch'; -} - -export interface iAPI_HEAD extends APIExecuter { - httpMethod: 'head'; -} - -function generateAPI(httpMethod: HttpMethod, - argValidator: ValidatorType | undefined, - preDecorator: ProcDecoratorRunner, - postDecorator: PostProcDecoratorRunner, - callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise, -): APIExecuter { - return Object.assign( - callback, - { - httpMethod, - argValidator, - preDecorator, - postDecorator, - } - ); -} - -export function GET(argValidator?: ValidatorType) { - return ([preDecorator, postDecorator]: readonly [ProcDecoratorRunner, PostProcDecoratorRunner]) => { - return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise) => { - return generateAPI( - 'get', - argValidator, - preDecorator, - postDecorator, - callback, - ) as iAPI_GET; - } - } -} - -export function POST(argValidator?: ValidatorType) { - return ([preDecorator, postDecorator]: readonly [ProcDecoratorRunner, PostProcDecoratorRunner]) => { - return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise) => { - return generateAPI( - 'post', - argValidator, - preDecorator, - postDecorator, - callback, - ) as iAPI_POST; - } - } -} - -export function PUT(argValidator?: ValidatorType) { - return ([preDecorator, postDecorator]: readonly [ProcDecoratorRunner, PostProcDecoratorRunner]) => { - return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise) => { - return generateAPI( - 'put', - argValidator, - preDecorator, - postDecorator, - callback, - ) as iAPI_PUT; - } - } -} - -export function DELETE(argValidator?: ValidatorType) { - return ([preDecorator, postDecorator]: readonly [ProcDecoratorRunner, PostProcDecoratorRunner]) => { - return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise) => { - return generateAPI( - 'delete', - argValidator, - preDecorator, - postDecorator, - callback, - ) as iAPI_DELETE; - } - } -} - -export function PATCH(argValidator?: ValidatorType) { - return ([preDecorator, postDecorator]: readonly [ProcDecoratorRunner, PostProcDecoratorRunner]) => { - return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise) => { - return generateAPI( - 'patch', - argValidator, - preDecorator, - postDecorator, - callback, - ) as iAPI_PATCH; - } - } -} - -export function HEAD(argValidator?: ValidatorType) { - return ([preDecorator, postDecorator]: readonly [ProcDecoratorRunner, PostProcDecoratorRunner]) => { - return (callback: (query: Q, ctx: CTX, expressReq: Request, expressRes: Response) => Promise) => { - return generateAPI( - 'head', - argValidator, - preDecorator, - postDecorator, - callback, - ) as iAPI_HEAD; - } - } -} - -export function raiseError(reason: string, recovery?: recoveryMethod): InvalidResponse { - if (recovery) { - return { - result: false, - reason, - recovery, - }; - } - return { - result: false, - reason, - }; -} - - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type ClassType = new (...args: any[]) => T; - -export type APIServerType = - // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends GetAPICallT ? iAPI_GET : - // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends PostAPICallT ? iAPI_POST : - // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends PutAPICallT ? iAPI_PUT : - // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends DeleteAPICallT ? iAPI_DELETE : - // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends PatchAPICallT ? iAPI_PATCH : - // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends HeadAPICallT ? iAPI_HEAD : - never; -export type APINamespaceType = { - [K in keyof T]: - T[K] extends Callable ? APIServerType : - T[K] extends DefAPINamespace ? APINamespaceType : - never; -}; \ No newline at end of file diff --git a/server/api/generator.ts b/server/api/generator.ts deleted file mode 100644 index 4dab34c..0000000 --- a/server/api/generator.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { Router, type Request, type Response } from 'express'; -import type { AnyAPIExecuter, APINamespace } from './defs.js'; -import type { RawArgType } from '../apiStructure/defs.js'; -import { z } from 'zod'; - -async function parseParam>(req: Request, argValidator?: z.ZodType): Promise> { - if (!argValidator) { - return { - success: true, - data: req.query as Q - } - } - - const query = req.query; - return await argValidator.safeParseAsync(query); -} - -async function parseBody>(req: Request, argValidator?: z.ZodType): Promise> { - if (!argValidator) { - return { - success: true, - data: req.body as Q - } - } - - const query = req.body; - return await argValidator.safeParseAsync(query); -} - -async function apiRun(query: object, req: Request, res: Response, api: AnyAPIExecuter): Promise { - const [preResult, ctx] = await api.preDecorator({}, req, res); - if (!preResult.every((v) => v.result)) { - const lastErr = preResult.pop() as typeof preResult[0]; - - const [postResult,] = await api.postDecorator(ctx, preResult, req, res, false); - const postErrors = postResult.filter((obj)=>!obj.result); - if (postErrors.length) { - //회수조차 불가능? - const postErrorsStr = postErrors.map((obj)=>{ - return `(${obj.type})${obj.info}` - }).join(', '); - res.json({ - result: false, - path: req.path, - reason: `preDecorator: (${lastErr.type})${lastErr.info}, postDecorator: ${postErrorsStr}`, - }); - return; - } - - res.json({ - result: false, - path: req.path, - reason: `preDecorator: (${lastErr.type})${lastErr.info}`, - }) - return; - } - const result = await api(query, ctx, req, res); - const [postResult,] = await api.postDecorator(ctx, preResult, req, res, true); - const postErrors = postResult.filter((obj)=>!obj.result); - if(postErrors.length) { - if(result === true) { - //NOTE: 이미 api에서 response를 보낸 특이 케이스. - return; - } - const postErrorsStr = postErrors.map((obj)=>{ - return `(${obj.type})${obj.info}` - }).join(', '); - res.json({ - result: false, - path: req.path, - reason: `postDecorator: ${postErrorsStr}`, - originalResult: result, - }); - return; - } - - if (result !== true) { - res.json(result); - } -} - -export function buildAPISystem(api: N | Q): Router { - const router = Router(); - - if(typeof api === 'function') { - throw 'root api cannot be function'; - } - - for (const [key, value] of Object.entries(api)) { - const rkey = `/${key}`; - if (typeof value !== 'function') { - router.use(rkey, buildAPISystem(value)); - - continue; - } - const executer = value; - - if (!executer.httpMethod) { - throw new Error('APIExecuter.reqType is not defined'); - } - - const parser = executer.httpMethod === 'get' ? parseParam : parseBody; - router[executer.httpMethod](rkey, async (req, res) => { - const queryResult = await parser(req, executer.argValidator); - if(!queryResult.success){ - res.json({ - result: false, - reason: `invalid parameter: ${queryResult.error.message}`, - error: queryResult.error - }); - return; - } - - await apiRun(queryResult.data, req, res, executer); - }); - } - return router; -} \ No newline at end of file diff --git a/server/apiStructure/defs.ts b/server/apiStructure/defs.ts deleted file mode 100644 index 25f43f2..0000000 --- a/server/apiStructure/defs.ts +++ /dev/null @@ -1,358 +0,0 @@ -export type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'; -export type RawArgType = { - [key: string]: unknown; -} | undefined; - - -export interface BasicAPICallT< - ArgType extends RawArgType, - ResultType extends ValidResponse, - ErrorType extends InvalidResponse -> { - (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; - 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 undefined ? EmptyAPICallT : BasicAPICallT; - -export type GetAPICallT< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse -> = ArgType extends undefined ? EmptyGetAPICallT : BasicGetAPICallT; - -export type PostAPICallT< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse -> = ArgType extends undefined ? EmptyPostAPICallT : BasicPostAPICallT; - -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 type PatchAPICallT< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse -> = ArgType extends undefined ? EmptyPatchAPICallT : BasicPatchAPICallT; - -export type HeadAPICallT< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse -> = ArgType extends undefined ? EmptyHeadAPICallT : BasicHeadAPICallT; - -export type APITail = ReturnType | ReturnType | ReturnType | ReturnType | ReturnType | ReturnType; - -export function GET< - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): EmptyGetAPICallT -export function GET< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicGetAPICallT; -export function GET< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicGetAPICallT | EmptyGetAPICallT { - return Object.assign( - fakeGET, - { reqType: 'get' } as const - ) -} - -export function POST< - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): EmptyPostAPICallT -export function POST< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicPostAPICallT; -export function POST< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicPostAPICallT | EmptyPostAPICallT { - return Object.assign( - fakePOST, - { reqType: 'post' } as const - ) -} - -export function PUT< - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): EmptyPutAPICallT -export function PUT< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicPutAPICallT; -export function PUT< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicPutAPICallT | EmptyPutAPICallT { - return Object.assign( - fakePUT, - { reqType: 'put' } as const - ) -} - -export function DELETE< - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): EmptyDeleteAPICallT -export function DELETE< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicDeleteAPICallT; -export function DELETE< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicDeleteAPICallT | EmptyDeleteAPICallT { - return Object.assign( - fakeDELETE, - { reqType: 'delete' } as const - ) -} - -export function PATCH< - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): EmptyPatchAPICallT -export function PATCH< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicPatchAPICallT; -export function PATCH< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicPatchAPICallT | EmptyPatchAPICallT { - return Object.assign( - fakePATCH, - { reqType: 'patch' } as const - ) -} - -export function HEAD< - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): EmptyHeadAPICallT -export function HEAD< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = InvalidResponse, ->(): BasicHeadAPICallT; -export function HEAD< - ArgType extends RawArgType, - ResultType extends ValidResponse = ValidResponse, - ErrorType extends InvalidResponse = 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 ->(args?: ArgType, returnError = false): Promise { - throw `Can't directly call GET. ${args}, ${returnError}. Use auto-generated path API.` -} - -export async function fakePOST< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - 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 fakePUT< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - 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 fakeDELETE< - ResultType extends ValidResponse, - ErrorType extends InvalidResponse, - 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; -} - -export type recoveryMethod = 'refreshEntirePage' | 'retryAPI' | 'gameLogin' | 'gatewayLogin' | 'gateway2FA' | 'gameQuota'; -export interface InvalidResponse { - result: false; - reason: string; - recovery?: recoveryMethod; -} - -type ExtractValid = T extends ValidResponse ? T : never; -type ExtractInvalid = T extends InvalidResponse ? T : never; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type Callable = (...args: any) => any; - -export type ExtractResponse = ExtractValid>>; -export type ExtractError = ExtractInvalid>>; -export type ExtractQuery = Parameters[0]; - -export type DefAPINamespace = { - [key: string]: DefAPINamespace - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | BasicGetAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | BasicPostAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | BasicPutAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | BasicDeleteAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | BasicPatchAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | BasicHeadAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | EmptyGetAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | EmptyPostAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | EmptyPutAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | EmptyDeleteAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | EmptyPatchAPICallT - // eslint-disable-next-line @typescript-eslint/no-explicit-any - | EmptyHeadAPICallT - ; -} - -export type APICompatType = T extends APICallT ? APICallT : never; \ No newline at end of file diff --git a/server/apiStructure/sammoAPI.ts b/server/apiStructure/sammoAPI.ts deleted file mode 100644 index e29b7e4..0000000 --- a/server/apiStructure/sammoAPI.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { type DefAPINamespace, GET, POST } from "./defs.js"; - -/** @internal */ -export const structure = { - -} satisfies DefAPINamespace; \ No newline at end of file diff --git a/server/connectGatewayDB.ts b/server/connectGatewayDB.ts deleted file mode 100644 index 87c816f..0000000 --- a/server/connectGatewayDB.ts +++ /dev/null @@ -1,22 +0,0 @@ -import 'dotenv/config'; -import { connect, Mongoose } from "mongoose"; -import { unwrap } from './util/unwrap.js'; - -const dbConfig = { - host: unwrap(process.env.GATEWAY_DB_HOST), - port: Number(unwrap(process.env.GATEWAY_DB_PORT)), - user: unwrap(process.env.GATEWAY_DB_USER), - password: unwrap(process.env.GATEWAY_DB_PASSWORD), - database: unwrap(process.env.GATEWAY_DB_DATABASE), -} - -const gatewayDB: Promise = (async () => { - return await connect(`mongodb://${dbConfig.host}:${dbConfig.port}/${dbConfig.database}`, { - auth:{ - username: dbConfig.user, - password: dbConfig.password, - } - }); -})(); - -export default gatewayDB; \ No newline at end of file diff --git a/server/gateway.ts b/server/gateway.ts deleted file mode 100644 index 53f7e9f..0000000 --- a/server/gateway.ts +++ /dev/null @@ -1,37 +0,0 @@ -import 'reflect-metadata'; -import gatewayDB from './connectGatewayDB.js'; -import express, { type Request, type Response } from "express" -import session from "express-session"; -import path from 'node:path'; -import { LiteHashDRBG } from './util/LiteHashDRBG.js'; -import { simpleSerialize } from './util/simpleSerialize.js'; -import { SammoGatewayAPI } from './clientAPI/sammoGatewayAPI.js'; -import { buildAPISystem } from './api/generator.js'; -import { sammoGatewayAPI } from './api/gatewayAPI.js'; -import { unwrap } from './util/unwrap.js'; -import { gatewayConfig } from './gatewayConfig.js'; - - - - -gatewayDB.then(async (gatewayDB) => { - // create express app - const app = express() - app.use(express.json()); - app.use(session({ - secret: unwrap(gatewayConfig.sessionSecret), - resave: false, - saveUninitialized: false, - })) - //app.set('etag', false); - - app.use('/gateway_api', buildAPISystem(sammoGatewayAPI)); - - // start express server - app.listen(gatewayConfig.port) - - console.log(`Gateway server has started on port ${gatewayConfig.port}`) - -}).catch(error => console.log(error)); - -export default {}; \ No newline at end of file diff --git a/server/gatewayConfig.ts b/server/gatewayConfig.ts deleted file mode 100644 index 492a4ed..0000000 --- a/server/gatewayConfig.ts +++ /dev/null @@ -1,7 +0,0 @@ -import 'dotenv/config'; -import { unwrap } from './util/unwrap.js'; - -export const gatewayConfig = { - sessionSecret: unwrap(process.env.GATEWAY_SESSION_SECRET), - port: Number(unwrap(process.env.GATEWAY_PORT)), -}; \ No newline at end of file diff --git a/server/util/BytesLike.ts b/server/util/BytesLike.ts deleted file mode 100644 index e69de29..0000000 diff --git a/tsconfig.app.json b/tsconfig.app.json deleted file mode 100644 index 3e5b621..0000000 --- a/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "@vue/tsconfig/tsconfig.dom.json", - "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], - "exclude": ["src/**/__tests__/*"], - "compilerOptions": { - "composite": true, - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } - } -}