diff --git a/.gitignore b/.gitignore index a582a2f3..8d2feb42 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ yarn.lock dbconf.json migrations.db + +package-lock.json diff --git a/build.json.default b/build.json.default index cac0a850..22b85300 100644 --- a/build.json.default +++ b/build.json.default @@ -11,6 +11,6 @@ "quiet": false, "steps": { "pre": ["clean"], - "post": ["remap_imports"] + "post": ["util_resources", "remap_imports"] } } diff --git a/scripts/build/util_resources.js b/scripts/build/util_resources.js new file mode 100644 index 00000000..17733ba8 --- /dev/null +++ b/scripts/build/util_resources.js @@ -0,0 +1,19 @@ +const { execSync } = require("child_process"); +const path = require("path"); +const fs = require("fs"); +const { argv, stdout, exit } = require("process"); +const { execIn, parts, getDirs, walk, sanitizeVarName } = require("../utils"); + +module.exports = function (config) { + console.log(`==> Copying all util resources...`); + let utilRes = walk(path.join(config.srcDir, "api", "routes-util")).filter((x) => !x.endsWith(".ts")); + utilRes.forEach((x) => { + fs.copyFileSync(x, x.replace("src", "dist")); + }); + console.log(`==> Cleaning util resources...`); + let dirt = walk(path.join(config.distDir, "api", "routes-util")).filter((x) => x.endsWith(".ts") || x.endsWith(".js.map") || x.endsWith(".d.ts")); + dirt.forEach((x) => { + fs.rmSync(x, { force: true }); + }); + +}; diff --git a/src/api/Server.ts b/src/api/Server.ts index e92335a5..d5ca50a0 100644 --- a/src/api/Server.ts +++ b/src/api/Server.ts @@ -1,6 +1,6 @@ -import { Config, getOrInitialiseDatabase, initEvent, registerRoutes } from "@fosscord/util"; +import { Config, getOrInitialiseDatabase, initEvent, registerRoutes, walk } from "@fosscord/util"; import { NextFunction, Request, Response, Router } from "express"; -import { Server, ServerOptions } from "lambert-server"; +import { Server, ServerOptions, traverseDirectory } from "lambert-server"; import morgan from "morgan"; import path from "path"; import { red } from "picocolors"; @@ -82,6 +82,24 @@ export class FosscordServer extends Server { app.use("/api/v9", api); app.use("/api", api); // allow unversioned requests + let utils = walk(path.join(__dirname, "routes-util")); + for (let file of utils) { + const fullPath = file; + file = file.replace(path.join(__dirname, "routes-util"), ""); + console.log(`[API] Registering util ${file}`); + if(file.endsWith(".js") || file.endsWith(".ts") && !file.endsWith(".web.js")) { + require(fullPath).default("/util/" + file.replace(".ts","").replace(".js", ""), app); + } + else { + app.use("/util/"+file, (req, res) => { + return res.sendFile(path.join(__dirname, "routes-util", file)); + }) + } + } + /*await traverseDirectory({dirname: }, (file) => { + app.use("/" + file, (file.endsWith(".ts") || file.endsWith(".js")) ? require(file) : (req, res) => res.status(404).json({ message: "404 endpoint not found", code: 0 })); + });*/ + this.app.use(ErrorHandler); TestClient(this.app); diff --git a/src/api/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts index 6d063953..741a2454 100644 --- a/src/api/middlewares/Authentication.ts +++ b/src/api/middlewares/Authentication.ts @@ -44,6 +44,7 @@ declare global { export async function Authentication(req: Request, res: Response, next: NextFunction) { if (req.method === "OPTIONS") return res.sendStatus(204); + if (req.url.startsWith("/util")) return next(); const url = req.url.replace(API_PREFIX, ""); if (url.startsWith("/invites") && req.method === "GET") return next(); if ( diff --git a/src/api/middlewares/TestClient.ts b/src/api/middlewares/TestClient.ts index 3afd0339..1ff8120e 100644 --- a/src/api/middlewares/TestClient.ts +++ b/src/api/middlewares/TestClient.ts @@ -83,6 +83,7 @@ export default function TestClient(app: Application) { res.send(fs.readFileSync(path.join(__dirname, "..", "..", "..", "assets", "developers.html"), { encoding: "utf8" })); }); app.get("*", (req: Request, res: Response) => { + if (req.url.startsWith("/util")) return; const { useTestClient } = Config.get().client; res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24); res.set("content-type", "text/html"); diff --git a/src/api/routes-util/test.css b/src/api/routes-util/test.css new file mode 100644 index 00000000..e69de29b diff --git a/src/api/routes-util/test.ts b/src/api/routes-util/test.ts new file mode 100644 index 00000000..6c420381 --- /dev/null +++ b/src/api/routes-util/test.ts @@ -0,0 +1,12 @@ +import { Config, Release } from "@fosscord/util"; +import { Request, Response, Router } from "express"; +import { route } from ".."; + +export default (path: string, router: Router) => { + router.get(path, route({}), async (req: Request, res: Response) => { + router.get("/", route({}), async (req: Request, res: Response) => { + res.json({ok:true}); + }); + }); +}; + diff --git a/src/util/util/Directory.ts b/src/util/util/Directory.ts new file mode 100644 index 00000000..73c54f12 --- /dev/null +++ b/src/util/util/Directory.ts @@ -0,0 +1,29 @@ +import fs from "fs"; +import path from "path"; + +export function getDirs(dir: string) { + return fs.readdirSync(dir).filter((x) => { + try { + fs.readdirSync(path.join(dir, x)); + return true; + } catch (e) { + return false; + } + }); +} + +export function walk(dir: string) { + let results: string[] = []; + let list = fs.readdirSync(dir); + list.forEach(function (file) { + file = dir + "/" + file; + let stat = fs.statSync(file); + if (stat && stat.isDirectory()) { + /* Recurse into a subdirectory */ + results = results.concat(walk(file)); + } else { + results.push(file); + } + }); + return results; +} \ No newline at end of file diff --git a/src/util/util/index.ts b/src/util/util/index.ts index 11f0b72a..8b291204 100644 --- a/src/util/util/index.ts +++ b/src/util/util/index.ts @@ -23,3 +23,4 @@ export * from "./Snowflake"; export * from "./String"; export * from "./Token"; export * from "./TraverseDirectory"; +export * from "./Directory"; \ No newline at end of file