{"version":3,"file":"fetch-router.cjs","names":[],"sources":["../../../../src/v2/runtime/core/fetch-router.ts"],"sourcesContent":["/**\n * Lightweight URL router for framework-agnostic CopilotKit runtime handler.\n *\n * Two strategies:\n * - With `basePath`: strict prefix strip → match remainder\n * - Without `basePath`: suffix matching on known patterns\n *\n * Single-route mode: delegates to `parseMethodCall` for JSON envelope dispatch.\n */\n\nimport type { RouteInfo } from \"./hooks\";\n\n/**\n * Match a request URL against known CopilotKit route patterns.\n *\n * @param pathname - The URL pathname to match\n * @param basePath - Optional base path prefix to strip first\n * @returns RouteInfo if matched, null otherwise\n */\nexport function matchRoute(\n  pathname: string,\n  basePath?: string,\n): RouteInfo | null {\n  let remainder: string;\n\n  if (basePath) {\n    // Normalize: ensure basePath doesn't end with /\n    const normalizedBase =\n      basePath.length > 1 && basePath.endsWith(\"/\")\n        ? basePath.slice(0, -1)\n        : basePath;\n\n    // Special case: basePath === \"/\" matches everything\n    if (normalizedBase === \"/\") {\n      remainder = pathname;\n    } else {\n      if (!pathname.startsWith(normalizedBase)) return null;\n\n      // The character after basePath must be \"/\" or end of string\n      const afterBase = pathname.slice(normalizedBase.length);\n      if (afterBase.length > 0 && !afterBase.startsWith(\"/\")) return null;\n\n      remainder = afterBase || \"/\";\n    }\n  } else {\n    // Suffix matching: find known patterns at the end of the pathname\n    remainder = pathname;\n  }\n\n  return matchSegments(remainder);\n}\n\nfunction safeDecodeURIComponent(value: string): string | null {\n  try {\n    return decodeURIComponent(value);\n  } catch {\n    return null;\n  }\n}\n\nfunction matchSegments(path: string): RouteInfo | null {\n  const segments = path.split(\"/\").filter(Boolean);\n  const len = segments.length;\n\n  // Try suffix matching — scan from the end for known patterns\n\n  // /info (1 segment)\n  if (len >= 1 && segments[len - 1] === \"info\") {\n    return { method: \"info\" };\n  }\n\n  // /transcribe (1 segment)\n  if (len >= 1 && segments[len - 1] === \"transcribe\") {\n    return { method: \"transcribe\" };\n  }\n\n  // /agent/:agentId/run (3 segments)\n  if (\n    len >= 3 &&\n    segments[len - 3] === \"agent\" &&\n    segments[len - 1] === \"run\"\n  ) {\n    const agentId = safeDecodeURIComponent(segments[len - 2]!);\n    if (!agentId) return null;\n    return { method: \"agent/run\", agentId };\n  }\n\n  // /agent/:agentId/connect (3 segments)\n  if (\n    len >= 3 &&\n    segments[len - 3] === \"agent\" &&\n    segments[len - 1] === \"connect\"\n  ) {\n    const agentId = safeDecodeURIComponent(segments[len - 2]!);\n    if (!agentId) return null;\n    return { method: \"agent/connect\", agentId };\n  }\n\n  // /agent/:agentId/stop/:threadId (4 segments)\n  if (\n    len >= 4 &&\n    segments[len - 4] === \"agent\" &&\n    segments[len - 2] === \"stop\"\n  ) {\n    const agentId = safeDecodeURIComponent(segments[len - 3]!);\n    const threadId = safeDecodeURIComponent(segments[len - 1]!);\n    if (!agentId || !threadId) return null;\n    return { method: \"agent/stop\", agentId, threadId };\n  }\n\n  // /threads/subscribe (2 segments)\n  if (\n    len >= 2 &&\n    segments[len - 2] === \"threads\" &&\n    segments[len - 1] === \"subscribe\"\n  ) {\n    return { method: \"threads/subscribe\" };\n  }\n\n  // /threads/:threadId/messages (3 segments)\n  if (\n    len >= 3 &&\n    segments[len - 3] === \"threads\" &&\n    segments[len - 1] === \"messages\"\n  ) {\n    const threadId = safeDecodeURIComponent(segments[len - 2]!);\n    if (!threadId) return null;\n    return { method: \"threads/messages\", threadId };\n  }\n\n  // /threads/:threadId/archive (3 segments)\n  if (\n    len >= 3 &&\n    segments[len - 3] === \"threads\" &&\n    segments[len - 1] === \"archive\"\n  ) {\n    const threadId = safeDecodeURIComponent(segments[len - 2]!);\n    if (!threadId) return null;\n    return { method: \"threads/archive\", threadId };\n  }\n\n  // /threads/:threadId (2 segments) — update or delete\n  if (\n    len >= 2 &&\n    segments[len - 2] === \"threads\" &&\n    segments[len - 1] !== \"subscribe\"\n  ) {\n    const threadId = safeDecodeURIComponent(segments[len - 1]!);\n    if (!threadId) return null;\n    // Disambiguated by HTTP method in the handler\n    return { method: \"threads/update\", threadId };\n  }\n\n  // /threads (1 segment) — list\n  if (len >= 1 && segments[len - 1] === \"threads\") {\n    return { method: \"threads/list\" };\n  }\n\n  return null;\n}\n"],"mappings":";;;;;;;;;;AAmBA,SAAgB,WACd,UACA,UACkB;CAClB,IAAI;AAEJ,KAAI,UAAU;EAEZ,MAAM,iBACJ,SAAS,SAAS,KAAK,SAAS,SAAS,IAAI,GACzC,SAAS,MAAM,GAAG,GAAG,GACrB;AAGN,MAAI,mBAAmB,IACrB,aAAY;OACP;AACL,OAAI,CAAC,SAAS,WAAW,eAAe,CAAE,QAAO;GAGjD,MAAM,YAAY,SAAS,MAAM,eAAe,OAAO;AACvD,OAAI,UAAU,SAAS,KAAK,CAAC,UAAU,WAAW,IAAI,CAAE,QAAO;AAE/D,eAAY,aAAa;;OAI3B,aAAY;AAGd,QAAO,cAAc,UAAU;;AAGjC,SAAS,uBAAuB,OAA8B;AAC5D,KAAI;AACF,SAAO,mBAAmB,MAAM;SAC1B;AACN,SAAO;;;AAIX,SAAS,cAAc,MAAgC;CACrD,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;CAChD,MAAM,MAAM,SAAS;AAKrB,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,OACpC,QAAO,EAAE,QAAQ,QAAQ;AAI3B,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,aACpC,QAAO,EAAE,QAAQ,cAAc;AAIjC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,OACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;AAC1D,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO;GAAE,QAAQ;GAAa;GAAS;;AAIzC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,WACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;AAC1D,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO;GAAE,QAAQ;GAAiB;GAAS;;AAI7C,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,QACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;EAC1D,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,WAAW,CAAC,SAAU,QAAO;AAClC,SAAO;GAAE,QAAQ;GAAc;GAAS;GAAU;;AAIpD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,YAEtB,QAAO,EAAE,QAAQ,qBAAqB;AAIxC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,YACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAoB;GAAU;;AAIjD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,WACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAmB;GAAU;;AAIhD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,aACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AAEtB,SAAO;GAAE,QAAQ;GAAkB;GAAU;;AAI/C,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,UACpC,QAAO,EAAE,QAAQ,gBAAgB;AAGnC,QAAO"}