Updated dependencies + A few other things (!150)
Initially this was going to be an update to dependencies but it seems i got a little carried away!
Anyways this PR removes 2 unused dependencies (`jshint` and `utf-8-validate`), and 2 other, `del` and `fs-extra` that were replaced by the built-in `fs/promises`.
It also renames all `tsconfig` and `Dockerfile` files, in a way that when viewed in a file tree sorted alphabetically they will be next to each other.
It also updates the typescript target to `ES2022`, and changes moduleResolution from `Node` to `Node10` (this isn't an update, they are the same thing but `Node` is now deprecated).
It also adds the `node:` discriminator to every import from built-in modules.
It also has major changes to the build script, `del` and `fs-extra` were only being used in the build script, it's now using `fs/promises` instead, cleaned up the code from some functions, adds better documentation to a few functions, and renames some gulp tasks and npm scripts to better represent what they actually do.
And finally it updates dependencies, except for `atomically` which can't be updated unless the project switches to ESM.
Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Server/pulls/150
Co-authored-by: TheSparta <thesparta@noreply.dev.sp-tarkov.com>
Co-committed-by: TheSparta <thesparta@noreply.dev.sp-tarkov.com>
2023-10-14 11:01:41 +02:00
|
|
|
import { IncomingMessage } from "node:http";
|
2023-11-13 17:43:37 +01:00
|
|
|
import { injectAll, injectable } from "tsyringe";
|
2023-03-03 16:23:46 +01:00
|
|
|
|
2023-10-19 19:21:17 +02:00
|
|
|
import { DynamicRouter, Router, StaticRouter } from "@spt-aki/di/Router";
|
2023-03-03 16:23:46 +01:00
|
|
|
|
|
|
|
@injectable()
|
|
|
|
export class HttpRouter
|
|
|
|
{
|
|
|
|
constructor(
|
|
|
|
@injectAll("StaticRoutes") protected staticRouters: StaticRouter[],
|
2023-11-13 17:12:17 +01:00
|
|
|
@injectAll("DynamicRoutes") protected dynamicRoutes: DynamicRouter[],
|
2023-03-03 16:23:46 +01:00
|
|
|
)
|
2023-11-13 17:12:17 +01:00
|
|
|
{}
|
2023-03-03 16:23:46 +01:00
|
|
|
|
2023-11-13 17:12:17 +01:00
|
|
|
protected groupBy<T>(list: T[], keyGetter: (t: T) => string): Map<string, T[]>
|
2023-03-03 16:23:46 +01:00
|
|
|
{
|
|
|
|
const map: Map<string, T[]> = new Map();
|
2023-10-31 18:46:14 +01:00
|
|
|
for (const item of list)
|
2023-03-03 16:23:46 +01:00
|
|
|
{
|
|
|
|
const key = keyGetter(item);
|
|
|
|
const collection = map.get(key);
|
|
|
|
if (!collection)
|
|
|
|
{
|
|
|
|
map.set(key, [item]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
collection.push(item);
|
|
|
|
}
|
2023-10-31 18:46:14 +01:00
|
|
|
}
|
2023-03-03 16:23:46 +01:00
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
2024-04-28 15:45:36 +02:00
|
|
|
public async getResponse(req: IncomingMessage, info: any, sessionID: string): Promise<string>
|
2023-03-03 16:23:46 +01:00
|
|
|
{
|
|
|
|
const wrapper: ResponseWrapper = new ResponseWrapper("");
|
|
|
|
let url = req.url;
|
|
|
|
|
|
|
|
// remove retry from url
|
2023-03-18 10:19:20 +01:00
|
|
|
if (url?.includes("?retry="))
|
2023-03-03 16:23:46 +01:00
|
|
|
{
|
|
|
|
url = url.split("?retry=")[0];
|
|
|
|
}
|
2024-04-28 15:45:36 +02:00
|
|
|
const handled = await this.handleRoute(url, info, sessionID, wrapper, this.staticRouters, false);
|
2023-03-03 16:23:46 +01:00
|
|
|
if (!handled)
|
|
|
|
{
|
2024-04-28 15:45:36 +02:00
|
|
|
await this.handleRoute(url, info, sessionID, wrapper, this.dynamicRoutes, true);
|
2023-03-03 16:23:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Temporary hack to change ItemEventRouter response sessionID binding to what client expects
|
2023-03-18 10:19:20 +01:00
|
|
|
if (wrapper.output?.includes("\"profileChanges\":{"))
|
2023-03-03 16:23:46 +01:00
|
|
|
{
|
2023-12-27 23:01:30 +01:00
|
|
|
wrapper.output = wrapper.output.replace(sessionID, sessionID);
|
2023-03-03 16:23:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return wrapper.output;
|
|
|
|
}
|
|
|
|
|
2024-04-28 15:45:36 +02:00
|
|
|
protected async handleRoute(
|
2023-11-13 17:12:17 +01:00
|
|
|
url: string,
|
|
|
|
info: any,
|
|
|
|
sessionID: string,
|
|
|
|
wrapper: ResponseWrapper,
|
|
|
|
routers: Router[],
|
|
|
|
dynamic: boolean,
|
2024-04-28 15:45:36 +02:00
|
|
|
): Promise<boolean>
|
2023-03-03 16:23:46 +01:00
|
|
|
{
|
|
|
|
let matched = false;
|
|
|
|
for (const route of routers)
|
|
|
|
{
|
|
|
|
if (route.canHandle(url, dynamic))
|
|
|
|
{
|
|
|
|
if (dynamic)
|
|
|
|
{
|
2024-04-28 15:45:36 +02:00
|
|
|
wrapper.output = await (route as DynamicRouter).handleDynamic(url, info, sessionID, wrapper.output);
|
2023-03-03 16:23:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-04-28 15:45:36 +02:00
|
|
|
wrapper.output = await (route as StaticRouter).handleStatic(url, info, sessionID, wrapper.output);
|
2023-03-03 16:23:46 +01:00
|
|
|
}
|
|
|
|
matched = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return matched;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ResponseWrapper
|
|
|
|
{
|
2023-11-13 18:31:52 +01:00
|
|
|
constructor(public output: string)
|
2023-03-03 16:23:46 +01:00
|
|
|
{}
|
2023-11-13 17:12:17 +01:00
|
|
|
}
|