UNPKG

@colyseus/core

Version:

Multiplayer Framework for Node.js.

85 lines (84 loc) 3.09 kB
// packages/core/src/router/index.ts import { createRouter as createBetterCallRouter, createEndpoint } from "@colyseus/better-call"; import { toNodeHandler, getRequest, setResponse } from "@colyseus/better-call/node"; import "../Transport.mjs"; import { controller } from "../matchmaker/controller.mjs"; import pkg from "../../package.json" with { type: "json" }; import { createEndpoint as createEndpoint2, createMiddleware, createInternalContext } from "@colyseus/better-call"; function bindRouterToTransport(transport, router, useExpress) { router.addEndpoint(createEndpoint("/__healthcheck", { method: "GET" }, async (ctx) => { return new Response("OK", { status: 200 }); })); const server = transport.server; const expressApp = useExpress ? transport.getExpressApp() : server?.listeners("request").find((listener) => listener.name === "app" && listener["mountpath"] === "/"); const hasRootRoute = ( // check if express app has a root route expressApp && expressRootRoute(expressApp) !== void 0 || // check if router has a root route Object.values(router.endpoints).some((endpoint) => endpoint.path === "/") ); if (!hasRootRoute) { router.addEndpoint(createEndpoint("/", { method: "GET" }, async (ctx) => { return new Response(`Colyseus ${pkg.version}`, { status: 200 }); })); } if (!server && transport.bindRouter) { transport.bindRouter(router); return; } let next; if (expressApp) { server.removeListener("request", expressApp); next = async (req, res) => { if (router.findRoute(req.method, req.url.split("?")[0]) !== void 0) { const protocol = req.headers["x-forwarded-proto"] || (req.socket.encrypted ? "https" : "http"); const base = `${protocol}://${req.headers[":authority"] || req.headers.host}`; const response = await router.handler(getRequest({ base, request: req })); return setResponse(res, response); } else { return expressApp["handle"](req, res); } }; } else { next = toNodeHandler(router.handler); } server.prependListener("request", (req, res) => { const corsHeaders = { ...controller.DEFAULT_CORS_HEADERS, ...controller.getCorsHeaders(new Headers(req.headers)) }; if (req.method === "OPTIONS") { res.writeHead(204, corsHeaders); res.end(); return; } Object.entries(corsHeaders).forEach(([key, value]) => { res.setHeader(key, value); }); next(req, res); }); } function expressRootRoute(expressApp) { const stack = expressApp?._router?.stack ?? expressApp?.router?.stack; if (!stack) { return false; } return stack.find((layer) => layer.match("/") && !["query", "expressInit"].includes(layer.name)); } var __globalEndpoints = {}; function createRouter(endpoints, config = {}) { __globalEndpoints = endpoints; return createBetterCallRouter({ ...endpoints }, config); } export { __globalEndpoints, bindRouterToTransport, createEndpoint2 as createEndpoint, createInternalContext, createMiddleware, createRouter, toNodeHandler };