@colyseus/core
Version:
Multiplayer Framework for Node.js.
85 lines (84 loc) • 3.09 kB
JavaScript
// 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
};