{
  "version": 3,
  "sources": ["../../src/router/index.ts"],
  "sourcesContent": ["import type express from \"express\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler, getRequest, setResponse } from \"@colyseus/better-call/node\";\nimport { Transport } from \"../Transport.ts\";\nimport { controller } from \"../matchmaker/controller.ts\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\nexport {\n  createEndpoint,\n  createMiddleware,\n  createInternalContext,\n\n  // Re-export types needed for declaration emit\n  type Router,\n  type RouterConfig,\n  type Endpoint,\n  type EndpointHandler,\n  type EndpointOptions,\n  type EndpointContext,\n  type StrictEndpoint,\n} from \"@colyseus/better-call\";\n\nexport { toNodeHandler };\n\nexport function bindRouterToTransport(transport: Transport, router: Router, useExpress: boolean) {\n  // add default \"/__healthcheck\" endpoint\n  router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n    return new Response(\"OK\", { status: 200 });\n  }));\n\n  const server = transport.server;\n\n  // check if the server is bound to an express app\n  const expressApp: express.Application = (useExpress)\n    ? transport.getExpressApp() as express.Application\n    // fallback searching for express app in server listeners\n    : server?.listeners('request').find((listener: Function) => listener.name === \"app\" && listener['mountpath'] === '/') as express.Application;\n\n  // add default \"/\" route, if not provided.\n  const hasRootRoute = (\n    // check if express app has a root route\n    (expressApp && expressRootRoute(expressApp) !== undefined) ||\n\n    // check if router has a root route\n    Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\")\n  );\n\n  if (!hasRootRoute) {\n    router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n      return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n    }));\n  }\n\n  // use custom bindRouter method if provided\n  if (!server && transport.bindRouter) {\n    transport.bindRouter(router);\n    return;\n  }\n\n  // which route handler to use\n  // (router + fallback to express, or just router)\n  let next: any;\n\n  if (expressApp) {\n    server.removeListener('request', expressApp);\n\n    next = async (req: IncomingMessage, res: ServerResponse) => {\n      // check if the route is defined in the router\n      // if so, use the router handler, otherwise fallback to express\n      if (router.findRoute(req.method, req.url.split('?')[0]) !== undefined) {\n        const protocol = req.headers[\"x-forwarded-proto\"] || ((req.socket as any).encrypted ? \"https\" : \"http\");\n        const base = `${protocol}://${req.headers[\":authority\"] || req.headers.host}`;\n        const response = await router.handler(getRequest({ base, request: req }));\n        return setResponse(res, response);\n\n      } else {\n        return expressApp['handle'](req, res);\n      }\n    };\n\n  } else {\n    next = toNodeHandler(router.handler);\n  }\n\n  // handle cors headers for all requests by default\n  server.prependListener('request', (req: IncomingMessage, res: ServerResponse) => {\n    const corsHeaders = {\n      ...controller.DEFAULT_CORS_HEADERS,\n      ...controller.getCorsHeaders(new Headers(req.headers as any)),\n    };\n\n    if (req.method === \"OPTIONS\") {\n      res.writeHead(204, corsHeaders);\n      res.end();\n      return;\n    }\n\n    Object.entries(corsHeaders).forEach(([key, value]) => {\n      res.setHeader(key, value);\n    });\n\n    next(req, res);\n  });\n}\n\nfunction expressRootRoute(expressApp: express.Application) {\n  //\n  // express v5 uses `app.router`, express v4 uses `app._router`\n  // check for `app._router` first, then `app.router`\n  //\n  // (express v4 will show a warning if `app.router` is used)\n  //\n  const stack = (expressApp as any)?._router?.stack ?? (expressApp as any)?.router?.stack;\n\n  if (!stack) {\n    return false;\n  }\n\n  return stack.find((layer: any) => layer.match('/') && !['query', 'expressInit'].includes(layer.name));\n}\n\n/**\n * Do not use this directly. This is used internally by `@colyseus/playground`.\n * TODO: refactor. Avoid using globals.\n * @internal\n */\nexport let __globalEndpoints: Record<string, Endpoint> = {};\n\nexport function createRouter<\n  E extends Record<string, Endpoint>,\n  Config extends RouterConfig\n>(endpoints: E, config: Config = {} as Config) {\n  // TODO: refactor. Avoid using globals.\n  __globalEndpoints = endpoints;\n\n  return createBetterCallRouter({ ...endpoints }, config);\n}\n"],
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAAsH;AACtH,kBAAuD;AACvD,uBAA0B;AAC1B,wBAA2B;AAC3B,qBAAgB;AAEhB,IAAAA,sBAaO;AAIA,SAAS,sBAAsB,WAAsB,QAAgB,YAAqB;AAE/F,SAAO,gBAAY,mCAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3C,CAAC,CAAC;AAEF,QAAM,SAAS,UAAU;AAGzB,QAAM,aAAmC,aACrC,UAAU,cAAc,IAExB,QAAQ,UAAU,SAAS,EAAE,KAAK,CAAC,aAAuB,SAAS,SAAS,SAAS,SAAS,WAAW,MAAM,GAAG;AAGtH,QAAM;AAAA;AAAA,IAEH,cAAc,iBAAiB,UAAU,MAAM;AAAA,IAGhD,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAAA;AAGxE,MAAI,CAAC,cAAc;AACjB,WAAO,gBAAY,mCAAe,KAAK,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACvE,aAAO,IAAI,SAAS,YAAY,eAAAC,QAAI,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IAChE,CAAC,CAAC;AAAA,EACJ;AAGA,MAAI,CAAC,UAAU,UAAU,YAAY;AACnC,cAAU,WAAW,MAAM;AAC3B;AAAA,EACF;AAIA,MAAI;AAEJ,MAAI,YAAY;AACd,WAAO,eAAe,WAAW,UAAU;AAE3C,WAAO,OAAO,KAAsB,QAAwB;AAG1D,UAAI,OAAO,UAAU,IAAI,QAAQ,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC,MAAM,QAAW;AACrE,cAAM,WAAW,IAAI,QAAQ,mBAAmB,MAAO,IAAI,OAAe,YAAY,UAAU;AAChG,cAAM,OAAO,GAAG,QAAQ,MAAM,IAAI,QAAQ,YAAY,KAAK,IAAI,QAAQ,IAAI;AAC3E,cAAM,WAAW,MAAM,OAAO,YAAQ,wBAAW,EAAE,MAAM,SAAS,IAAI,CAAC,CAAC;AACxE,mBAAO,yBAAY,KAAK,QAAQ;AAAA,MAElC,OAAO;AACL,eAAO,WAAW,QAAQ,EAAE,KAAK,GAAG;AAAA,MACtC;AAAA,IACF;AAAA,EAEF,OAAO;AACL,eAAO,2BAAc,OAAO,OAAO;AAAA,EACrC;AAGA,SAAO,gBAAgB,WAAW,CAAC,KAAsB,QAAwB;AAC/E,UAAM,cAAc;AAAA,MAClB,GAAG,6BAAW;AAAA,MACd,GAAG,6BAAW,eAAe,IAAI,QAAQ,IAAI,OAAc,CAAC;AAAA,IAC9D;AAEA,QAAI,IAAI,WAAW,WAAW;AAC5B,UAAI,UAAU,KAAK,WAAW;AAC9B,UAAI,IAAI;AACR;AAAA,IACF;AAEA,WAAO,QAAQ,WAAW,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACpD,UAAI,UAAU,KAAK,KAAK;AAAA,IAC1B,CAAC;AAED,SAAK,KAAK,GAAG;AAAA,EACf,CAAC;AACH;AAEA,SAAS,iBAAiB,YAAiC;AAOzD,QAAM,QAAS,YAAoB,SAAS,SAAU,YAAoB,QAAQ;AAElF,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,KAAK,CAAC,UAAe,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,SAAS,MAAM,IAAI,CAAC;AACtG;AAOO,IAAI,oBAA8C,CAAC;AAEnD,SAAS,aAGd,WAAc,SAAiB,CAAC,GAAa;AAE7C,sBAAoB;AAEpB,aAAO,mBAAAC,cAAuB,EAAE,GAAG,UAAU,GAAG,MAAM;AACxD;",
  "names": ["import_better_call", "pkg", "createBetterCallRouter"]
}
