{"version":3,"sources":["../src/runtime/server-utils.ts"],"sourcesContent":["import type { H3Event } from \"h3\";\nimport type { ServiceInstanceInfo } from \"../types\";\nimport { getConfig, getGlobalState, updateConfigPort } from \"../utils/config\";\nimport {\n  DEFAULT_PORT,\n  DEFAULT_LANE_TARGET_HEADER,\n  HEADER_LANE_DEBUG,\n  HEADER_LANE_DETAIL,\n  getSafeHeaderValue\n} from \"../utils/defaults\";\nimport { logger } from \"../utils/logger\";\nimport { deregisterServiceInstance, getNacosLaneInstances, registerServiceInstance, startHeartbeat, stopHeartbeat } from \"../utils/nacos\";\nimport { LoadBalanceStrategy, proxyRequestWithFailover, selectInstance } from \"../utils/proxy\";\n\n/**\n * 从cookie字符串中解析指定key的值\n *\n * @param cookieHeader cookie字符串，格式如 \"key1=value1; key2=value2\"\n * @param key 要查找的cookie键名\n * @returns 找到的cookie值，如果未找到则返回undefined\n */\nfunction parseCookieValue(cookieHeader: string, key: string): string | undefined {\n  console.log(`[multi-lane-manager] 解析Cookie: cookieHeader=${cookieHeader}, key=${key}`);\n\n  if (!cookieHeader || !key) {\n    console.log(`[multi-lane-manager] Cookie解析失败: cookieHeader或key为空`);\n    return undefined;\n  }\n\n  // 将cookie字符串分割成键值对数组\n  const cookies = cookieHeader.split(';');\n  console.log(`[multi-lane-manager] Cookie分割结果: ${JSON.stringify(cookies)}`);\n\n  // 查找匹配的cookie\n  for (const cookie of cookies) {\n    console.log(`[multi-lane-manager] 处理Cookie片段: ${cookie}`);\n\n    const parts = cookie.split('=');\n    if (parts.length < 2) {\n      console.log(`[multi-lane-manager] 无效的Cookie格式: ${cookie}`);\n      continue;\n    }\n\n    const cookieKey = parts[0].trim();\n    const cookieValue = parts.slice(1).join('=').trim(); // 处理值中可能包含等号的情况\n\n    console.log(`[multi-lane-manager] Cookie键值对: key=${cookieKey}, value=${cookieValue}`);\n\n    // 不区分大小写比较cookie键名\n    if (cookieKey.toLowerCase() === key.toLowerCase()) {\n      console.log(`[multi-lane-manager] 找到匹配的Cookie: ${cookieKey}=${cookieValue}`);\n      return cookieValue;\n    }\n  }\n\n  console.log(`[multi-lane-manager] 未找到匹配的Cookie: ${key}`);\n  return undefined;\n}\n\n/**\n * 从环境变量或 Nitro 配置中获取服务器端口\n * 优先使用环境变量中的端口配置\n *\n * @returns 服务器端口\n */\nexport function getServerPort(): number {\n  // 优先使用环境变量中的端口\n  const port = parseInt(process.env.NITRO_PORT || process.env.PORT || String(DEFAULT_PORT), 10);\n  logger.debug(`🔍 从环境变量获取服务器端口: ${port}`);\n  return port;\n}\n\n/**\n * 自动检测和注册服务实例\n * 这个函数主要负责服务注册和设置进程退出处理程序\n *\n * @returns 是否尝试了注册\n */\nexport function detectPortAndRegisterOnFirstRequest(): boolean {\n  logger.info(`====== 🚀 开始端口检测和服务注册流程 ======`);\n\n  // 获取配置\n  logger.debug(`📋 正在加载配置...`);\n  const config = getConfig();\n\n  try {\n    // 检查泳道功能是否启用\n    logger.debug(`🔍 检查泳道功能是否启用: ${config.isLaneEnabled}`);\n    if (!config.isLaneEnabled) {\n      logger.debug(`🚫 泳道功能未启用，跳过初始注册`);\n      return false;\n    }\n\n    // 获取服务器端口\n    const serverPort = getServerPort();\n    logger.info(`🔌 检测到服务器端口: ${serverPort}`);\n\n    // 检查全局注册状态\n    const globalState = getGlobalState();\n\n    if (!globalState._laneMgrRegistered) {\n      logger.info(`🆕 首次检测到端口 ${serverPort}，准备注册服务...`);\n\n      // 设置全局注册状态\n      globalState._laneMgrRegistered = true;\n      globalState._laneMgrPort = serverPort;\n\n      // 更新配置中的端口\n      updateConfigPort(serverPort);\n\n      // 注册服务实例\n      registerServiceInstance(serverPort)\n        .then((success) => {\n          if (success) {\n            logger.info(`✅ 服务注册成功，设置进程退出处理程序`);\n\n            // 创建优雅退出处理函数\n            const gracefulShutdown = async () => {\n              logger.info(`🛑 应用退出/信号，正在注销服务，端口=${serverPort}...`);\n              await deregisterServiceInstance(serverPort);\n            };\n\n            // 注册进程退出事件处理程序\n            process.on(\"beforeExit\", gracefulShutdown);\n            process.on(\"SIGINT\", async () => {\n              logger.info(\"🔴 收到 SIGINT 信号，执行注销...\");\n              await gracefulShutdown();\n              process.exit(0);\n            });\n            process.on(\"SIGTERM\", async () => {\n              logger.info(\"🔴 收到 SIGTERM 信号，执行注销...\");\n              await gracefulShutdown();\n              process.exit(0);\n            });\n          } else {\n            logger.warn(`⚠️ 服务注册失败，不设置退出处理程序`);\n          }\n        })\n        .catch((err) => {\n          logger.error(`❌ 注册过程中出错: ${err.message}`, err.stack);\n        });\n\n      logger.info(`====== ✅ 端口检测和服务注册流程完成，返回 true ======`);\n      return true;\n    } else {\n      logger.info(`ℹ️ 服务已注册 (端口: ${globalState._laneMgrPort})，跳过初始注册`);\n    }\n\n    logger.info(`====== ✅ 端口检测和服务注册流程完成，返回 false ======`);\n    return false;\n  } catch (error) {\n    logger.error(\n      `❌ 端口检测或初始注册错误: ${error instanceof Error ? error.message : String(error)}`,\n      error instanceof Error ? error.stack : \"\",\n    );\n    return false;\n  }\n}\n\n/**\n * 创建服务器中间件以处理跨泳道代理\n * 这个中间件负责检测请求的目标泳道，并在必要时将请求转发到目标泳道的实例\n * 注意：服务注册逻辑已移至 Nitro 插件\n *\n * @returns 中间件处理函数\n */\nexport function createServerMiddleware() {\n  const config = getConfig();\n\n  // 使用 console.log 确保日志一定会输出\n  console.log(`[multi-lane-manager] 🔧 服务器中间件初始化: 启用状态=${config.isLaneEnabled}, 当前泳道ID=${config.currentLaneId}, 服务名=${config.serviceName}, 目标泳道Header=${config.targetLaneHeaderKey || DEFAULT_LANE_TARGET_HEADER.toLowerCase()}, Cookie检测=${config.isLaneCookieEnabled ? '启用' : '禁用'}`);\n\n  logger.info(\n    `🔧 服务器中间件初始化: 启用状态=${config.isLaneEnabled}, 当前泳道ID=${config.currentLaneId}, 服务名=${config.serviceName}, 目标泳道Header=${config.targetLaneHeaderKey || DEFAULT_LANE_TARGET_HEADER.toLowerCase()}, Cookie检测=${config.isLaneCookieEnabled ? '启用' : '禁用'}`,\n  );\n\n  return async (event: H3Event) => {\n    // 检查是否启用了调试模式\n    const debugHeaderKey = HEADER_LANE_DEBUG.toLowerCase();\n    const debugHeaderValue = event.node.req.headers[debugHeaderKey];\n    const isDebugMode = !!debugHeaderValue;\n\n    // 记录调试模式检测过程\n    console.log(`[multi-lane-manager] 调试模式检测: headerKey=${HEADER_LANE_DEBUG}, headerKeyLower=${debugHeaderKey}, value=${debugHeaderValue}, isDebugMode=${isDebugMode}`);\n    const debugInfo: string[] = [];\n\n    // 如果启用了调试模式，收集调试信息\n    if (isDebugMode) {\n      debugInfo.push(`请求时间: ${new Date().toISOString()}`);\n      debugInfo.push(`请求路径: ${event.node.req.method} ${event.node.req.url || \"\"}`);\n      debugInfo.push(`当前泳道: ${config.currentLaneId}`);\n      debugInfo.push(`服务名称: ${config.serviceName}`);\n    }\n\n    // 检查请求是否已经被处理过\n    if (event.context._laneManagerHandled) {\n      if (isDebugMode) debugInfo.push(`状态: 请求已被泳道管理器处理，跳过`);\n      logger.debug(`⏭️ 请求已被泳道管理器处理，跳过`);\n      return;\n    }\n\n    const requestPath = event.node.req.url || \"\";\n\n    // 特别记录 /_nuxt/ 路径的请求\n    if (event.path.startsWith('/_nuxt/')) {\n      console.log(`[multi-lane-manager] Intercepting _nuxt request2: ${event.path}`);\n      logger.info(`🔍 拦截到静态资源请求: ${event.path}`);\n    }\n\n    // 特别记录 /api/ 路径的请求\n    if (event.path.startsWith('/api/')) {\n      console.log(`[multi-lane-manager] Intercepting API request: ${event.path}`);\n      logger.info(`🔍 拦截到API请求: ${event.path}, 方法: ${event.node.req.method}, 头部: ${JSON.stringify(event.node.req.headers)}`);\n    }\n\n    // 强制使用 console.log 确保日志一定会输出\n    console.log(`[multi-lane-manager] 📥 中间件接收请求: ${event.node.req.method} ${requestPath}`);\n    logger.debug(`📥 中间件接收请求: ${event.node.req.method} ${requestPath}`);\n\n    if (!config.isLaneEnabled) {\n      if (isDebugMode) debugInfo.push(`状态: 泳道功能未启用，跳过代理逻辑`);\n      logger.debug(`🚫 泳道功能未启用，跳过代理逻辑`);\n\n      // 如果启用了调试模式，添加调试响应头\n      if (isDebugMode && !event.node.res.headersSent) {\n        try {\n          event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n        } catch (error) {\n          logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n        }\n      }\n      return;\n    }\n\n    // 标记请求正在被处理\n    event.context._laneManagerProcessing = true;\n\n    // 获取目标泳道ID\n    const headerKey = config.targetLaneHeaderKey || DEFAULT_LANE_TARGET_HEADER;\n\n    // 记录请求头信息，帮助调试\n    console.log(`[multi-lane-manager] 请求头信息:`, event.node.req.headers);\n\n    // HTTP 请求头是不区分大小写的，在 Node.js 中会被自动转换为小写\n    const headerKeyLower = headerKey.toLowerCase();\n\n    // 1. 首先尝试从header中获取泳道ID\n    const requestTargetLaneIdHeaderValue = event.node.req.headers[headerKeyLower];\n    let requestTargetLaneId = Array.isArray(requestTargetLaneIdHeaderValue)\n      ? requestTargetLaneIdHeaderValue[0]?.trim()\n      : requestTargetLaneIdHeaderValue?.trim();\n\n    // 记录泳道ID获取过程\n    console.log(`[multi-lane-manager] 尝试从请求头获取泳道ID: headerKey=${headerKey}, headerKeyLower=${headerKeyLower}, value=${requestTargetLaneIdHeaderValue}`);\n\n    if (isDebugMode) {\n      debugInfo.push(`目标泳道Header键: ${headerKey} (实际查找: ${headerKeyLower})`);\n    }\n\n    // 2. 如果header中没有泳道ID，且启用了cookie功能，则尝试从cookie中获取\n    if (!requestTargetLaneId && config.isLaneCookieEnabled) {\n      const cookieHeader = event.node.req.headers.cookie;\n      if (cookieHeader) {\n        // 记录 Cookie 信息，帮助调试\n        console.log(`[multi-lane-manager] Cookie信息: ${cookieHeader}`);\n\n        // 从cookie字符串中解析出目标泳道ID\n        // 使用与header完全相同的键名，不再移除'x-'前缀\n        const cookieKey = headerKey;\n        const cookieValue = parseCookieValue(cookieHeader, cookieKey);\n\n        // 记录 Cookie 解析过程\n        console.log(`[multi-lane-manager] 尝试从Cookie获取泳道ID: cookieKey=${cookieKey}, value=${cookieValue}`);\n\n        if (cookieValue) {\n          requestTargetLaneId = cookieValue.trim();\n          console.log(`[multi-lane-manager] 🍪 从Cookie中获取到泳道ID: ${requestTargetLaneId}, Cookie键名: ${cookieKey}`);\n          logger.debug(`🍪 从Cookie中获取到泳道ID: ${requestTargetLaneId}, Cookie键名: ${cookieKey}`);\n          if (isDebugMode) debugInfo.push(`泳道ID来源: Cookie, 值: ${requestTargetLaneId}`);\n        } else if (isDebugMode) {\n          debugInfo.push(`Cookie中未找到泳道ID, Cookie键: ${cookieKey}`);\n        }\n      } else if (isDebugMode) {\n        debugInfo.push(`请求中没有Cookie`);\n      }\n    } else if (requestTargetLaneId) {\n      console.log(`[multi-lane-manager] 🔤 从Header中获取到泳道ID: ${requestTargetLaneId}`);\n      logger.debug(`🔤 从Header中获取到泳道ID: ${requestTargetLaneId}`);\n      if (isDebugMode) debugInfo.push(`泳道ID来源: Header, 值: ${requestTargetLaneId}`);\n    } else if (isDebugMode) {\n      debugInfo.push(`未找到泳道ID`);\n    }\n\n    // 处理请求的泳道路由逻辑\n    if (requestTargetLaneId && requestTargetLaneId !== config.currentLaneId) {\n      // 1. 如果请求指定了目标泳道，且与当前泳道不同，则进行代理\n      // 确定泳道ID的来源\n      const sourceType = event.node.req.headers[headerKey] ? 'Header' : 'Cookie';\n\n      // 使用 console.log 确保日志一定会输出\n      console.log(`[multi-lane-manager] 🔀 检测到跨泳道请求: 当前泳道=${config.currentLaneId}, 目标泳道=${requestTargetLaneId} (来源: ${sourceType}), 路径: ${event.path}`);\n      logger.info(`🔀 检测到跨泳道请求: 当前泳道=${config.currentLaneId}, 目标泳道=${requestTargetLaneId} (来源: ${sourceType}), 路径: ${event.path}`);\n\n      if (isDebugMode) {\n        debugInfo.push(`处理: 跨泳道请求`);\n        debugInfo.push(`目标泳道: ${requestTargetLaneId}`);\n      }\n    } else if (!requestTargetLaneId) {\n      // 2. 如果请求没有指定泳道ID，尝试路由到 baseline 泳道\n      logger.debug(`🔍 请求未指定泳道ID，尝试查找 baseline 泳道实例`);\n\n      if (isDebugMode) {\n        debugInfo.push(`处理: 未指定泳道ID，尝试路由到 baseline 泳道`);\n      }\n\n      // 如果当前已经是 baseline 泳道，直接在本地处理\n      if (config.currentLaneId === 'baseline') {\n        logger.debug(`✅ 当前已是 baseline 泳道，在本地处理请求`);\n\n        if (isDebugMode) {\n          debugInfo.push(`状态: 当前已是 baseline 泳道，在本地处理`);\n\n          // 如果启用了调试模式，添加调试响应头\n          if (!event.node.res.headersSent) {\n            try {\n              event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n            } catch (error) {\n              logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n            }\n          }\n        }\n\n        // 清除处理中标记，但不标记为已处理，因为请求将由后续中间件处理\n        event.context._laneManagerProcessing = false;\n        return;\n      }\n\n      // 设置目标泳道ID为 baseline\n      requestTargetLaneId = 'baseline';\n\n      if (isDebugMode) {\n        debugInfo.push(`目标泳道: ${requestTargetLaneId} (默认)`);\n      }\n\n    }\n\n    // 如果有目标泳道ID（可能是请求中指定的，也可能是默认的 baseline），且与当前泳道不同，则尝试进行代理\n    if (requestTargetLaneId && requestTargetLaneId !== config.currentLaneId) {\n      try {\n        // 获取目标泳道的服务实例（按心跳时间排序）\n        const targetInstances = await getNacosLaneInstances(config.serviceName, requestTargetLaneId, true);\n\n        if (isDebugMode) {\n          debugInfo.push(`找到实例数量: ${targetInstances.length}`);\n        }\n\n        if (targetInstances.length > 0) {\n          // 使用负载均衡策略选择一个实例\n          const targetInstance = selectInstance(\n            targetInstances,\n            config.serviceName,\n            LoadBalanceStrategy.ROUND_ROBIN\n          );\n\n          if (isDebugMode) {\n            debugInfo.push(`选择实例: ${targetInstance.ip}:${targetInstance.port}`);\n            debugInfo.push(`负载均衡策略: ROUND_ROBIN`);\n\n            // 添加调试响应头\n            if (!event.node.res.headersSent) {\n              try {\n                event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n              } catch (error) {\n                logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n              }\n            }\n          }\n\n          // 转发请求到目标实例（使用故障转移）\n          await proxyRequestWithFailover(event, targetInstance, isDebugMode, targetInstances);\n          return;\n        } else {\n          // 如果是尝试路由到 baseline 但没找到实例，则在当前实例处理\n          if (requestTargetLaneId === 'baseline' && !event.node.req.headers[headerKey]) {\n            logger.info(`🔄 未找到 baseline 泳道实例，在当前泳道 ${config.currentLaneId} 处理请求`);\n\n            if (isDebugMode) {\n              debugInfo.push(`状态: 未找到 baseline 泳道实例，在当前泳道处理`);\n\n              // 如果启用了调试模式，添加调试响应头\n              if (!event.node.res.headersSent) {\n                try {\n                  event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n                } catch (error) {\n                  logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n                }\n              }\n            }\n\n            // 清除处理中标记，但不标记为已处理，因为请求将由后续中间件处理\n            event.context._laneManagerProcessing = false;\n            return;\n          }\n\n          // 对于明确指定了泳道ID的请求，如果找不到实例，尝试查找 baseline 泳道\n          logger.warn(`⚠️ 未找到泳道 ${requestTargetLaneId} 的健康实例，尝试查找 baseline 泳道`);\n\n          if (isDebugMode) {\n            debugInfo.push(`警告: 未找到泳道 ${requestTargetLaneId} 的健康实例，尝试查找 baseline 泳道`);\n          }\n\n          // 如果当前请求的泳道不是 baseline，则尝试查找 baseline 泳道\n          if (requestTargetLaneId !== 'baseline') {\n            console.log(`[multi-lane-manager] 尝试查找 baseline 泳道实例`);\n\n            // 获取 baseline 泳道的服务实例（按心跳时间排序）\n            const baselineInstances = await getNacosLaneInstances(config.serviceName, 'baseline', true);\n\n            if (baselineInstances.length > 0) {\n              console.log(`[multi-lane-manager] 找到 baseline 泳道实例，将请求转发到 baseline 泳道`);\n              logger.info(`✅ 找到 baseline 泳道实例，将请求转发到 baseline 泳道`);\n\n              if (isDebugMode) {\n                debugInfo.push(`状态: 找到 baseline 泳道实例，将请求转发到 baseline 泳道`);\n              }\n\n              // 使用负载均衡策略选择一个实例\n              const baselineInstance = selectInstance(\n                baselineInstances,\n                config.serviceName,\n                LoadBalanceStrategy.ROUND_ROBIN\n              );\n\n              if (isDebugMode) {\n                debugInfo.push(`选择实例: ${baselineInstance.ip}:${baselineInstance.port}`);\n                debugInfo.push(`负载均衡策略: ROUND_ROBIN`);\n\n                // 添加调试响应头\n                if (!event.node.res.headersSent) {\n                  try {\n                    event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n                  } catch (error) {\n                    logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n                  }\n                }\n              }\n\n              // 转发请求到 baseline 实例（使用故障转移）\n              await proxyRequestWithFailover(event, baselineInstance, isDebugMode, baselineInstances);\n              return;\n            } else {\n              console.log(`[multi-lane-manager] 未找到 baseline 泳道实例，在当前泳道处理请求`);\n              logger.info(`🔄 未找到 baseline 泳道实例，在当前泳道 ${config.currentLaneId} 处理请求`);\n\n              if (isDebugMode) {\n                debugInfo.push(`状态: 未找到 baseline 泳道实例，在当前泳道处理请求`);\n              }\n\n              // 清除处理中标记，但不标记为已处理，因为请求将由后续中间件处理\n              event.context._laneManagerProcessing = false;\n\n              // 如果启用了调试模式，添加调试响应头\n              if (isDebugMode && !event.node.res.headersSent) {\n                try {\n                  event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n                } catch (error) {\n                  logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n                }\n              }\n\n              return;\n            }\n          } else {\n            // 如果当前请求的泳道已经是 baseline，但仍然没有找到实例，则在当前泳道处理\n            console.log(`[multi-lane-manager] 已经是 baseline 泳道但未找到实例，在当前泳道处理请求`);\n            logger.info(`🔄 已经是 baseline 泳道但未找到实例，在当前泳道 ${config.currentLaneId} 处理请求`);\n\n            if (isDebugMode) {\n              debugInfo.push(`状态: 已经是 baseline 泳道但未找到实例，在当前泳道处理请求`);\n            }\n\n            // 清除处理中标记，但不标记为已处理，因为请求将由后续中间件处理\n            event.context._laneManagerProcessing = false;\n\n            // 如果启用了调试模式，添加调试响应头\n            if (isDebugMode && !event.node.res.headersSent) {\n              try {\n                event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n              } catch (error) {\n                logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n              }\n            }\n\n            return;\n          }\n        }\n      } catch (e) {\n        logger.error(`❌ 处理跨泳道请求时发生错误: ${e instanceof Error ? e.message : String(e)}`);\n\n        if (isDebugMode) {\n          debugInfo.push(`错误: ${e instanceof Error ? e.message : String(e)}`);\n        }\n\n        if (!event.node.res.headersSent) {\n          // 如果启用了调试模式，添加调试响应头\n          if (isDebugMode) {\n            try {\n              event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n            } catch (error) {\n              logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n            }\n          }\n\n          event.node.res.statusCode = 500; // Internal Server Error\n          event.node.res.setHeader(\"Content-Type\", \"text/plain\");\n          event.node.res.end(\"处理泳道请求时发生内部服务器错误。\");\n        }\n        // 标记请求已处理\n        event.context._laneManagerHandled = true;\n        return;\n      }\n    }\n\n    logger.debug(`✅ 请求在当前泳道 (${config.currentLaneId}) 处理或无目标泳道指定，将由后续处理程序处理。`);\n\n    if (isDebugMode) {\n      debugInfo.push(`处理: 在当前泳道处理请求`);\n\n      // 如果启用了调试模式，添加调试响应头\n      if (!event.node.res.headersSent) {\n        try {\n          event.node.res.setHeader(HEADER_LANE_DETAIL, getSafeHeaderValue(debugInfo));\n        } catch (error) {\n          logger.error(`❌ 设置调试响应头时出错: ${error instanceof Error ? error.message : String(error)}`);\n        }\n      }\n    }\n\n    // 清除处理中标记，但不标记为已处理，因为请求将由后续中间件处理\n    event.context._laneManagerProcessing = false;\n  };\n}\n\n// 导出 Nacos 相关函数，方便其他模块使用\nexport { getNacosLaneInstances };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,SAAS,iBAAiB,cAAsB,KAAiC;AAC/E,UAAQ,IAAI,yDAA+C,YAAY,SAAS,GAAG,EAAE;AAErF,MAAI,CAAC,gBAAgB,CAAC,KAAK;AACzB,YAAQ,IAAI,wFAAqD;AACjE,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,aAAa,MAAM,GAAG;AACtC,UAAQ,IAAI,wDAAoC,KAAK,UAAU,OAAO,CAAC,EAAE;AAGzE,aAAW,UAAU,SAAS;AAC5B,YAAQ,IAAI,wDAAoC,MAAM,EAAE;AAExD,UAAM,QAAQ,OAAO,MAAM,GAAG;AAC9B,QAAI,MAAM,SAAS,GAAG;AACpB,cAAQ,IAAI,8DAAqC,MAAM,EAAE;AACzD;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,CAAC,EAAE,KAAK;AAChC,UAAM,cAAc,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,KAAK;AAElD,YAAQ,IAAI,sDAAuC,SAAS,WAAW,WAAW,EAAE;AAGpF,QAAI,UAAU,YAAY,MAAM,IAAI,YAAY,GAAG;AACjD,cAAQ,IAAI,8DAAqC,SAAS,IAAI,WAAW,EAAE;AAC3E,aAAO;AAAA,IACT;AAAA,EACF;AAEA,UAAQ,IAAI,oEAAsC,GAAG,EAAE;AACvD,SAAO;AACT;AAQO,SAAS,gBAAwB;AAEtC,QAAM,OAAO,SAAS,QAAQ,IAAI,cAAc,QAAQ,IAAI,QAAQ,OAAO,YAAY,GAAG,EAAE;AAC5F,SAAO,MAAM,uFAAoB,IAAI,EAAE;AACvC,SAAO;AACT;AAQO,SAAS,sCAA+C;AAC7D,SAAO,KAAK,wGAAgC;AAG5C,SAAO,MAAM,mDAAc;AAC3B,QAAM,SAAS,UAAU;AAEzB,MAAI;AAEF,WAAO,MAAM,2EAAkB,OAAO,aAAa,EAAE;AACrD,QAAI,CAAC,OAAO,eAAe;AACzB,aAAO,MAAM,gGAAmB;AAChC,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,cAAc;AACjC,WAAO,KAAK,+DAAgB,UAAU,EAAE;AAGxC,UAAM,cAAc,eAAe;AAEnC,QAAI,CAAC,YAAY,oBAAoB;AACnC,aAAO,KAAK,wDAAc,UAAU,+CAAY;AAGhD,kBAAY,qBAAqB;AACjC,kBAAY,eAAe;AAG3B,uBAAiB,UAAU;AAG3B,8BAAwB,UAAU,EAC/B,KAAK,CAAC,YAAY;AACjB,YAAI,SAAS;AACX,iBAAO,KAAK,+GAAqB;AAGjC,gBAAM,mBAAmB,YAAY;AACnC,mBAAO,KAAK,+GAAwB,UAAU,KAAK;AACnD,kBAAM,0BAA0B,UAAU;AAAA,UAC5C;AAGA,kBAAQ,GAAG,cAAc,gBAAgB;AACzC,kBAAQ,GAAG,UAAU,YAAY;AAC/B,mBAAO,KAAK,6EAAyB;AACrC,kBAAM,iBAAiB;AACvB,oBAAQ,KAAK,CAAC;AAAA,UAChB,CAAC;AACD,kBAAQ,GAAG,WAAW,YAAY;AAChC,mBAAO,KAAK,8EAA0B;AACtC,kBAAM,iBAAiB;AACvB,oBAAQ,KAAK,CAAC;AAAA,UAChB,CAAC;AAAA,QACH,OAAO;AACL,iBAAO,KAAK,+GAAqB;AAAA,QACnC;AAAA,MACF,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,eAAO,MAAM,sDAAc,IAAI,OAAO,IAAI,IAAI,KAAK;AAAA,MACrD,CAAC;AAEH,aAAO,KAAK,4HAAuC;AACnD,aAAO;AAAA,IACT,OAAO;AACL,aAAO,KAAK,8DAAiB,YAAY,YAAY,6CAAU;AAAA,IACjE;AAEA,WAAO,KAAK,6HAAwC;AACpD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO;AAAA,MACL,8EAAkB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACxE,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AACF;AASO,SAAS,yBAAyB;AACvC,QAAM,SAAS,UAAU;AAGzB,UAAQ,IAAI,mHAA2C,OAAO,aAAa,gCAAY,OAAO,aAAa,wBAAS,OAAO,WAAW,oCAAgB,OAAO,uBAAuB,2BAA2B,YAAY,CAAC,wBAAc,OAAO,sBAAsB,iBAAO,cAAI,EAAE;AAEpR,SAAO;AAAA,IACL,8FAAsB,OAAO,aAAa,gCAAY,OAAO,aAAa,wBAAS,OAAO,WAAW,oCAAgB,OAAO,uBAAuB,2BAA2B,YAAY,CAAC,wBAAc,OAAO,sBAAsB,iBAAO,cAAI;AAAA,EACnP;AAEA,SAAO,OAAO,UAAmB;AAE/B,UAAM,iBAAiB,kBAAkB,YAAY;AACrD,UAAM,mBAAmB,MAAM,KAAK,IAAI,QAAQ,cAAc;AAC9D,UAAM,cAAc,CAAC,CAAC;AAGtB,YAAQ,IAAI,wEAA0C,iBAAiB,oBAAoB,cAAc,WAAW,gBAAgB,iBAAiB,WAAW,EAAE;AAClK,UAAM,YAAsB,CAAC;AAG7B,QAAI,aAAa;AACf,gBAAU,KAAK,8BAAS,oBAAI,KAAK,GAAE,YAAY,CAAC,EAAE;AAClD,gBAAU,KAAK,6BAAS,MAAM,KAAK,IAAI,MAAM,IAAI,MAAM,KAAK,IAAI,OAAO,EAAE,EAAE;AAC3E,gBAAU,KAAK,6BAAS,OAAO,aAAa,EAAE;AAC9C,gBAAU,KAAK,6BAAS,OAAO,WAAW,EAAE;AAAA,IAC9C;AAGA,QAAI,MAAM,QAAQ,qBAAqB;AACrC,UAAI,YAAa,WAAU,KAAK,oGAAoB;AACpD,aAAO,MAAM,mGAAmB;AAChC;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,KAAK,IAAI,OAAO;AAG1C,QAAI,MAAM,KAAK,WAAW,SAAS,GAAG;AACpC,cAAQ,IAAI,qDAAqD,MAAM,IAAI,EAAE;AAC7E,aAAO,KAAK,qEAAiB,MAAM,IAAI,EAAE;AAAA,IAC3C;AAGA,QAAI,MAAM,KAAK,WAAW,OAAO,GAAG;AAClC,cAAQ,IAAI,kDAAkD,MAAM,IAAI,EAAE;AAC1E,aAAO,KAAK,gDAAgB,MAAM,IAAI,mBAAS,MAAM,KAAK,IAAI,MAAM,mBAAS,KAAK,UAAU,MAAM,KAAK,IAAI,OAAO,CAAC,EAAE;AAAA,IACvH;AAGA,YAAQ,IAAI,8EAAoC,MAAM,KAAK,IAAI,MAAM,IAAI,WAAW,EAAE;AACtF,WAAO,MAAM,yDAAe,MAAM,KAAK,IAAI,MAAM,IAAI,WAAW,EAAE;AAElE,QAAI,CAAC,OAAO,eAAe;AACzB,UAAI,YAAa,WAAU,KAAK,oGAAoB;AACpD,aAAO,MAAM,gGAAmB;AAGhC,UAAI,eAAe,CAAC,MAAM,KAAK,IAAI,aAAa;AAC9C,YAAI;AACF,gBAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,QAC5E,SAAS,OAAO;AACd,iBAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,QACxF;AAAA,MACF;AACA;AAAA,IACF;AAGA,UAAM,QAAQ,yBAAyB;AAGvC,UAAM,YAAY,OAAO,uBAAuB;AAGhD,YAAQ,IAAI,wDAA+B,MAAM,KAAK,IAAI,OAAO;AAGjE,UAAM,iBAAiB,UAAU,YAAY;AAG7C,UAAM,iCAAiC,MAAM,KAAK,IAAI,QAAQ,cAAc;AAC5E,QAAI,sBAAsB,MAAM,QAAQ,8BAA8B,IAClE,+BAA+B,CAAC,GAAG,KAAK,IACxC,gCAAgC,KAAK;AAGzC,YAAQ,IAAI,kGAAgD,SAAS,oBAAoB,cAAc,WAAW,8BAA8B,EAAE;AAElJ,QAAI,aAAa;AACf,gBAAU,KAAK,yCAAgB,SAAS,+BAAW,cAAc,GAAG;AAAA,IACtE;AAGA,QAAI,CAAC,uBAAuB,OAAO,qBAAqB;AACtD,YAAM,eAAe,MAAM,KAAK,IAAI,QAAQ;AAC5C,UAAI,cAAc;AAEhB,gBAAQ,IAAI,4CAAkC,YAAY,EAAE;AAI5D,cAAM,YAAY;AAClB,cAAM,cAAc,iBAAiB,cAAc,SAAS;AAG5D,gBAAQ,IAAI,sFAAmD,SAAS,WAAW,WAAW,EAAE;AAEhG,YAAI,aAAa;AACf,gCAAsB,YAAY,KAAK;AACvC,kBAAQ,IAAI,sFAA4C,mBAAmB,yBAAe,SAAS,EAAE;AACrG,iBAAO,MAAM,iEAAuB,mBAAmB,yBAAe,SAAS,EAAE;AACjF,cAAI,YAAa,WAAU,KAAK,+CAAsB,mBAAmB,EAAE;AAAA,QAC7E,WAAW,aAAa;AACtB,oBAAU,KAAK,+DAA4B,SAAS,EAAE;AAAA,QACxD;AAAA,MACF,WAAW,aAAa;AACtB,kBAAU,KAAK,sCAAa;AAAA,MAC9B;AAAA,IACF,WAAW,qBAAqB;AAC9B,cAAQ,IAAI,sFAA4C,mBAAmB,EAAE;AAC7E,aAAO,MAAM,iEAAuB,mBAAmB,EAAE;AACzD,UAAI,YAAa,WAAU,KAAK,+CAAsB,mBAAmB,EAAE;AAAA,IAC7E,WAAW,aAAa;AACtB,gBAAU,KAAK,kCAAS;AAAA,IAC1B;AAGA,QAAI,uBAAuB,wBAAwB,OAAO,eAAe;AAGvE,YAAM,aAAa,MAAM,KAAK,IAAI,QAAQ,SAAS,IAAI,WAAW;AAGlE,cAAQ,IAAI,6GAA0C,OAAO,aAAa,8BAAU,mBAAmB,mBAAS,UAAU,oBAAU,MAAM,IAAI,EAAE;AAChJ,aAAO,KAAK,wFAAqB,OAAO,aAAa,8BAAU,mBAAmB,mBAAS,UAAU,oBAAU,MAAM,IAAI,EAAE;AAE3H,UAAI,aAAa;AACf,kBAAU,KAAK,8CAAW;AAC1B,kBAAU,KAAK,6BAAS,mBAAmB,EAAE;AAAA,MAC/C;AAAA,IACF,WAAW,CAAC,qBAAqB;AAE/B,aAAO,MAAM,wHAAiC;AAE9C,UAAI,aAAa;AACf,kBAAU,KAAK,0GAA+B;AAAA,MAChD;AAGA,UAAI,OAAO,kBAAkB,YAAY;AACvC,eAAO,MAAM,uGAA4B;AAEzC,YAAI,aAAa;AACf,oBAAU,KAAK,kGAA4B;AAG3C,cAAI,CAAC,MAAM,KAAK,IAAI,aAAa;AAC/B,gBAAI;AACF,oBAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,YAC5E,SAAS,OAAO;AACd,qBAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,YACxF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,QAAQ,yBAAyB;AACvC;AAAA,MACF;AAGA,4BAAsB;AAEtB,UAAI,aAAa;AACf,kBAAU,KAAK,6BAAS,mBAAmB,iBAAO;AAAA,MACpD;AAAA,IAEF;AAGA,QAAI,uBAAuB,wBAAwB,OAAO,eAAe;AACvE,UAAI;AAEF,cAAM,kBAAkB,MAAM,sBAAsB,OAAO,aAAa,qBAAqB,IAAI;AAEjG,YAAI,aAAa;AACf,oBAAU,KAAK,yCAAW,gBAAgB,MAAM,EAAE;AAAA,QACpD;AAEA,YAAI,gBAAgB,SAAS,GAAG;AAE9B,gBAAM,iBAAiB;AAAA,YACrB;AAAA,YACA,OAAO;AAAA;AAAA,UAET;AAEA,cAAI,aAAa;AACf,sBAAU,KAAK,6BAAS,eAAe,EAAE,IAAI,eAAe,IAAI,EAAE;AAClE,sBAAU,KAAK,mDAAqB;AAGpC,gBAAI,CAAC,MAAM,KAAK,IAAI,aAAa;AAC/B,kBAAI;AACF,sBAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,cAC5E,SAAS,OAAO;AACd,uBAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,cACxF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,yBAAyB,OAAO,gBAAgB,aAAa,eAAe;AAClF;AAAA,QACF,OAAO;AAEL,cAAI,wBAAwB,cAAc,CAAC,MAAM,KAAK,IAAI,QAAQ,SAAS,GAAG;AAC5E,mBAAO,KAAK,sGAA8B,OAAO,aAAa,2BAAO;AAErE,gBAAI,aAAa;AACf,wBAAU,KAAK,oHAA+B;AAG9C,kBAAI,CAAC,MAAM,KAAK,IAAI,aAAa;AAC/B,oBAAI;AACF,wBAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,gBAC5E,SAAS,OAAO;AACd,yBAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,gBACxF;AAAA,cACF;AAAA,YACF;AAGA,kBAAM,QAAQ,yBAAyB;AACvC;AAAA,UACF;AAGA,iBAAO,KAAK,+CAAY,mBAAmB,qFAAyB;AAEpE,cAAI,aAAa;AACf,sBAAU,KAAK,gDAAa,mBAAmB,qFAAyB;AAAA,UAC1E;AAGA,cAAI,wBAAwB,YAAY;AACtC,oBAAQ,IAAI,iFAAyC;AAGrD,kBAAM,oBAAoB,MAAM,sBAAsB,OAAO,aAAa,YAAY,IAAI;AAE1F,gBAAI,kBAAkB,SAAS,GAAG;AAChC,sBAAQ,IAAI,qIAA0D;AACtE,qBAAO,KAAK,uHAAuC;AAEnD,kBAAI,aAAa;AACf,0BAAU,KAAK,8HAAyC;AAAA,cAC1D;AAGA,oBAAM,mBAAmB;AAAA,gBACvB;AAAA,gBACA,OAAO;AAAA;AAAA,cAET;AAEA,kBAAI,aAAa;AACf,0BAAU,KAAK,6BAAS,iBAAiB,EAAE,IAAI,iBAAiB,IAAI,EAAE;AACtE,0BAAU,KAAK,mDAAqB;AAGpC,oBAAI,CAAC,MAAM,KAAK,IAAI,aAAa;AAC/B,sBAAI;AACF,0BAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,kBAC5E,SAAS,OAAO;AACd,2BAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,kBACxF;AAAA,gBACF;AAAA,cACF;AAGA,oBAAM,yBAAyB,OAAO,kBAAkB,aAAa,iBAAiB;AACtF;AAAA,YACF,OAAO;AACL,sBAAQ,IAAI,uIAAkD;AAC9D,qBAAO,KAAK,sGAA8B,OAAO,aAAa,2BAAO;AAErE,kBAAI,aAAa;AACf,0BAAU,KAAK,gIAAiC;AAAA,cAClD;AAGA,oBAAM,QAAQ,yBAAyB;AAGvC,kBAAI,eAAe,CAAC,MAAM,KAAK,IAAI,aAAa;AAC9C,oBAAI;AACF,wBAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,gBAC5E,SAAS,OAAO;AACd,yBAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,gBACxF;AAAA,cACF;AAEA;AAAA,YACF;AAAA,UACF,OAAO;AAEL,oBAAQ,IAAI,+JAAsD;AAClE,mBAAO,KAAK,8HAAkC,OAAO,aAAa,2BAAO;AAEzE,gBAAI,aAAa;AACf,wBAAU,KAAK,wJAAqC;AAAA,YACtD;AAGA,kBAAM,QAAQ,yBAAyB;AAGvC,gBAAI,eAAe,CAAC,MAAM,KAAK,IAAI,aAAa;AAC9C,kBAAI;AACF,sBAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,cAC5E,SAAS,OAAO;AACd,uBAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,cACxF;AAAA,YACF;AAEA;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,GAAG;AACV,eAAO,MAAM,oFAAmB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAE5E,YAAI,aAAa;AACf,oBAAU,KAAK,iBAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,QACpE;AAEA,YAAI,CAAC,MAAM,KAAK,IAAI,aAAa;AAE/B,cAAI,aAAa;AACf,gBAAI;AACF,oBAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,YAC5E,SAAS,OAAO;AACd,qBAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,YACxF;AAAA,UACF;AAEA,gBAAM,KAAK,IAAI,aAAa;AAC5B,gBAAM,KAAK,IAAI,UAAU,gBAAgB,YAAY;AACrD,gBAAM,KAAK,IAAI,IAAI,wGAAmB;AAAA,QACxC;AAEA,cAAM,QAAQ,sBAAsB;AACpC;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM,sDAAc,OAAO,aAAa,wIAA0B;AAEzE,QAAI,aAAa;AACf,gBAAU,KAAK,sEAAe;AAG9B,UAAI,CAAC,MAAM,KAAK,IAAI,aAAa;AAC/B,YAAI;AACF,gBAAM,KAAK,IAAI,UAAU,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,QAC5E,SAAS,OAAO;AACd,iBAAO,MAAM,wEAAiB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,QACxF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,QAAQ,yBAAyB;AAAA,EACzC;AACF;","names":[]}