diff options
Diffstat (limited to 'source/index.js')
| -rw-r--r-- | source/index.js | 115 |
1 files changed, 112 insertions, 3 deletions
diff --git a/source/index.js b/source/index.js index fb25ff9..21429f9 100644 --- a/source/index.js +++ b/source/index.js @@ -1,6 +1,112 @@ import puppeteer from "@cloudflare/puppeteer"; -import Router from "./library/router/index.js"; -import talent96 from "./data/talent96.js"; + +/* + Router class to handle routing of requests based on the request path. + + @param {Request} request - the incoming request object + @param {Environment} environment - the environment object + @param {Context} context - the context object + + @returns {Response} a new Response object +*/ +class Router { + constructor(request, environment, context) { + this.request = request; + this.environment = environment; + this.context = context; + this.routes = new Map(); // Use Map for faster lookups + this.parameters = {}; // Store extracted route parameters + } + + /* + Add a new route to the router. + + @param {string} path - the path to match + @param {function} handler - the handler function to call if the path matches + + @returns {Router} the router object + */ + add(path, handler) { + if (typeof path !== "string") { + throw new TypeError("Path must be a string"); + } + if (typeof handler !== "function") { + throw new TypeError("Handler must be a function"); + } + + const normalizedPath = path.replace(/\/+$/, ""); // Normalize path + const pathRegex = new RegExp( + "^" + + normalizedPath + .replace(/:[^/]+/g, "([^/]+)") // Convert :param to regex group + .replace(/\//g, "\\/") + + "$" + ); + this.routes.set(pathRegex, { handler, originalPath: normalizedPath }); + return this; + } + + /* + Helper function to respond with a JSON object. + + @param {object} body - the JSON object to respond with + + @returns {Response} a new Response object + */ + respond(body, status = 200) { + return new Response(JSON.stringify(body), { + status, + headers: { + "Access-Control-Allow-Origin": "*", + "Content-Type": "application/json", + }, + }); + } + + /* + Route the request to the appropriate handler based on the request path. + + @returns {Response} a new Response object + */ + route() { + try { + const url = new URL(this.request.url); + const normalizedPath = url.pathname.replace(/\/+$/, ""); // Remove trailing slashes + + for (const [pathRegex, { handler, originalPath }] of this.routes) { + const match = normalizedPath.match(pathRegex); + if (match) { + // Extract parameters + const paramNames = [...originalPath.matchAll(/:([^/]+)/g)].map( + (m) => m[1] + ); + this.parameters = paramNames.reduce((params, name, index) => { + params[name] = match[index + 1]; + return params; + }, {}); + + return handler(this.request, this.environment, this.context); + } + } + + // Return 404 if route not found + return this.respond( + { + error: `Route not found: ${normalizedPath}`, + }, + 404 + ); + } catch (error) { + // Handle unexpected errors + return this.respond( + { + error: `Internal Server Error: ${error.message}`, + }, + 500 + ); + } + } +} export default { /* @@ -84,7 +190,10 @@ export default { error: `channel not provided`, }); - const whitelist = ["zuedev", ...talent96]; + const whitelist = [ + "zuedev", + ...["vtsweets", "bunnibana", "yayjaybae", "justawoney", "tygiwygi"], + ]; if (!whitelist.includes(channel)) return router.respond({ |
