@hangox/mg-cli 1.4.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1081 -118
- package/dist/cli.js.map +1 -1
- package/dist/daemon-runner.js +12 -1
- package/dist/daemon-runner.js.map +1 -1
- package/dist/{index-AVsoGQ0e.d.ts → index-DuCpsEXk.d.ts} +341 -1
- package/dist/index.d.ts +7 -4
- package/dist/index.js +32 -7
- package/dist/index.js.map +1 -1
- package/dist/native-host.js +5329 -136
- package/dist/native-host.js.map +1 -1
- package/dist/postinstall.js +89 -8
- package/dist/postinstall.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +12 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/native-host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/native-host/index.ts","../src/server/daemon.ts","../src/shared/utils.ts","../src/shared/constants.ts","../src/shared/errors.ts","../src/server/websocket-server.ts","../src/server/logger.ts","../src/shared/version.ts","../src/server/analytics.ts","../src/native-host/protocol.ts"],"sourcesContent":["/**\n * Native Messaging Host 入口\n * Chrome 通过 stdin/stdout 与此进程通信\n * 协议: 32位小端长度前缀 + UTF-8 JSON\n */\n\nimport { stdin, stdout } from 'node:process'\nimport { isServerRunning, startServerDaemon, getServerStatus } from '../server/daemon.js'\nimport { encodeMessage, decodeMessage } from './protocol.js'\n\n// ==================== 消息类型 ====================\n\ninterface NativeRequest {\n type: 'ensure_server' | 'get_status' | 'stop_server' | 'ping'\n port?: number\n}\n\ninterface NativeResponse {\n type: string\n success: boolean\n data?: {\n running: boolean\n port?: number\n pid?: number\n startedAt?: string\n uptime?: string\n version?: string\n }\n error?: string\n}\n\n// ==================== 消息处理 ====================\n\nfunction sendMessage(message: NativeResponse): void {\n const encoded = encodeMessage(message)\n stdout.write(encoded)\n}\n\nasync function handleMessage(request: NativeRequest): Promise<void> {\n try {\n switch (request.type) {\n case 'ensure_server': {\n // 确保 Server 运行(幂等操作)\n const { running, info } = isServerRunning()\n if (running && info) {\n sendMessage({\n type: 'server_status',\n success: true,\n data: {\n running: true,\n port: info.port,\n pid: info.pid,\n startedAt: info.startedAt,\n version: info.version,\n },\n })\n } else {\n try {\n const newInfo = await startServerDaemon(request.port)\n sendMessage({\n type: 'server_started',\n success: true,\n data: {\n running: true,\n port: newInfo.port,\n pid: newInfo.pid,\n startedAt: newInfo.startedAt,\n version: newInfo.version,\n },\n })\n } catch (error) {\n sendMessage({\n type: 'error',\n success: false,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n break\n }\n\n case 'get_status': {\n const status = getServerStatus()\n sendMessage({\n type: 'status',\n success: true,\n data: status,\n })\n break\n }\n\n case 'ping': {\n sendMessage({ type: 'pong', success: true })\n break\n }\n\n default:\n sendMessage({\n type: 'error',\n success: false,\n error: `Unknown message type: ${(request as { type: string }).type}`,\n })\n }\n } catch (error) {\n sendMessage({\n type: 'error',\n success: false,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n// ==================== 主循环 ====================\n\nfunction main(): void {\n let buffer: Buffer = Buffer.alloc(0)\n\n stdin.on('readable', () => {\n let chunk: Buffer | null\n while ((chunk = stdin.read() as Buffer | null) !== null) {\n buffer = Buffer.concat([buffer, chunk])\n\n // 尝试解析完整消息\n let result: ReturnType<typeof decodeMessage>\n while ((result = decodeMessage(buffer)) !== null) {\n buffer = result.remaining\n handleMessage(result.message as NativeRequest)\n }\n }\n })\n\n stdin.on('end', () => {\n process.exit(0)\n })\n\n stdin.on('error', () => {\n process.exit(1)\n })\n}\n\nmain()\n","/**\n * 守护进程管理\n */\n\nimport { spawn, ChildProcess } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, join } from 'node:path'\nimport {\n readServerInfo,\n writeServerInfo,\n deleteServerInfo,\n isProcessRunning,\n killProcess,\n ensureConfigDir,\n getCurrentISOTime,\n formatDuration,\n} from '../shared/utils.js'\nimport { SERVER_START_TIMEOUT, DEFAULT_PORT } from '../shared/constants.js'\nimport { ErrorCode, MGError } from '../shared/errors.js'\nimport type { ServerInfo } from '../shared/types.js'\nimport { createServer } from './websocket-server.js'\nimport { createLogger, LogLevel } from './logger.js'\nimport { getVersion } from '../shared/version.js'\n\n/**\n * 检查 Server 是否在运行\n */\nexport function isServerRunning(): { running: boolean; info: ServerInfo | null } {\n const info = readServerInfo()\n\n if (!info) {\n return { running: false, info: null }\n }\n\n // 检查进程是否存在\n if (!isProcessRunning(info.pid)) {\n // 进程不存在,清理旧文件\n deleteServerInfo()\n return { running: false, info: null }\n }\n\n return { running: true, info }\n}\n\n/**\n * 启动 Server(前台模式)\n */\nexport async function startServerForeground(port?: number): Promise<void> {\n const { running, info } = isServerRunning()\n\n if (running && info) {\n throw new MGError(\n ErrorCode.SERVER_ALREADY_RUNNING,\n `Server 已在运行中 (PID: ${info.pid}, 端口: ${info.port})`\n )\n }\n\n ensureConfigDir()\n\n const logger = createLogger({\n console: true,\n file: true,\n minLevel: LogLevel.INFO,\n })\n\n const server = createServer({\n port: port || DEFAULT_PORT,\n logger,\n })\n\n // 注册信号处理\n const cleanup = async () => {\n console.log('\\n正在停止 Server...')\n await server.stop()\n deleteServerInfo()\n process.exit(0)\n }\n\n process.on('SIGINT', cleanup)\n process.on('SIGTERM', cleanup)\n\n try {\n const actualPort = await server.start()\n\n // 写入 Server 信息(包含版本号)\n writeServerInfo({\n port: actualPort,\n pid: process.pid,\n startedAt: getCurrentISOTime(),\n version: getVersion(),\n })\n\n console.log(`\\nMG Server 启动成功`)\n console.log(`监听端口: ${actualPort}`)\n console.log(`进程 PID: ${process.pid}`)\n console.log(`运行模式: 前台`)\n console.log(`\\n按 Ctrl+C 停止...`)\n } catch (error) {\n logger.error('Server 启动失败:', error)\n throw error\n }\n}\n\n/**\n * 启动 Server(守护进程模式)\n */\nexport async function startServerDaemon(port?: number): Promise<ServerInfo> {\n const { running, info } = isServerRunning()\n\n if (running && info) {\n throw new MGError(\n ErrorCode.SERVER_ALREADY_RUNNING,\n `Server 已在运行中 (PID: ${info.pid}, 端口: ${info.port})`\n )\n }\n\n ensureConfigDir()\n\n // 获取当前模块的路径\n const currentFile = fileURLToPath(import.meta.url)\n const currentDir = dirname(currentFile)\n const serverScript = join(currentDir, 'daemon-runner.js')\n\n // 启动子进程\n const args = ['--foreground']\n if (port) {\n args.push('--port', String(port))\n }\n\n const child: ChildProcess = spawn(process.execPath, [serverScript, ...args], {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n MG_DAEMON: '1',\n },\n })\n\n child.unref()\n\n // 等待 Server 启动\n const startTime = Date.now()\n while (Date.now() - startTime < SERVER_START_TIMEOUT) {\n await new Promise((resolve) => setTimeout(resolve, 200))\n\n const { running, info } = isServerRunning()\n if (running && info) {\n return info\n }\n }\n\n throw new MGError(ErrorCode.SERVER_START_FAILED, 'Server 启动超时')\n}\n\n/**\n * 停止 Server\n */\nexport function stopServer(): { stopped: boolean; info: ServerInfo | null } {\n const { running, info } = isServerRunning()\n\n if (!running || !info) {\n return { stopped: false, info: null }\n }\n\n // 终止进程\n const killed = killProcess(info.pid)\n\n if (killed) {\n deleteServerInfo()\n }\n\n return { stopped: killed, info }\n}\n\n/**\n * 重启 Server\n */\nexport async function restartServer(port?: number): Promise<ServerInfo> {\n const { info: oldInfo } = stopServer()\n\n // 等待旧进程完全停止\n await new Promise((resolve) => setTimeout(resolve, 500))\n\n // 启动新 Server\n return startServerDaemon(port || oldInfo?.port)\n}\n\n/**\n * 获取 Server 状态\n */\nexport function getServerStatus(): {\n running: boolean\n port?: number\n pid?: number\n startedAt?: string\n uptime?: string\n version?: string\n} {\n const { running, info } = isServerRunning()\n\n if (!running || !info) {\n return { running: false }\n }\n\n const uptimeMs = Date.now() - new Date(info.startedAt).getTime()\n\n return {\n running: true,\n port: info.port,\n pid: info.pid,\n startedAt: info.startedAt,\n uptime: formatDuration(uptimeMs),\n version: info.version,\n }\n}\n","/**\n * MG Plugin 工具函数\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs'\nimport { dirname, resolve, isAbsolute } from 'node:path'\nimport { CONFIG_DIR, SERVER_INFO_FILE, LOG_DIR } from './constants.js'\nimport type { ServerInfo, SpaceNodeInfo, NodeInfo } from './types.js'\n\n// ==================== 文件操作 ====================\n\n/**\n * 确保目录存在\n */\nexport function ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\n/**\n * 确保配置目录存在\n */\nexport function ensureConfigDir(): void {\n ensureDir(CONFIG_DIR)\n ensureDir(LOG_DIR)\n}\n\n/**\n * 读取 Server 信息文件\n */\nexport function readServerInfo(): ServerInfo | null {\n try {\n if (!existsSync(SERVER_INFO_FILE)) {\n return null\n }\n const content = readFileSync(SERVER_INFO_FILE, 'utf-8')\n return JSON.parse(content) as ServerInfo\n } catch {\n return null\n }\n}\n\n/**\n * 写入 Server 信息文件\n */\nexport function writeServerInfo(info: ServerInfo): void {\n ensureConfigDir()\n writeFileSync(SERVER_INFO_FILE, JSON.stringify(info, null, 2), 'utf-8')\n}\n\n/**\n * 删除 Server 信息文件\n */\nexport function deleteServerInfo(): void {\n try {\n if (existsSync(SERVER_INFO_FILE)) {\n unlinkSync(SERVER_INFO_FILE)\n }\n } catch {\n // 忽略删除错误\n }\n}\n\n/**\n * 解析输出路径(支持相对路径和绝对路径)\n */\nexport function resolveOutputPath(outputPath: string): string {\n if (isAbsolute(outputPath)) {\n return outputPath\n }\n return resolve(process.cwd(), outputPath)\n}\n\n/**\n * 确保输出路径的目录存在\n */\nexport function ensureOutputDir(outputPath: string): void {\n const dir = dirname(outputPath)\n ensureDir(dir)\n}\n\n// ==================== 进程管理 ====================\n\n/**\n * 检查进程是否存在\n */\nexport function isProcessRunning(pid: number): boolean {\n try {\n // 发送信号 0 不会终止进程,但如果进程不存在会抛出错误\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 终止进程\n */\nexport function killProcess(pid: number): boolean {\n try {\n process.kill(pid, 'SIGTERM')\n return true\n } catch {\n return false\n }\n}\n\n// ==================== URL 处理 ====================\n\n/**\n * 标准化页面 URL\n *\n * 输入: https://mastergo.netease.com/file/174135798361888?fileOpenFrom=home&page_id=0%3A8347\n * 输出: mastergo.netease.com/file/174135798361888\n */\nexport function normalizePageUrl(url: string): string {\n try {\n // 已标准化的 URL(无协议)直接去掉查询参数\n if (!url.includes('://') && !url.startsWith('//')) {\n return url.split('?')[0].split('#')[0]\n }\n\n const urlObj = new URL(url)\n // 返回 host + pathname,去掉 https:// 前缀和查询参数\n return urlObj.host + urlObj.pathname\n } catch {\n // 如果已经是标准化的格式,直接返回\n return url\n }\n}\n\n/**\n * 标准化页面 URL(保留 page_id)\n * 用于导航时精确匹配页面,不同 page_id 视为不同页面\n * MasterGo 不支持在同一个 Tab 中切换 Page,所以需要精确匹配\n *\n * @example\n * normalizePageUrlWithPageId('https://mastergo.netease.com/file/123?page_id=456%3A789&other=foo')\n * // => 'mastergo.netease.com/file/123?page_id=456:789'\n *\n * normalizePageUrlWithPageId('https://mastergo.netease.com/file/123')\n * // => 'mastergo.netease.com/file/123'\n */\nexport function normalizePageUrlWithPageId(url: string): string {\n try {\n let urlObj: URL\n\n // 如果已经是标准化格式(没有协议),添加临时协议以便解析\n if (!url.includes('://') && !url.startsWith('//')) {\n urlObj = new URL(`https://${url}`)\n } else {\n urlObj = new URL(url)\n }\n\n const basePath = `${urlObj.host}${urlObj.pathname}`\n\n // 提取 page_id 参数\n const pageId = urlObj.searchParams.get('page_id')\n if (pageId) {\n // page_id 可能是 URL 编码的,解码后返回\n const decodedPageId = decodeURIComponent(pageId)\n return `${basePath}?page_id=${decodedPageId}`\n }\n\n return basePath\n } catch {\n // 解析失败,尝试简单处理\n const withoutProtocol = url\n .replace(/^https?:\\/\\//, '')\n .replace(/^\\/\\//, '')\n\n // 尝试提取 page_id\n const pageIdMatch = withoutProtocol.match(/[?&]page_id=([^&#]+)/)\n const basePath = withoutProtocol.split('?')[0].split('#')[0]\n\n if (pageIdMatch) {\n const decodedPageId = decodeURIComponent(pageIdMatch[1])\n return `${basePath}?page_id=${decodedPageId}`\n }\n\n return basePath\n }\n}\n\n/**\n * 检查是否是设计页面 URL\n * 支持 /file/ 和 /prototyping/ 两种路径\n */\nexport function isDesignPageUrl(url: string): boolean {\n // 匹配 /file/数字 或 /prototyping/数字 格式\n return /\\/(file|prototyping)\\/\\d+/.test(url)\n}\n\n// ==================== 页面 URL 构建 ====================\n\n/** 页面类型 */\nexport type PageType = 'file' | 'prototyping'\n\n/**\n * 构建页面 URL\n * 统一 pageUrl 构建逻辑,避免多处重复代码\n *\n * @param domain MasterGo 域名(如 mastergo.netease.com)\n * @param fileId 文件 ID\n * @param pageType 页面类型:file(默认)或 prototyping\n * @returns 标准化的页面 URL(如 mastergo.netease.com/file/123456)\n */\nexport function buildPageUrl(\n domain: string,\n fileId: string | number,\n pageType: PageType = 'file'\n): string {\n // 规范化 domain,去掉末尾 /\n const normalizedDomain = domain.replace(/\\/$/, '')\n return `${normalizedDomain}/${pageType}/${fileId}`\n}\n\n/**\n * 解析 mgp:// 链接\n *\n * 支持的格式 (queryParams 格式,nodeId/pageId 需要 URL 编码):\n * - mgp://mastergo.netease.com/file/174135798361888?nodeId=123%3A456 (单个节点)\n * - mgp://mastergo.netease.com/file/174135798361888?page_id=321:11979&nodeId=123%3A456 (带 page_id)\n * - mgp://mastergo.netease.com/file/174135798361888?nodeId=0%3A8633&nodePath=314%3A13190%2F0%3A8633 (带父节点路径)\n * - mgp://mastergo.netease.com/file/174135798361888?nodeId=100%3A200&childNodeIds=100%3A201,100%3A202 (多选链接)\n * - mgp://mastergo.netease.com/file/174135798361888?pageId=0%3A1 (页面链接)\n *\n * 输出: { pageUrl: 'mastergo.netease.com/file/174135798361888?page_id=321:11979', nodeId: '123:456' }\n * 或 { pageUrl: 'mastergo.netease.com/file/174135798361888', pageId: '0:1' }\n * 或 { pageUrl: 'mastergo.netease.com/file/174135798361888', nodeId: '100:200', childNodeIds: ['100:201', '100:202'] }\n */\nexport function parseMgpLink(link: string): { pageUrl: string; nodeId?: string; pageId?: string; nodePath?: string[]; childNodeIds?: string[] } | null {\n // 检查是否是 mgp:// 协议\n if (!link.startsWith('mgp://')) {\n return null\n }\n\n try {\n // 移除 mgp:// 前缀,构造为可解析的 URL\n const urlPart = link.slice(6) // 移除 'mgp://'\n const questionMarkIndex = urlPart.indexOf('?')\n\n if (questionMarkIndex === -1) {\n // 没有查询参数,无效格式\n return null\n }\n\n const basePath = urlPart.slice(0, questionMarkIndex)\n const queryString = urlPart.slice(questionMarkIndex + 1)\n\n // 解析查询参数\n const params = new URLSearchParams(queryString)\n const encodedNodeId = params.get('nodeId')\n const encodedPageId = params.get('pageId')\n const mgPageId = params.get('page_id') // MasterGo 页面 ID(用于区分同一文件的不同 page)\n\n // nodeId 和 pageId 必须有一个\n if (!encodedNodeId && !encodedPageId) {\n return null\n }\n\n // 不能同时有 nodeId 和 pageId\n if (encodedNodeId && encodedPageId) {\n return null\n }\n\n // 构建 pageUrl(包含 page_id 如果存在)\n let pageUrl = basePath\n if (mgPageId) {\n pageUrl = `${basePath}?page_id=${mgPageId}`\n }\n\n // 解析 nodeId\n if (encodedNodeId) {\n const nodeId = decodeURIComponent(encodedNodeId)\n\n // 验证 nodeId 格式:支持单个节点 (数字:数字) 或带路径的格式 (数字:数字/数字:数字/...)\n if (!/^(\\d+:\\d+)(\\/\\d+:\\d+)*$/.test(nodeId)) {\n return null\n }\n\n // 解析可选的 nodePath\n const encodedNodePath = params.get('nodePath')\n let nodePath: string[] | undefined\n\n if (encodedNodePath) {\n const decodedNodePath = decodeURIComponent(encodedNodePath)\n nodePath = decodedNodePath.split('/').filter(Boolean)\n // 验证每个路径段的格式\n if (!nodePath.every(segment => /^\\d+:\\d+$/.test(segment))) {\n return null\n }\n }\n\n // 解析可选的 childNodeIds(多选模式,逗号分隔)\n const childNodeIdsRaw = params.get('childNodeIds')\n let childNodeIds: string[] | undefined\n\n if (childNodeIdsRaw) {\n childNodeIds = childNodeIdsRaw.split(',').map(id => decodeURIComponent(id))\n // 验证每个 childNodeId 的格式(支持简单格式和带路径的格式,与 nodeId 一致)\n if (!childNodeIds.every(id => /^(\\d+:\\d+)(\\/\\d+:\\d+)*$/.test(id))) {\n return null\n }\n }\n\n return {\n pageUrl,\n nodeId,\n nodePath,\n childNodeIds,\n }\n }\n\n // 解析 pageId(不做格式校验,MasterGo 支持多种 pageId 格式如 \"0:1\" 或 \"M\")\n if (encodedPageId) {\n const pageId = decodeURIComponent(encodedPageId)\n return {\n pageUrl,\n pageId,\n }\n }\n\n return null\n } catch {\n return null\n }\n}\n\n/**\n * 生成 mgp:// 链接\n *\n * @param pageUrl 页面 URL(会被标准化,保留 page_id)\n * @param nodeId 节点 ID(会被 URL 编码)\n * @param nodePath 可选的父节点路径(会被 URL 编码)\n */\nexport function generateMgpLink(pageUrl: string, nodeId: string, nodePath?: string[]): string {\n // 使用保留 page_id 的标准化函数,确保不同 page 生成不同的链接\n const normalizedUrl = normalizePageUrlWithPageId(pageUrl)\n const encodedNodeId = encodeURIComponent(nodeId)\n\n // 注意:normalizedUrl 可能包含 ?page_id=xxx,所以使用 & 连接后续参数\n const separator = normalizedUrl.includes('?') ? '&' : '?'\n let link = `mgp://${normalizedUrl}${separator}nodeId=${encodedNodeId}`\n\n if (nodePath && nodePath.length > 0) {\n const encodedNodePath = encodeURIComponent(nodePath.join('/'))\n link += `&nodePath=${encodedNodePath}`\n }\n\n return link\n}\n\n/**\n * 生成 mgp:// 页面链接\n *\n * @param pageUrl 页面 URL(会被标准化,保留 page_id)\n * @param pageId 页面 ID(会被 URL 编码)\n */\nexport function generatePageLink(pageUrl: string, pageId: string): string {\n // 使用不保留 page_id 的标准化函数,避免 page_id 和 pageId 重复\n const normalizedUrl = normalizePageUrl(pageUrl)\n const encodedPageId = encodeURIComponent(pageId)\n\n // normalizedUrl 不包含查询参数,使用 ? 连接\n return `mgp://${normalizedUrl}?pageId=${encodedPageId}`\n}\n\n/**\n * 生成多节点 mgp:// 链接\n * 用于多选场景:以公共父元素为主节点,用 childNodeIds 参数指定选中的子节点\n *\n * 格式: mgp://[页面URL]?nodeId=[公共父元素ID]&childNodeIds=[子节点1],[子节点2]...\n *\n * @param pageUrl 页面 URL(会被标准化,保留 page_id)\n * @param parentNodeId 公共父元素 ID(作为 nodeId)\n * @param childNodeIds 选中的子节点 ID 数组(逗号分隔)\n * @returns mgp:// 格式的链接\n *\n * @example\n * generateMultiNodeMgpLink('https://mastergo.netease.com/file/123', '100:200', ['100:201', '100:202'])\n * // => 'mgp://mastergo.netease.com/file/123?nodeId=100%3A200&childNodeIds=100%3A201,100%3A202'\n */\nexport function generateMultiNodeMgpLink(\n pageUrl: string,\n parentNodeId: string,\n childNodeIds: string[]\n): string {\n // 使用保留 page_id 的标准化函数\n const normalizedUrl = normalizePageUrlWithPageId(pageUrl)\n const encodedParentNodeId = encodeURIComponent(parentNodeId)\n\n // 构建基础 URL\n const separator = normalizedUrl.includes('?') ? '&' : '?'\n let link = `mgp://${normalizedUrl}${separator}nodeId=${encodedParentNodeId}`\n\n // 添加 childNodeIds 参数(逗号分隔)\n const encodedChildIds = childNodeIds.map(id => encodeURIComponent(id)).join(',')\n link += `&childNodeIds=${encodedChildIds}`\n\n return link\n}\n\n// ==================== 输出格式化 ====================\n\n/**\n * 格式化文件大小\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} 字节`\n }\n const kb = bytes / 1024\n if (kb < 1024) {\n return `${kb.toFixed(2)} KB`\n }\n const mb = kb / 1024\n return `${mb.toFixed(2)} MB`\n}\n\n/**\n * 格式化时间间隔\n */\nexport function formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n const minutes = Math.floor(seconds / 60)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n\n if (days > 0) {\n return `${days} 天 ${hours % 24} 小时`\n }\n if (hours > 0) {\n return `${hours} 小时 ${minutes % 60} 分钟`\n }\n if (minutes > 0) {\n return `${minutes} 分钟 ${seconds % 60} 秒`\n }\n return `${seconds} 秒`\n}\n\n/**\n * 生成唯一 ID\n */\nexport function generateId(): string {\n return `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`\n}\n\n/**\n * 获取当前时间的 ISO 格式字符串\n */\nexport function getCurrentISOTime(): string {\n return new Date().toISOString()\n}\n\n/**\n * 格式化日期时间用于日志\n */\nexport function formatLogTime(date: Date = new Date()): string {\n const year = date.getFullYear()\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n const seconds = String(date.getSeconds()).padStart(2, '0')\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`\n}\n\n// ==================== FileId 提取 ====================\n\n/**\n * 从完整 URL 提取 fileId\n * \n * 支持格式:\n * - https://mastergo.netease.com/file/174875497054651?page_id=321%3A11979\n * - mastergo.netease.com/file/174875497054651\n * \n * @returns fileId 或 null\n */\nexport function extractFileIdFromUrl(url: string): string | null {\n // 匹配 /file/数字 格式\n const match = url.match(/\\/file\\/(\\d+)/)\n return match ? match[1] : null\n}\n\n/**\n * 从 mgp:// 链接提取 fileId\n * \n * 支持格式:\n * - mgp://mastergo.netease.com/file/174875497054651?nodeId=xxx\n * \n * @returns fileId 或 null\n */\nexport function extractFileIdFromMgpLink(link: string): string | null {\n if (!link.startsWith('mgp://')) {\n return null\n }\n return extractFileIdFromUrl(link)\n}\n\n/**\n * 统一处理输入,提取 fileId\n * \n * 支持三种输入格式:\n * 1. 完整 URL: https://mastergo.netease.com/file/174875497054651?page_id=xxx\n * 2. mgp 协议: mgp://mastergo.netease.com/file/174875497054651?nodeId=xxx\n * 3. 纯 fileId: 174875497054651\n * \n * @returns fileId 或 null\n */\nexport function extractFileId(input: string): string | null {\n const trimmed = input.trim()\n \n // 1. 纯数字 fileId\n if (/^\\d+$/.test(trimmed)) {\n return trimmed\n }\n \n // 2. mgp:// 协议\n if (trimmed.startsWith('mgp://')) {\n return extractFileIdFromMgpLink(trimmed)\n }\n \n // 3. 完整 URL (http:// 或 https://)\n if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) {\n return extractFileIdFromUrl(trimmed)\n }\n \n // 4. 尝试作为不带协议的 URL 解析\n return extractFileIdFromUrl(trimmed)\n}\n\n// ==================== 节点数据精简 ====================\n\n/**\n * 需要四舍五入的数值字段\n */\nconst NUMERIC_FIELDS = [\n 'x', 'y', 'width', 'height',\n 'rotation',\n 'opacity',\n 'cornerRadius', 'topLeftRadius', 'topRightRadius', 'bottomLeftRadius', 'bottomRightRadius',\n 'strokeWeight', 'strokeTopWeight', 'strokeLeftWeight', 'strokeBottomWeight', 'strokeRightWeight',\n 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',\n 'itemSpacing', 'crossAxisSpacing',\n 'flexGrow',\n]\n\n/**\n * 四舍五入到一位小数\n * 25.666667938232422 -> 25.7\n */\nexport function roundToOneDecimal(value: number): number {\n return Math.round(value * 10) / 10\n}\n\n/**\n * MasterGo 节点属性默认值\n * 基于官方文档定义,当值等于默认值时可以省略以减少 JSON 体积\n */\nexport const NODE_DEFAULTS: Record<string, unknown> = {\n // Scene Node 属性\n visible: true,\n isVisible: true,\n isLocked: false,\n\n // Blend 属性\n opacity: 1,\n blendMode: 'NORMAL',\n isMask: false,\n isMaskOutline: false,\n isMaskVisible: false,\n effectStyleId: '',\n\n // Geometry 属性\n strokeStyle: 'SOLID',\n strokeWeight: 0,\n strokeTopWeight: 0,\n strokeLeftWeight: 0,\n strokeBottomWeight: 0,\n strokeRightWeight: 0,\n strokeAlign: 'CENTER',\n strokeCap: 'NONE',\n strokeJoin: 'MITER',\n dashCap: 'NONE',\n fillStyleId: '',\n strokeStyleId: '',\n strokeFillStyleId: '',\n strokeWidthStyleId: '',\n\n // Corner 属性\n cornerSmooth: 0,\n cornerRadius: 0,\n topLeftRadius: 0,\n topRightRadius: 0,\n bottomLeftRadius: 0,\n bottomRightRadius: 0,\n cornerRadiusStyleId: '',\n\n // Layout 属性\n rotation: 0,\n flexGrow: 0,\n alignSelf: 'INHERIT',\n layoutPositioning: 'AUTO',\n constrainProportions: false,\n\n // 容器专属属性 (FrameNode)\n flexMode: 'NONE',\n flexWrap: 'NO_WRAP',\n itemSpacing: 0,\n crossAxisSpacing: 0,\n paddingTop: 0,\n paddingRight: 0,\n paddingBottom: 0,\n paddingLeft: 0,\n paddingStyleId: '',\n spacingStyleId: '',\n clipsContent: false,\n itemReverseZIndex: false,\n strokesIncludedInLayout: false,\n overflowDirection: 'NONE',\n gridStyleId: '',\n\n // 其他属性\n componentPropertyReferences: null,\n}\n\n/**\n * 需要检查是否为空数组的字段\n */\nconst EMPTY_ARRAY_FIELDS = [\n 'fills',\n 'strokes',\n 'effects',\n 'strokeDashes',\n 'exportSettings',\n 'reactions',\n 'attachedConnectors',\n 'layoutGrids',\n]\n\n/**\n * 检查值是否为空数组\n */\nfunction isEmptyArray(value: unknown): boolean {\n return Array.isArray(value) && value.length === 0\n}\n\n/**\n * 检查两个值是否相等(简单比较)\n */\nfunction isEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (a === null || b === null) return a === b\n if (typeof a !== typeof b) return false\n return false\n}\n\n/**\n * 精简节点数据,移除等于默认值的字段\n * 递归处理 children 数组\n *\n * @param node 原始节点数据\n * @returns 精简后的节点数据\n */\nexport function trimNodeDefaults<T extends Record<string, unknown>>(node: T): T {\n const result: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(node)) {\n // 递归处理 children 数组\n if (key === 'children' && Array.isArray(value)) {\n const trimmedChildren = value.map((child) =>\n typeof child === 'object' && child !== null\n ? trimNodeDefaults(child as Record<string, unknown>)\n : child\n )\n // 只有非空时才保留\n if (trimmedChildren.length > 0) {\n result[key] = trimmedChildren\n }\n continue\n }\n\n // 检查是否是需要检查空数组的字段\n if (EMPTY_ARRAY_FIELDS.includes(key) && isEmptyArray(value)) {\n continue // 跳过空数组\n }\n\n // 对数值字段进行四舍五入\n if (NUMERIC_FIELDS.includes(key) && typeof value === 'number') {\n const roundedValue = roundToOneDecimal(value)\n // 检查四舍五入后是否等于默认值\n if (key in NODE_DEFAULTS && isEqual(roundedValue, NODE_DEFAULTS[key])) {\n continue // 跳过等于默认值的字段\n }\n result[key] = roundedValue\n continue\n }\n\n // 检查是否有默认值定义\n if (key in NODE_DEFAULTS) {\n const defaultValue = NODE_DEFAULTS[key]\n if (isEqual(value, defaultValue)) {\n continue // 跳过等于默认值的字段\n }\n }\n\n // 保留此字段\n result[key] = value\n }\n\n return result as T\n}\n\n// ==================== 空间信息提取 ====================\n\n/**\n * 提取节点的空间信息\n * 只保留 id、name、x、y、width、height、absoluteX、absoluteY 和 children 字段\n * 用于让 AI 以最少的字段理解节点的空间布局关系\n *\n * @param node 原始节点数据\n * @returns 精简的空间节点信息\n */\nexport function extractSpaceInfo(node: NodeInfo): SpaceNodeInfo {\n const result: SpaceNodeInfo = {\n id: node.id,\n name: node.name,\n x: roundToOneDecimal(typeof node.x === 'number' ? node.x : 0),\n y: roundToOneDecimal(typeof node.y === 'number' ? node.y : 0),\n width: roundToOneDecimal(typeof node.width === 'number' ? node.width : 0),\n height: roundToOneDecimal(typeof node.height === 'number' ? node.height : 0),\n }\n\n // 添加绝对坐标(如果存在)\n if (typeof node.absoluteX === 'number') {\n result.absoluteX = roundToOneDecimal(node.absoluteX)\n }\n if (typeof node.absoluteY === 'number') {\n result.absoluteY = roundToOneDecimal(node.absoluteY)\n }\n\n // 递归处理 children\n if (node.children && Array.isArray(node.children) && node.children.length > 0) {\n result.children = node.children.map((child) => extractSpaceInfo(child))\n }\n\n return result\n}\n","/**\n * MG Plugin 常量定义\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\n// ==================== 运行模式 ====================\n\n/** 是否为开发模式(通过环境变量 MG_DEV_MODE=true 设置) */\nexport const IS_DEV_MODE = process.env.MG_DEV_MODE === 'true'\n\n// ==================== 端口配置 ====================\n\n/** 生产环境默认端口 */\nexport const PROD_DEFAULT_PORT = 9527\n\n/** 生产环境端口范围:起始 */\nexport const PROD_PORT_RANGE_START = 9527\n\n/** 生产环境端口范围:结束 */\nexport const PROD_PORT_RANGE_END = 9536\n\n/** 开发环境默认端口 */\nexport const DEV_DEFAULT_PORT = 19527\n\n/** 开发环境端口范围:起始 */\nexport const DEV_PORT_RANGE_START = 19527\n\n/** 开发环境端口范围:结束 */\nexport const DEV_PORT_RANGE_END = 19536\n\n/** 默认端口(根据运行模式自动选择) */\nexport const DEFAULT_PORT = IS_DEV_MODE ? DEV_DEFAULT_PORT : PROD_DEFAULT_PORT\n\n/** 端口范围:起始(根据运行模式自动选择) */\nexport const PORT_RANGE_START = IS_DEV_MODE ? DEV_PORT_RANGE_START : PROD_PORT_RANGE_START\n\n/** 端口范围:结束(根据运行模式自动选择) */\nexport const PORT_RANGE_END = IS_DEV_MODE ? DEV_PORT_RANGE_END : PROD_PORT_RANGE_END\n\n/** 最大尝试端口数 */\nexport const MAX_PORT_ATTEMPTS = 10\n\n/** 端口扫描超时(毫秒) */\nexport const PORT_SCAN_TIMEOUT = 500\n\n// ==================== 路径配置 ====================\n\n/** 配置目录 */\nexport const CONFIG_DIR = join(homedir(), '.mg-plugin')\n\n/** Server 状态文件 */\nexport const SERVER_INFO_FILE = join(CONFIG_DIR, 'server.json')\n\n/** 日志目录 */\nexport const LOG_DIR = join(CONFIG_DIR, 'logs')\n\n/** Server 日志文件 */\nexport const SERVER_LOG_FILE = join(LOG_DIR, 'server.log')\n\n// ==================== 超时配置 ====================\n\n/** 心跳间隔(毫秒)- 30 秒 */\nexport const HEARTBEAT_INTERVAL = 30000\n\n/** 心跳超时(毫秒)- 90 秒(3 次心跳) */\nexport const HEARTBEAT_TIMEOUT = 90000\n\n/** 请求超时(毫秒)- 30 秒 */\nexport const REQUEST_TIMEOUT = 30000\n\n/** Server 启动等待超时(毫秒)- 5 秒 */\nexport const SERVER_START_TIMEOUT = 5000\n\n/** CLI 重试间隔(毫秒) */\nexport const RETRY_INTERVALS = [1000, 2000, 4000]\n\n/** 最大重试次数 */\nexport const MAX_RETRY_COUNT = 3\n\n// ==================== 连接类型 ====================\n\n/** 连接类型 */\nexport enum ConnectionType {\n /** 获取端 (CLI/MCP) */\n CONSUMER = 'consumer',\n /** 提供端 (Injector) */\n PROVIDER = 'provider',\n /** Chrome 扩展 (Background Script) */\n CHROME_EXTENSION = 'chrome_extension',\n}\n\n// ==================== 消息类型 ====================\n\n/** WebSocket 消息类型 */\nexport enum MessageType {\n // 系统消息\n PING = 'ping',\n PONG = 'pong',\n REGISTER = 'register',\n REGISTER_ACK = 'register_ack',\n\n // 业务消息\n GET_NODE_BY_ID = 'get_node_by_id',\n GET_PAGE_BY_ID = 'get_page_by_id',\n GET_ALL_NODES = 'get_all_nodes',\n GET_SELECTION = 'get_selection',\n EXPORT_IMAGE = 'export_image',\n EXECUTE_CODE = 'execute_code',\n GET_ALL_PAGES = 'get_all_pages',\n GET_COMMENTS = 'get_comments',\n\n // 扩展管理消息\n LIST_EXTENSIONS = 'list_extensions',\n OPEN_PAGE = 'open_page',\n NAVIGATE_TO_NODE = 'navigate_to_node',\n\n // Server 状态消息(本地请求,不转发到 Provider)\n GET_SERVER_STATUS = 'get_server_status',\n\n // 统计分析消息(CLI -> Server,fire-and-forget)\n TRACK_ANALYTICS = 'track_analytics',\n\n // 响应\n RESPONSE = 'response',\n ERROR = 'error',\n}\n","/**\n * MG Plugin 错误码定义\n */\n\n/** 错误码枚举 */\nexport enum ErrorCode {\n /** 无法连接到 MG Server */\n CONNECTION_FAILED = 'E001',\n /** 连接超时 */\n CONNECTION_TIMEOUT = 'E002',\n /** 没有 MasterGo 页面连接到 Server */\n NO_PAGE_CONNECTED = 'E003',\n /** 未找到匹配的页面 */\n PAGE_NOT_FOUND = 'E004',\n /** 节点不存在 */\n NODE_NOT_FOUND = 'E005',\n /** 没有选中任何节点 */\n NO_SELECTION = 'E006',\n /** mg 对象不可用 */\n MG_UNAVAILABLE = 'E007',\n /** 导出图片失败 */\n EXPORT_FAILED = 'E008',\n /** 文件写入失败 */\n FILE_WRITE_FAILED = 'E009',\n /** 无效的 mgp:// 链接格式 */\n INVALID_LINK = 'E010',\n /** 参数校验失败 */\n INVALID_PARAMS = 'E011',\n /** 请求超时 */\n REQUEST_TIMEOUT = 'E012',\n /** 所有备选端口均被占用 */\n PORT_EXHAUSTED = 'E013',\n /** 无法发现 Server (端口扫描失败) */\n SERVER_DISCOVERY_FAILED = 'E014',\n /** 自动启动 Server 失败 */\n SERVER_START_FAILED = 'E015',\n /** Server 已在运行中 */\n SERVER_ALREADY_RUNNING = 'E016',\n /** 连接断开 */\n CONNECTION_LOST = 'E017',\n /** 没有扩展连接到 Server */\n NO_EXTENSION_CONNECTED = 'E018',\n /** 未知错误 */\n UNKNOWN_ERROR = 'E099',\n}\n\n/** 错误码对应的错误名称 */\nexport const ErrorNames: Record<ErrorCode, string> = {\n [ErrorCode.CONNECTION_FAILED]: 'CONNECTION_FAILED',\n [ErrorCode.CONNECTION_TIMEOUT]: 'CONNECTION_TIMEOUT',\n [ErrorCode.NO_PAGE_CONNECTED]: 'NO_PAGE_CONNECTED',\n [ErrorCode.PAGE_NOT_FOUND]: 'PAGE_NOT_FOUND',\n [ErrorCode.NODE_NOT_FOUND]: 'NODE_NOT_FOUND',\n [ErrorCode.NO_SELECTION]: 'NO_SELECTION',\n [ErrorCode.MG_UNAVAILABLE]: 'MG_UNAVAILABLE',\n [ErrorCode.EXPORT_FAILED]: 'EXPORT_FAILED',\n [ErrorCode.FILE_WRITE_FAILED]: 'FILE_WRITE_FAILED',\n [ErrorCode.INVALID_LINK]: 'INVALID_LINK',\n [ErrorCode.INVALID_PARAMS]: 'INVALID_PARAMS',\n [ErrorCode.REQUEST_TIMEOUT]: 'REQUEST_TIMEOUT',\n [ErrorCode.PORT_EXHAUSTED]: 'PORT_EXHAUSTED',\n [ErrorCode.SERVER_DISCOVERY_FAILED]: 'SERVER_DISCOVERY_FAILED',\n [ErrorCode.SERVER_START_FAILED]: 'SERVER_START_FAILED',\n [ErrorCode.SERVER_ALREADY_RUNNING]: 'SERVER_ALREADY_RUNNING',\n [ErrorCode.CONNECTION_LOST]: 'CONNECTION_LOST',\n [ErrorCode.NO_EXTENSION_CONNECTED]: 'NO_EXTENSION_CONNECTED',\n [ErrorCode.UNKNOWN_ERROR]: 'UNKNOWN_ERROR',\n}\n\n/** 错误码对应的默认消息 */\nexport const ErrorMessages: Record<ErrorCode, string> = {\n [ErrorCode.CONNECTION_FAILED]: '无法连接到 MG Server',\n [ErrorCode.CONNECTION_TIMEOUT]: '连接超时',\n [ErrorCode.NO_PAGE_CONNECTED]: '没有 MasterGo 页面连接到 Server。请安装 MG Plugin 浏览器扩展: https://chromewebstore.google.com/detail/mg-plugin/ddhihanlpcdneicohnglnaliefnkaeja',\n [ErrorCode.PAGE_NOT_FOUND]: '未找到匹配的页面',\n [ErrorCode.NODE_NOT_FOUND]: '节点不存在',\n [ErrorCode.NO_SELECTION]: '没有选中任何节点',\n [ErrorCode.MG_UNAVAILABLE]: 'mg 对象不可用',\n [ErrorCode.EXPORT_FAILED]: '导出图片失败',\n [ErrorCode.FILE_WRITE_FAILED]: '文件写入失败',\n [ErrorCode.INVALID_LINK]: '无效的 mgp:// 链接格式',\n [ErrorCode.INVALID_PARAMS]: '参数校验失败',\n [ErrorCode.REQUEST_TIMEOUT]: '请求超时',\n [ErrorCode.PORT_EXHAUSTED]: '所有备选端口均被占用',\n [ErrorCode.SERVER_DISCOVERY_FAILED]: '无法发现 Server (端口扫描失败)',\n [ErrorCode.SERVER_START_FAILED]: '自动启动 Server 失败',\n [ErrorCode.SERVER_ALREADY_RUNNING]: 'Server 已在运行中',\n [ErrorCode.CONNECTION_LOST]: '连接断开',\n [ErrorCode.NO_EXTENSION_CONNECTED]: '没有 Chrome 扩展连接到 Server。请确保浏览器已打开并安装了 MG Plugin',\n [ErrorCode.UNKNOWN_ERROR]: '未知错误',\n}\n\n/** MG Plugin 错误类 */\nexport class MGError extends Error {\n /** 错误码 */\n code: ErrorCode\n /** 错误名称 */\n errorName: string\n /** 额外详情 */\n details?: Record<string, unknown>\n\n constructor(code: ErrorCode, message?: string, details?: Record<string, unknown>) {\n super(message || ErrorMessages[code])\n this.name = 'MGError'\n this.code = code\n this.errorName = ErrorNames[code]\n this.details = details\n }\n\n /** 转换为 JSON 格式 */\n toJSON() {\n return {\n code: this.code,\n name: this.errorName,\n message: this.message,\n details: this.details,\n }\n }\n\n /** 格式化输出 */\n toString() {\n return `错误 [${this.code}]: ${this.message}`\n }\n}\n\n/**\n * 创建错误\n */\nexport function createError(\n code: ErrorCode,\n message?: string,\n details?: Record<string, unknown>\n): MGError {\n return new MGError(code, message, details)\n}\n","/**\n * WebSocket 服务器\n */\n\nimport { WebSocketServer, WebSocket } from 'ws'\nimport type { IncomingMessage } from 'node:http'\nimport {\n ConnectionType,\n MessageType,\n DEFAULT_PORT,\n PORT_RANGE_START,\n PORT_RANGE_END,\n HEARTBEAT_INTERVAL,\n} from '../shared/constants.js'\nimport { ErrorCode, MGError } from '../shared/errors.js'\nimport type { BaseMessage, RegisterMessage, ResponseMessage, ServerStatusResponse, ConnectedPageInfo } from '../shared/types.js'\nimport { formatDuration } from '../shared/utils.js'\nimport { Logger, createLogger } from './logger.js'\nimport { ConnectionManager, ManagedWebSocket } from './connection-manager.js'\nimport { RequestHandler } from './request-handler.js'\nimport { getVersion } from '../shared/version.js'\nimport { initServerAnalytics, trackEvent, shutdownServerAnalytics, type AnalyticsEvent } from './analytics.js'\n\nexport interface ServerOptions {\n /** 监听端口 */\n port?: number\n /** 日志选项 */\n logger?: Logger\n}\n\n/**\n * MG WebSocket 服务器\n */\nexport class MGServer {\n private wss: WebSocketServer | null = null\n private logger: Logger\n private connectionManager: ConnectionManager\n private requestHandler: RequestHandler\n\n private port: number\n private isRunning = false\n private startedAt: Date | null = null\n\n constructor(options: ServerOptions = {}) {\n this.port = options.port || DEFAULT_PORT\n this.logger = options.logger || createLogger()\n this.connectionManager = new ConnectionManager(this.logger)\n this.requestHandler = new RequestHandler(this.connectionManager, this.logger)\n }\n\n /**\n * 启动服务器\n */\n async start(): Promise<number> {\n if (this.isRunning) {\n throw new MGError(ErrorCode.SERVER_ALREADY_RUNNING, 'Server 已在运行中')\n }\n\n // 尝试绑定端口\n const port = await this.findAvailablePort()\n\n return new Promise((resolve, reject) => {\n this.wss = new WebSocketServer({ port })\n\n this.wss.on('listening', () => {\n this.port = port\n this.isRunning = true\n this.startedAt = new Date()\n this.logger.info(`Server 启动成功,监听端口: ${port}`)\n\n // 启动心跳检查\n this.connectionManager.startHeartbeatCheck(HEARTBEAT_INTERVAL)\n\n // 初始化统计分析\n initServerAnalytics(this.logger)\n\n resolve(port)\n })\n\n this.wss.on('error', (error: NodeJS.ErrnoException) => {\n this.logger.error('Server 错误:', error)\n reject(error)\n })\n\n this.wss.on('connection', (ws: WebSocket, request: IncomingMessage) => {\n this.handleConnection(ws, request)\n })\n })\n }\n\n /**\n * 查找可用端口\n */\n private async findAvailablePort(): Promise<number> {\n for (let port = PORT_RANGE_START; port <= PORT_RANGE_END; port++) {\n const available = await this.isPortAvailable(port)\n if (available) {\n return port\n }\n this.logger.debug(`端口 ${port} 被占用,尝试下一个`)\n }\n\n throw new MGError(\n ErrorCode.PORT_EXHAUSTED,\n `端口 ${PORT_RANGE_START}-${PORT_RANGE_END} 均被占用`\n )\n }\n\n /**\n * 检查端口是否可用\n */\n private isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const testServer = new WebSocketServer({ port })\n\n testServer.on('listening', () => {\n testServer.close()\n resolve(true)\n })\n\n testServer.on('error', () => {\n resolve(false)\n })\n })\n }\n\n /**\n * 处理新连接\n */\n private handleConnection(ws: WebSocket, _request: IncomingMessage): void {\n this.logger.info('新连接建立')\n\n // 等待注册消息\n const registerTimeout = setTimeout(() => {\n this.logger.warn('连接注册超时,关闭连接')\n ws.close()\n }, 5000)\n\n ws.on('message', (data) => {\n try {\n const message = JSON.parse(data.toString()) as BaseMessage\n\n // 处理注册消息\n if (message.type === MessageType.REGISTER) {\n clearTimeout(registerTimeout)\n this.handleRegister(ws, message as RegisterMessage)\n return\n }\n\n // 统计消息不需要注册(fire-and-forget 模式)\n if (message.type === MessageType.TRACK_ANALYTICS) {\n this.handleTrackAnalytics(message)\n return\n }\n\n // 其他消息需要已注册\n const managedWs = ws as ManagedWebSocket\n if (!managedWs.connectionId) {\n this.logger.warn('未注册的连接发送消息,忽略')\n return\n }\n\n this.handleMessage(managedWs, message)\n } catch (error) {\n this.logger.error('消息解析失败:', error)\n }\n })\n\n ws.on('close', () => {\n clearTimeout(registerTimeout)\n const managedWs = ws as ManagedWebSocket\n if (managedWs.connectionId) {\n this.requestHandler.cleanupConnectionRequests(managedWs.connectionId)\n this.connectionManager.removeConnection(managedWs)\n }\n })\n\n ws.on('error', (error) => {\n this.logger.error('WebSocket 错误:', error)\n })\n }\n\n /**\n * 处理注册消息\n */\n private handleRegister(ws: WebSocket, message: RegisterMessage): void {\n const { connectionType, pageUrl, pageId } = message.data\n const extensionId = (message.data as any).extensionId\n\n let managedWs: ManagedWebSocket\n let extensionIndex: number | undefined\n\n // Chrome 扩展需要特殊处理\n if (connectionType === ConnectionType.CHROME_EXTENSION && extensionId) {\n managedWs = this.connectionManager.addChromeExtension(ws, extensionId)\n const exts = this.connectionManager.getAllExtensions()\n const ext = exts.find(e => e.extensionId === extensionId)\n extensionIndex = ext?.index\n } else {\n managedWs = this.connectionManager.addConnection(\n ws,\n connectionType,\n pageUrl,\n pageId\n )\n }\n\n // 发送注册确认(包含 Server 版本信息和扩展序号)\n const ack: ResponseMessage = {\n id: message.id || '',\n type: MessageType.REGISTER_ACK,\n success: true,\n data: {\n connectionId: managedWs.connectionId,\n pageUrl,\n serverVersion: getVersion(),\n ...(extensionIndex !== undefined && { extensionIndex }),\n },\n }\n\n ws.send(JSON.stringify(ack))\n }\n\n /**\n * 处理消息\n */\n private handleMessage(ws: ManagedWebSocket, message: BaseMessage): void {\n this.connectionManager.updateLastActive(ws)\n\n switch (message.type) {\n case MessageType.PING:\n this.handlePing(ws, message)\n break\n\n case MessageType.GET_SERVER_STATUS:\n // 直接处理 Server 状态查询,不转发给 Provider\n this.handleGetServerStatus(ws, message)\n break\n\n case MessageType.LIST_EXTENSIONS:\n // 直接处理扩展列表查询\n this.handleListExtensions(ws, message)\n break\n\n case MessageType.OPEN_PAGE:\n // 处理打开页面请求\n this.handleOpenPage(ws, message)\n break\n\n case MessageType.NAVIGATE_TO_NODE:\n // 处理节点导航请求\n this.handleNavigateToNode(ws, message)\n break\n\n case MessageType.TRACK_ANALYTICS:\n // 处理统计事件(fire-and-forget,不返回响应)\n this.handleTrackAnalytics(message)\n break\n\n case MessageType.RESPONSE:\n case MessageType.ERROR:\n // Provider 或 Extension 返回的响应\n this.requestHandler.handleResponse(message as ResponseMessage)\n break\n\n default:\n // Consumer 发送的请求\n if (ws.connectionInfo.type === ConnectionType.CONSUMER) {\n this.requestHandler.handleRequest(ws, message as any)\n }\n break\n }\n }\n\n /**\n * 处理心跳\n */\n private handlePing(ws: ManagedWebSocket, message: BaseMessage): void {\n const pong = {\n type: MessageType.PONG,\n timestamp: (message as any).timestamp || Date.now(),\n }\n ws.send(JSON.stringify(pong))\n }\n\n /**\n * 处理 Server 状态查询\n */\n private handleGetServerStatus(ws: ManagedWebSocket, message: BaseMessage): void {\n const providers = this.connectionManager.getAllProviders()\n const stats = this.connectionManager.getStats()\n\n // 构建连接页面信息\n const connectedPages: ConnectedPageInfo[] = providers.map((info) => ({\n pageUrl: info.pageUrl || '',\n connectedAt: info.connectedAt.toISOString(),\n lastActiveAt: info.lastActiveAt.toISOString(),\n }))\n\n // 构建扩展信息\n const extensions = this.connectionManager.getAllExtensions()\n const connectedExtensions = extensions.map((ext) => ({\n index: ext.index,\n extensionId: ext.extensionId,\n connectedAt: ext.ws.connectionInfo.connectedAt.toISOString(),\n lastActiveAt: ext.ws.connectionInfo.lastActiveAt.toISOString(),\n }))\n\n const uptimeMs = this.startedAt ? Date.now() - this.startedAt.getTime() : 0\n\n const statusData: ServerStatusResponse = {\n running: this.isRunning,\n port: this.port,\n pid: process.pid,\n startedAt: this.startedAt?.toISOString() || '',\n uptime: formatDuration(uptimeMs),\n version: getVersion(),\n stats,\n connectedPages,\n connectedExtensions,\n }\n\n const response: ResponseMessage = {\n id: message.id || '',\n type: MessageType.RESPONSE,\n success: true,\n data: statusData,\n }\n\n ws.send(JSON.stringify(response))\n this.logger.info('返回 Server 状态信息')\n }\n\n /**\n * 处理扩展列表查询\n */\n private handleListExtensions(ws: ManagedWebSocket, message: BaseMessage): void {\n const extensions = this.connectionManager.getAllExtensions()\n\n const extensionList = extensions.map((ext) => ({\n index: ext.index,\n extensionId: ext.extensionId,\n connectedAt: ext.ws.connectionInfo.connectedAt.toISOString(),\n lastActiveAt: ext.ws.connectionInfo.lastActiveAt.toISOString(),\n }))\n\n const response: ResponseMessage = {\n id: message.id || '',\n type: MessageType.RESPONSE,\n success: true,\n data: {\n extensions: extensionList,\n totalCount: extensionList.length,\n },\n }\n\n ws.send(JSON.stringify(response))\n this.logger.info(`返回扩展列表,共 ${extensionList.length} 个扩展`)\n }\n\n /**\n * 处理打开页面请求\n */\n private handleOpenPage(ws: ManagedWebSocket, message: BaseMessage): void {\n const params = (message as any).params as { url: string; extensionIndex?: number }\n const requestId = message.id || ''\n\n if (!params?.url) {\n const errorResponse: ResponseMessage = {\n id: requestId,\n type: MessageType.ERROR,\n success: false,\n error: {\n code: ErrorCode.INVALID_PARAMS,\n name: 'INVALID_PARAMS',\n message: '缺少 url 参数',\n },\n }\n ws.send(JSON.stringify(errorResponse))\n return\n }\n\n // 查找目标扩展\n const targetIndex = params.extensionIndex || 1\n const targetExtension = this.connectionManager.findExtensionByIndex(targetIndex)\n\n if (!targetExtension) {\n const errorResponse: ResponseMessage = {\n id: requestId,\n type: MessageType.ERROR,\n success: false,\n error: {\n code: ErrorCode.NO_EXTENSION_CONNECTED,\n name: 'NO_EXTENSION_CONNECTED',\n message: targetIndex === 1\n ? '没有 Chrome 扩展连接到 Server。请确保浏览器已打开并安装了 MG Plugin'\n : `未找到序号为 #${targetIndex} 的扩展实例`,\n },\n }\n ws.send(JSON.stringify(errorResponse))\n this.logger.warn(`未找到扩展实例 #${targetIndex}`)\n return\n }\n\n // 创建请求消息\n const forwardMessage = {\n id: requestId,\n type: MessageType.OPEN_PAGE,\n params: { url: params.url },\n }\n\n // 注册待处理请求(复用 requestHandler 的超时和响应处理逻辑)\n this.requestHandler.registerPendingRequest(requestId, ws, () => {\n // 转发请求给目标扩展\n try {\n targetExtension.send(JSON.stringify(forwardMessage))\n this.logger.info(`转发 OPEN_PAGE 请求到扩展 #${targetIndex}: ${params.url}`)\n } catch (error) {\n this.logger.error(`转发请求失败: ${error}`)\n const errorResponse: ResponseMessage = {\n id: requestId,\n type: MessageType.ERROR,\n success: false,\n error: {\n code: ErrorCode.CONNECTION_FAILED,\n name: 'CONNECTION_FAILED',\n message: '转发请求失败',\n },\n }\n ws.send(JSON.stringify(errorResponse))\n }\n })\n }\n\n /**\n * 处理统计事件\n */\n private handleTrackAnalytics(message: BaseMessage): void {\n const eventData = (message as any).data as AnalyticsEvent\n if (eventData) {\n trackEvent(eventData)\n }\n }\n\n /**\n * 处理节点导航请求\n */\n private handleNavigateToNode(ws: ManagedWebSocket, message: BaseMessage): void {\n const params = (message as any).params as {\n pageUrl: string\n nodeId: string\n extensionIndex?: number\n }\n const requestId = message.id || ''\n\n if (!params?.pageUrl || !params?.nodeId) {\n const errorResponse: ResponseMessage = {\n id: requestId,\n type: MessageType.ERROR,\n success: false,\n error: {\n code: ErrorCode.INVALID_PARAMS,\n name: 'INVALID_PARAMS',\n message: '缺少 pageUrl 或 nodeId 参数',\n },\n }\n ws.send(JSON.stringify(errorResponse))\n return\n }\n\n // 查找目标扩展\n const targetIndex = params.extensionIndex || 1\n const targetExtension = this.connectionManager.findExtensionByIndex(targetIndex)\n\n if (!targetExtension) {\n const errorResponse: ResponseMessage = {\n id: requestId,\n type: MessageType.ERROR,\n success: false,\n error: {\n code: ErrorCode.NO_EXTENSION_CONNECTED,\n name: 'NO_EXTENSION_CONNECTED',\n message: targetIndex === 1\n ? '没有 Chrome 扩展连接到 Server。请确保浏览器已打开并安装了 MG Plugin'\n : `未找到序号为 #${targetIndex} 的扩展实例`,\n },\n }\n ws.send(JSON.stringify(errorResponse))\n this.logger.warn(`未找到扩展实例 #${targetIndex}`)\n return\n }\n\n // 创建请求消息\n const forwardMessage = {\n id: requestId,\n type: MessageType.NAVIGATE_TO_NODE,\n params: {\n pageUrl: params.pageUrl,\n nodeId: params.nodeId,\n },\n }\n\n // 注册待处理请求\n this.requestHandler.registerPendingRequest(requestId, ws, () => {\n try {\n targetExtension.send(JSON.stringify(forwardMessage))\n this.logger.info(`转发 NAVIGATE_TO_NODE 请求到扩展 #${targetIndex}: ${params.pageUrl} -> ${params.nodeId}`)\n } catch (error) {\n this.logger.error(`转发请求失败: ${error}`)\n const errorResponse: ResponseMessage = {\n id: requestId,\n type: MessageType.ERROR,\n success: false,\n error: {\n code: ErrorCode.CONNECTION_FAILED,\n name: 'CONNECTION_FAILED',\n message: '转发请求失败',\n },\n }\n ws.send(JSON.stringify(errorResponse))\n }\n })\n }\n\n /**\n * 停止服务器\n */\n async stop(): Promise<void> {\n if (!this.isRunning || !this.wss) {\n return\n }\n\n this.logger.info('正在停止 Server...')\n\n // 关闭统计分析(确保事件发送完成)\n await shutdownServerAnalytics()\n\n // 清理所有请求\n this.requestHandler.cleanupAll()\n\n // 关闭所有连接\n this.connectionManager.closeAll()\n\n // 关闭服务器\n return new Promise((resolve) => {\n this.wss!.close(() => {\n this.isRunning = false\n this.wss = null\n this.logger.info('Server 已停止')\n resolve()\n })\n })\n }\n\n /**\n * 获取运行状态\n */\n getStatus(): {\n running: boolean\n port: number\n stats: { providers: number; consumers: number; total: number }\n connectedPages: string[]\n } {\n return {\n running: this.isRunning,\n port: this.port,\n stats: this.connectionManager.getStats(),\n connectedPages: this.connectionManager.getConnectedPageUrls(),\n }\n }\n\n /**\n * 获取端口\n */\n getPort(): number {\n return this.port\n }\n\n /**\n * 是否运行中\n */\n isServerRunning(): boolean {\n return this.isRunning\n }\n}\n\n/**\n * 创建服务器实例\n */\nexport function createServer(options?: ServerOptions): MGServer {\n return new MGServer(options)\n}\n","/**\n * 日志模块\n */\n\nimport { appendFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { SERVER_LOG_FILE } from '../shared/constants.js'\nimport { formatLogTime } from '../shared/utils.js'\n\nexport enum LogLevel {\n DEBUG = 'DEBUG',\n INFO = 'INFO',\n WARN = 'WARN',\n ERROR = 'ERROR',\n}\n\nexport interface LoggerOptions {\n /** 是否输出到控制台 */\n console?: boolean\n /** 是否输出到文件 */\n file?: boolean\n /** 日志文件路径 */\n filePath?: string\n /** 最小日志级别 */\n minLevel?: LogLevel\n}\n\nconst levelPriority: Record<LogLevel, number> = {\n [LogLevel.DEBUG]: 0,\n [LogLevel.INFO]: 1,\n [LogLevel.WARN]: 2,\n [LogLevel.ERROR]: 3,\n}\n\n/**\n * 日志记录器\n */\nexport class Logger {\n private options: Required<LoggerOptions>\n\n constructor(options: LoggerOptions = {}) {\n this.options = {\n console: options.console ?? true,\n file: options.file ?? false,\n filePath: options.filePath ?? SERVER_LOG_FILE,\n minLevel: options.minLevel ?? LogLevel.INFO,\n }\n\n // 确保日志目录存在\n if (this.options.file) {\n const dir = dirname(this.options.filePath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n }\n }\n\n /**\n * 记录日志\n */\n private log(level: LogLevel, message: string, ...args: unknown[]): void {\n // 检查日志级别\n if (levelPriority[level] < levelPriority[this.options.minLevel]) {\n return\n }\n\n const timestamp = formatLogTime()\n const formattedMessage = `[${timestamp}] [${level}] ${message}`\n\n // 输出到控制台\n if (this.options.console) {\n const consoleMethod = level === LogLevel.ERROR ? console.error : console.log\n if (args.length > 0) {\n consoleMethod(formattedMessage, ...args)\n } else {\n consoleMethod(formattedMessage)\n }\n }\n\n // 输出到文件\n if (this.options.file) {\n try {\n const fileMessage =\n args.length > 0\n ? `${formattedMessage} ${JSON.stringify(args)}\\n`\n : `${formattedMessage}\\n`\n appendFileSync(this.options.filePath, fileMessage)\n } catch (error) {\n // 文件写入失败时静默处理\n if (this.options.console) {\n console.error('日志文件写入失败:', error)\n }\n }\n }\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.log(LogLevel.DEBUG, message, ...args)\n }\n\n info(message: string, ...args: unknown[]): void {\n this.log(LogLevel.INFO, message, ...args)\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.log(LogLevel.WARN, message, ...args)\n }\n\n error(message: string, ...args: unknown[]): void {\n this.log(LogLevel.ERROR, message, ...args)\n }\n}\n\n/** 创建默认日志记录器 */\nexport function createLogger(options?: LoggerOptions): Logger {\n return new Logger(options)\n}\n","/**\n * 版本管理模块\n * 提供获取当前 CLI 版本的函数\n * 优先从 package.json 读取版本号(本地开发默认 9.9.9)\n * CI 发布时会用 VERSION 文件覆盖 package.json\n */\n\nimport { readFileSync, existsSync } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, join } from 'node:path'\n\n/** 缓存的版本号 */\nlet cachedVersion: string | null = null\n\n/**\n * 获取当前 CLI 版本号\n * 优先从 package.json 读取(本地开发默认 9.9.9)\n * CI 发布时会用 VERSION 文件的值覆盖 package.json\n */\nexport function getVersion(): string {\n if (cachedVersion !== null) {\n return cachedVersion\n }\n\n try {\n // 获取当前模块的目录\n const currentFile = fileURLToPath(import.meta.url)\n const currentDir = dirname(currentFile)\n\n // 优先从 package.json 读取版本号\n // 本地开发时 package.json 固定为 9.9.9\n // CI 发布时会用 VERSION 文件覆盖 package.json 后再打包\n const packageJsonPaths = [\n join(currentDir, '..', 'package.json'), // dist/xxx.js -> ../package.json\n join(currentDir, '..', '..', 'package.json'), // src/shared/version.ts -> ../../package.json\n ]\n\n for (const packageJsonPath of packageJsonPaths) {\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))\n if (packageJson.name === '@hangox/mg-cli') {\n cachedVersion = (packageJson.version as string) || '0.0.0'\n return cachedVersion\n }\n }\n }\n\n // 如果找不到,返回默认版本\n cachedVersion = '0.0.0'\n return cachedVersion\n } catch {\n // 如果读取失败,返回默认版本\n cachedVersion = '0.0.0'\n return cachedVersion\n }\n}\n\n/** 开发版本标识 */\nconst DEV_VERSION = '9.9.9'\n\n/**\n * 比较两个版本是否一致\n * 9.9.9 是开发版本,与任何版本都视为匹配\n */\nexport function isVersionMatch(version1: string, version2: string): boolean {\n // 开发版本 9.9.9 与任何版本都视为匹配\n if (version1 === DEV_VERSION || version2 === DEV_VERSION) {\n return true\n }\n return version1 === version2\n}\n\n/**\n * 清除缓存的版本号(用于测试)\n */\nexport function clearVersionCache(): void {\n cachedVersion = null\n}\n","/**\n * Server 端 PostHog 统计分析模块\n * 负责接收 CLI 发送的统计事件并批量发送到 PostHog\n */\n\nimport { PostHog } from 'posthog-node'\nimport { Logger } from './logger.js'\n\n// PostHog 配置\nconst POSTHOG_API_KEY = 'phc_cSZZIxZOPhWOlsw92Wz8tmKQ5z8eQYsI3m9aM2Ujia9'\nconst POSTHOG_HOST = 'https://us.i.posthog.com'\n\n// 单例实例\nlet posthogClient: PostHog | null = null\nlet logger: Logger | null = null\n\n/**\n * 检查是否禁用遥测\n * 支持环境变量: MG_TELEMETRY_DISABLED=1 或 DO_NOT_TRACK=1\n */\nfunction isTelemetryDisabled(): boolean {\n return (\n process.env.MG_TELEMETRY_DISABLED === '1' ||\n process.env.MG_TELEMETRY_DISABLED === 'true' ||\n process.env.DO_NOT_TRACK === '1' ||\n process.env.DO_NOT_TRACK === 'true'\n )\n}\n\n/**\n * 初始化 Server 端 Analytics\n * @param serverLogger Server 的 Logger 实例\n */\nexport function initServerAnalytics(serverLogger: Logger): void {\n logger = serverLogger\n\n if (isTelemetryDisabled()) {\n logger.info('遥测已禁用 (MG_TELEMETRY_DISABLED 或 DO_NOT_TRACK)')\n return\n }\n\n if (!posthogClient) {\n posthogClient = new PostHog(POSTHOG_API_KEY, {\n host: POSTHOG_HOST,\n // Server 端使用批量模式,减少网络请求\n flushAt: 10,\n flushInterval: 30000, // 30 秒\n })\n logger.info('PostHog Analytics 已初始化')\n }\n}\n\n/**\n * 统计事件数据结构\n */\nexport interface AnalyticsEvent {\n distinctId: string\n event: string\n properties: Record<string, any>\n}\n\n/**\n * 处理从 CLI 发送的统计事件\n */\nexport function trackEvent(eventData: AnalyticsEvent): void {\n if (!posthogClient) {\n return\n }\n\n try {\n posthogClient.capture({\n distinctId: eventData.distinctId,\n event: eventData.event,\n properties: eventData.properties,\n })\n logger?.info(`统计事件已记录: ${eventData.event}`, eventData.properties)\n } catch (error) {\n logger?.error('统计事件记录失败:', error)\n }\n}\n\n/**\n * 关闭 PostHog 客户端\n * 确保所有事件都已发送\n */\nexport async function shutdownServerAnalytics(): Promise<void> {\n if (posthogClient) {\n try {\n logger?.info('正在发送剩余统计事件...')\n await posthogClient.shutdown()\n logger?.info('PostHog Analytics 已关闭')\n } catch (error) {\n logger?.error('关闭 PostHog 失败:', error)\n }\n posthogClient = null\n }\n}\n","/**\n * Native Messaging 协议层\n * Chrome Native Messaging 使用 32 位小端长度前缀 + UTF-8 JSON\n */\n\n/**\n * 编码消息为 Native Messaging 格式\n * 格式: [4字节长度(小端)] + [JSON字符串]\n */\nexport function encodeMessage(message: unknown): Buffer {\n const json = JSON.stringify(message)\n const body = Buffer.from(json, 'utf-8')\n const header = Buffer.alloc(4)\n header.writeUInt32LE(body.length, 0)\n return Buffer.concat([header, body])\n}\n\n/**\n * 从 Buffer 解码消息\n * 返回: { message, remaining } 或 null(数据不完整)\n */\nexport function decodeMessage(buffer: Buffer): { message: unknown; remaining: Buffer } | null {\n if (buffer.length < 4) return null\n\n const length = buffer.readUInt32LE(0)\n\n // Chrome Native Messaging 消息最大 1MB\n if (length > 1024 * 1024) {\n throw new Error(`消息过大: ${length} 字节(最大 1MB)`)\n }\n\n if (buffer.length < 4 + length) return null\n\n const json = buffer.subarray(4, 4 + length).toString('utf-8')\n const message = JSON.parse(json)\n const remaining = Buffer.from(buffer.subarray(4 + length))\n\n return { message, remaining }\n}\n"],"mappings":"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","names":["fileURLToPath","dirname","join","existsSync","mkdirSync","dirname","readFileSync","existsSync","dirname","join","fileURLToPath","dirname","join","resolve","running","info"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/constants.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/buffer-util.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/limiter.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/permessage-deflate.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/validation.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/receiver.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/sender.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/event-target.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/extension.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/websocket.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/stream.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/subprotocol.js","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/lib/websocket-server.js","../src/native-host/index.ts","../src/server/daemon.ts","../src/shared/utils.ts","../src/shared/constants.ts","../src/shared/errors.ts","../node_modules/.pnpm/ws@8.18.3/node_modules/ws/wrapper.mjs","../src/server/logger.ts","../src/shared/version.ts","../node_modules/.pnpm/posthog-node@5.18.0/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/vendor/uuidv7.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/utils/type-utils.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/utils/number-utils.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/utils/index.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/index.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/types.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs","../node_modules/.pnpm/@posthog+core@1.9.0/node_modules/@posthog/core/dist/error-tracking/utils.mjs","../node_modules/.pnpm/posthog-node@5.18.0/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs","../node_modules/.pnpm/posthog-node@5.18.0/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs","../node_modules/.pnpm/posthog-node@5.18.0/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs","../node_modules/.pnpm/posthog-node@5.18.0/node_modules/posthog-node/dist/extensions/context/context.mjs","../node_modules/.pnpm/posthog-node@5.18.0/node_modules/posthog-node/dist/extensions/sentry-integration.mjs","../node_modules/.pnpm/posthog-node@5.18.0/node_modules/posthog-node/dist/entrypoints/index.node.mjs","../src/native-host/protocol.ts"],"sourcesContent":["'use strict';\n\nconst BINARY_TYPES = ['nodebuffer', 'arraybuffer', 'fragments'];\nconst hasBlob = typeof Blob !== 'undefined';\n\nif (hasBlob) BINARY_TYPES.push('blob');\n\nmodule.exports = {\n BINARY_TYPES,\n EMPTY_BUFFER: Buffer.alloc(0),\n GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',\n hasBlob,\n kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),\n kListener: Symbol('kListener'),\n kStatusCode: Symbol('status-code'),\n kWebSocket: Symbol('websocket'),\n NOOP: () => {}\n};\n","'use strict';\n\nconst { EMPTY_BUFFER } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\n\n/**\n * Merges an array of buffers into a new buffer.\n *\n * @param {Buffer[]} list The array of buffers to concat\n * @param {Number} totalLength The total length of buffers in the list\n * @return {Buffer} The resulting buffer\n * @public\n */\nfunction concat(list, totalLength) {\n if (list.length === 0) return EMPTY_BUFFER;\n if (list.length === 1) return list[0];\n\n const target = Buffer.allocUnsafe(totalLength);\n let offset = 0;\n\n for (let i = 0; i < list.length; i++) {\n const buf = list[i];\n target.set(buf, offset);\n offset += buf.length;\n }\n\n if (offset < totalLength) {\n return new FastBuffer(target.buffer, target.byteOffset, offset);\n }\n\n return target;\n}\n\n/**\n * Masks a buffer using the given mask.\n *\n * @param {Buffer} source The buffer to mask\n * @param {Buffer} mask The mask to use\n * @param {Buffer} output The buffer where to store the result\n * @param {Number} offset The offset at which to start writing\n * @param {Number} length The number of bytes to mask.\n * @public\n */\nfunction _mask(source, mask, output, offset, length) {\n for (let i = 0; i < length; i++) {\n output[offset + i] = source[i] ^ mask[i & 3];\n }\n}\n\n/**\n * Unmasks a buffer using the given mask.\n *\n * @param {Buffer} buffer The buffer to unmask\n * @param {Buffer} mask The mask to use\n * @public\n */\nfunction _unmask(buffer, mask) {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] ^= mask[i & 3];\n }\n}\n\n/**\n * Converts a buffer to an `ArrayBuffer`.\n *\n * @param {Buffer} buf The buffer to convert\n * @return {ArrayBuffer} Converted buffer\n * @public\n */\nfunction toArrayBuffer(buf) {\n if (buf.length === buf.buffer.byteLength) {\n return buf.buffer;\n }\n\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);\n}\n\n/**\n * Converts `data` to a `Buffer`.\n *\n * @param {*} data The data to convert\n * @return {Buffer} The buffer\n * @throws {TypeError}\n * @public\n */\nfunction toBuffer(data) {\n toBuffer.readOnly = true;\n\n if (Buffer.isBuffer(data)) return data;\n\n let buf;\n\n if (data instanceof ArrayBuffer) {\n buf = new FastBuffer(data);\n } else if (ArrayBuffer.isView(data)) {\n buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);\n } else {\n buf = Buffer.from(data);\n toBuffer.readOnly = false;\n }\n\n return buf;\n}\n\nmodule.exports = {\n concat,\n mask: _mask,\n toArrayBuffer,\n toBuffer,\n unmask: _unmask\n};\n\n/* istanbul ignore else */\nif (!process.env.WS_NO_BUFFER_UTIL) {\n try {\n const bufferUtil = require('bufferutil');\n\n module.exports.mask = function (source, mask, output, offset, length) {\n if (length < 48) _mask(source, mask, output, offset, length);\n else bufferUtil.mask(source, mask, output, offset, length);\n };\n\n module.exports.unmask = function (buffer, mask) {\n if (buffer.length < 32) _unmask(buffer, mask);\n else bufferUtil.unmask(buffer, mask);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n","'use strict';\n\nconst kDone = Symbol('kDone');\nconst kRun = Symbol('kRun');\n\n/**\n * A very simple job queue with adjustable concurrency. Adapted from\n * https://github.com/STRML/async-limiter\n */\nclass Limiter {\n /**\n * Creates a new `Limiter`.\n *\n * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed\n * to run concurrently\n */\n constructor(concurrency) {\n this[kDone] = () => {\n this.pending--;\n this[kRun]();\n };\n this.concurrency = concurrency || Infinity;\n this.jobs = [];\n this.pending = 0;\n }\n\n /**\n * Adds a job to the queue.\n *\n * @param {Function} job The job to run\n * @public\n */\n add(job) {\n this.jobs.push(job);\n this[kRun]();\n }\n\n /**\n * Removes a job from the queue and runs it if possible.\n *\n * @private\n */\n [kRun]() {\n if (this.pending === this.concurrency) return;\n\n if (this.jobs.length) {\n const job = this.jobs.shift();\n\n this.pending++;\n job(this[kDone]);\n }\n }\n}\n\nmodule.exports = Limiter;\n","'use strict';\n\nconst zlib = require('zlib');\n\nconst bufferUtil = require('./buffer-util');\nconst Limiter = require('./limiter');\nconst { kStatusCode } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\nconst TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);\nconst kPerMessageDeflate = Symbol('permessage-deflate');\nconst kTotalLength = Symbol('total-length');\nconst kCallback = Symbol('callback');\nconst kBuffers = Symbol('buffers');\nconst kError = Symbol('error');\n\n//\n// We limit zlib concurrency, which prevents severe memory fragmentation\n// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913\n// and https://github.com/websockets/ws/issues/1202\n//\n// Intentionally global; it's the global thread pool that's an issue.\n//\nlet zlibLimiter;\n\n/**\n * permessage-deflate implementation.\n */\nclass PerMessageDeflate {\n /**\n * Creates a PerMessageDeflate instance.\n *\n * @param {Object} [options] Configuration options\n * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support\n * for, or request, a custom client window size\n * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/\n * acknowledge disabling of client context takeover\n * @param {Number} [options.concurrencyLimit=10] The number of concurrent\n * calls to zlib\n * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the\n * use of a custom server window size\n * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept\n * disabling of server context takeover\n * @param {Number} [options.threshold=1024] Size (in bytes) below which\n * messages should not be compressed if context takeover is disabled\n * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on\n * deflate\n * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on\n * inflate\n * @param {Boolean} [isServer=false] Create the instance in either server or\n * client mode\n * @param {Number} [maxPayload=0] The maximum allowed message length\n */\n constructor(options, isServer, maxPayload) {\n this._maxPayload = maxPayload | 0;\n this._options = options || {};\n this._threshold =\n this._options.threshold !== undefined ? this._options.threshold : 1024;\n this._isServer = !!isServer;\n this._deflate = null;\n this._inflate = null;\n\n this.params = null;\n\n if (!zlibLimiter) {\n const concurrency =\n this._options.concurrencyLimit !== undefined\n ? this._options.concurrencyLimit\n : 10;\n zlibLimiter = new Limiter(concurrency);\n }\n }\n\n /**\n * @type {String}\n */\n static get extensionName() {\n return 'permessage-deflate';\n }\n\n /**\n * Create an extension negotiation offer.\n *\n * @return {Object} Extension parameters\n * @public\n */\n offer() {\n const params = {};\n\n if (this._options.serverNoContextTakeover) {\n params.server_no_context_takeover = true;\n }\n if (this._options.clientNoContextTakeover) {\n params.client_no_context_takeover = true;\n }\n if (this._options.serverMaxWindowBits) {\n params.server_max_window_bits = this._options.serverMaxWindowBits;\n }\n if (this._options.clientMaxWindowBits) {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n } else if (this._options.clientMaxWindowBits == null) {\n params.client_max_window_bits = true;\n }\n\n return params;\n }\n\n /**\n * Accept an extension negotiation offer/response.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Object} Accepted configuration\n * @public\n */\n accept(configurations) {\n configurations = this.normalizeParams(configurations);\n\n this.params = this._isServer\n ? this.acceptAsServer(configurations)\n : this.acceptAsClient(configurations);\n\n return this.params;\n }\n\n /**\n * Releases all resources used by the extension.\n *\n * @public\n */\n cleanup() {\n if (this._inflate) {\n this._inflate.close();\n this._inflate = null;\n }\n\n if (this._deflate) {\n const callback = this._deflate[kCallback];\n\n this._deflate.close();\n this._deflate = null;\n\n if (callback) {\n callback(\n new Error(\n 'The deflate stream was closed while data was being processed'\n )\n );\n }\n }\n }\n\n /**\n * Accept an extension negotiation offer.\n *\n * @param {Array} offers The extension negotiation offers\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsServer(offers) {\n const opts = this._options;\n const accepted = offers.find((params) => {\n if (\n (opts.serverNoContextTakeover === false &&\n params.server_no_context_takeover) ||\n (params.server_max_window_bits &&\n (opts.serverMaxWindowBits === false ||\n (typeof opts.serverMaxWindowBits === 'number' &&\n opts.serverMaxWindowBits > params.server_max_window_bits))) ||\n (typeof opts.clientMaxWindowBits === 'number' &&\n !params.client_max_window_bits)\n ) {\n return false;\n }\n\n return true;\n });\n\n if (!accepted) {\n throw new Error('None of the extension offers can be accepted');\n }\n\n if (opts.serverNoContextTakeover) {\n accepted.server_no_context_takeover = true;\n }\n if (opts.clientNoContextTakeover) {\n accepted.client_no_context_takeover = true;\n }\n if (typeof opts.serverMaxWindowBits === 'number') {\n accepted.server_max_window_bits = opts.serverMaxWindowBits;\n }\n if (typeof opts.clientMaxWindowBits === 'number') {\n accepted.client_max_window_bits = opts.clientMaxWindowBits;\n } else if (\n accepted.client_max_window_bits === true ||\n opts.clientMaxWindowBits === false\n ) {\n delete accepted.client_max_window_bits;\n }\n\n return accepted;\n }\n\n /**\n * Accept the extension negotiation response.\n *\n * @param {Array} response The extension negotiation response\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsClient(response) {\n const params = response[0];\n\n if (\n this._options.clientNoContextTakeover === false &&\n params.client_no_context_takeover\n ) {\n throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n }\n\n if (!params.client_max_window_bits) {\n if (typeof this._options.clientMaxWindowBits === 'number') {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n }\n } else if (\n this._options.clientMaxWindowBits === false ||\n (typeof this._options.clientMaxWindowBits === 'number' &&\n params.client_max_window_bits > this._options.clientMaxWindowBits)\n ) {\n throw new Error(\n 'Unexpected or invalid parameter \"client_max_window_bits\"'\n );\n }\n\n return params;\n }\n\n /**\n * Normalize parameters.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Array} The offers/response with normalized parameters\n * @private\n */\n normalizeParams(configurations) {\n configurations.forEach((params) => {\n Object.keys(params).forEach((key) => {\n let value = params[key];\n\n if (value.length > 1) {\n throw new Error(`Parameter \"${key}\" must have only a single value`);\n }\n\n value = value[0];\n\n if (key === 'client_max_window_bits') {\n if (value !== true) {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (!this._isServer) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else if (key === 'server_max_window_bits') {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (\n key === 'client_no_context_takeover' ||\n key === 'server_no_context_takeover'\n ) {\n if (value !== true) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else {\n throw new Error(`Unknown parameter \"${key}\"`);\n }\n\n params[key] = value;\n });\n });\n\n return configurations;\n }\n\n /**\n * Decompress data. Concurrency limited.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n decompress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._decompress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Compress data. Concurrency limited.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n compress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._compress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Decompress data.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _decompress(data, fin, callback) {\n const endpoint = this._isServer ? 'client' : 'server';\n\n if (!this._inflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._inflate = zlib.createInflateRaw({\n ...this._options.zlibInflateOptions,\n windowBits\n });\n this._inflate[kPerMessageDeflate] = this;\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n this._inflate.on('error', inflateOnError);\n this._inflate.on('data', inflateOnData);\n }\n\n this._inflate[kCallback] = callback;\n\n this._inflate.write(data);\n if (fin) this._inflate.write(TRAILER);\n\n this._inflate.flush(() => {\n const err = this._inflate[kError];\n\n if (err) {\n this._inflate.close();\n this._inflate = null;\n callback(err);\n return;\n }\n\n const data = bufferUtil.concat(\n this._inflate[kBuffers],\n this._inflate[kTotalLength]\n );\n\n if (this._inflate._readableState.endEmitted) {\n this._inflate.close();\n this._inflate = null;\n } else {\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._inflate.reset();\n }\n }\n\n callback(null, data);\n });\n }\n\n /**\n * Compress data.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _compress(data, fin, callback) {\n const endpoint = this._isServer ? 'server' : 'client';\n\n if (!this._deflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._deflate = zlib.createDeflateRaw({\n ...this._options.zlibDeflateOptions,\n windowBits\n });\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n this._deflate.on('data', deflateOnData);\n }\n\n this._deflate[kCallback] = callback;\n\n this._deflate.write(data);\n this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {\n if (!this._deflate) {\n //\n // The deflate stream was closed while data was being processed.\n //\n return;\n }\n\n let data = bufferUtil.concat(\n this._deflate[kBuffers],\n this._deflate[kTotalLength]\n );\n\n if (fin) {\n data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);\n }\n\n //\n // Ensure that the callback will not be called again in\n // `PerMessageDeflate#cleanup()`.\n //\n this._deflate[kCallback] = null;\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._deflate.reset();\n }\n\n callback(null, data);\n });\n }\n}\n\nmodule.exports = PerMessageDeflate;\n\n/**\n * The listener of the `zlib.DeflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction deflateOnData(chunk) {\n this[kBuffers].push(chunk);\n this[kTotalLength] += chunk.length;\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction inflateOnData(chunk) {\n this[kTotalLength] += chunk.length;\n\n if (\n this[kPerMessageDeflate]._maxPayload < 1 ||\n this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload\n ) {\n this[kBuffers].push(chunk);\n return;\n }\n\n this[kError] = new RangeError('Max payload size exceeded');\n this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';\n this[kError][kStatusCode] = 1009;\n this.removeListener('data', inflateOnData);\n\n //\n // The choice to employ `zlib.reset()` over `zlib.close()` is dictated by the\n // fact that in Node.js versions prior to 13.10.0, the callback for\n // `zlib.flush()` is not called if `zlib.close()` is used. Utilizing\n // `zlib.reset()` ensures that either the callback is invoked or an error is\n // emitted.\n //\n this.reset();\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'error'` event.\n *\n * @param {Error} err The emitted error\n * @private\n */\nfunction inflateOnError(err) {\n //\n // There is no need to call `Zlib#close()` as the handle is automatically\n // closed when an error is emitted.\n //\n this[kPerMessageDeflate]._inflate = null;\n\n if (this[kError]) {\n this[kCallback](this[kError]);\n return;\n }\n\n err[kStatusCode] = 1007;\n this[kCallback](err);\n}\n","'use strict';\n\nconst { isUtf8 } = require('buffer');\n\nconst { hasBlob } = require('./constants');\n\n//\n// Allowed token characters:\n//\n// '!', '#', '$', '%', '&', ''', '*', '+', '-',\n// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'\n//\n// tokenChars[32] === 0 // ' '\n// tokenChars[33] === 1 // '!'\n// tokenChars[34] === 0 // '\"'\n// ...\n//\n// prettier-ignore\nconst tokenChars = [\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31\n 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63\n 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127\n];\n\n/**\n * Checks if a status code is allowed in a close frame.\n *\n * @param {Number} code The status code\n * @return {Boolean} `true` if the status code is valid, else `false`\n * @public\n */\nfunction isValidStatusCode(code) {\n return (\n (code >= 1000 &&\n code <= 1014 &&\n code !== 1004 &&\n code !== 1005 &&\n code !== 1006) ||\n (code >= 3000 && code <= 4999)\n );\n}\n\n/**\n * Checks if a given buffer contains only correct UTF-8.\n * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by\n * Markus Kuhn.\n *\n * @param {Buffer} buf The buffer to check\n * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`\n * @public\n */\nfunction _isValidUTF8(buf) {\n const len = buf.length;\n let i = 0;\n\n while (i < len) {\n if ((buf[i] & 0x80) === 0) {\n // 0xxxxxxx\n i++;\n } else if ((buf[i] & 0xe0) === 0xc0) {\n // 110xxxxx 10xxxxxx\n if (\n i + 1 === len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i] & 0xfe) === 0xc0 // Overlong\n ) {\n return false;\n }\n\n i += 2;\n } else if ((buf[i] & 0xf0) === 0xe0) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n if (\n i + 2 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong\n (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)\n ) {\n return false;\n }\n\n i += 3;\n } else if ((buf[i] & 0xf8) === 0xf0) {\n // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n if (\n i + 3 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i + 3] & 0xc0) !== 0x80 ||\n (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong\n (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||\n buf[i] > 0xf4 // > U+10FFFF\n ) {\n return false;\n }\n\n i += 4;\n } else {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Determines whether a value is a `Blob`.\n *\n * @param {*} value The value to be tested\n * @return {Boolean} `true` if `value` is a `Blob`, else `false`\n * @private\n */\nfunction isBlob(value) {\n return (\n hasBlob &&\n typeof value === 'object' &&\n typeof value.arrayBuffer === 'function' &&\n typeof value.type === 'string' &&\n typeof value.stream === 'function' &&\n (value[Symbol.toStringTag] === 'Blob' ||\n value[Symbol.toStringTag] === 'File')\n );\n}\n\nmodule.exports = {\n isBlob,\n isValidStatusCode,\n isValidUTF8: _isValidUTF8,\n tokenChars\n};\n\nif (isUtf8) {\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);\n };\n} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) {\n try {\n const isValidUTF8 = require('utf-8-validate');\n\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n","'use strict';\n\nconst { Writable } = require('stream');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n kStatusCode,\n kWebSocket\n} = require('./constants');\nconst { concat, toArrayBuffer, unmask } = require('./buffer-util');\nconst { isValidStatusCode, isValidUTF8 } = require('./validation');\n\nconst FastBuffer = Buffer[Symbol.species];\n\nconst GET_INFO = 0;\nconst GET_PAYLOAD_LENGTH_16 = 1;\nconst GET_PAYLOAD_LENGTH_64 = 2;\nconst GET_MASK = 3;\nconst GET_DATA = 4;\nconst INFLATING = 5;\nconst DEFER_EVENT = 6;\n\n/**\n * HyBi Receiver implementation.\n *\n * @extends Writable\n */\nclass Receiver extends Writable {\n /**\n * Creates a Receiver instance.\n *\n * @param {Object} [options] Options object\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {String} [options.binaryType=nodebuffer] The type for binary data\n * @param {Object} [options.extensions] An object containing the negotiated\n * extensions\n * @param {Boolean} [options.isServer=false] Specifies whether to operate in\n * client or server mode\n * @param {Number} [options.maxPayload=0] The maximum allowed message length\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n */\n constructor(options = {}) {\n super();\n\n this._allowSynchronousEvents =\n options.allowSynchronousEvents !== undefined\n ? options.allowSynchronousEvents\n : true;\n this._binaryType = options.binaryType || BINARY_TYPES[0];\n this._extensions = options.extensions || {};\n this._isServer = !!options.isServer;\n this._maxPayload = options.maxPayload | 0;\n this._skipUTF8Validation = !!options.skipUTF8Validation;\n this[kWebSocket] = undefined;\n\n this._bufferedBytes = 0;\n this._buffers = [];\n\n this._compressed = false;\n this._payloadLength = 0;\n this._mask = undefined;\n this._fragmented = 0;\n this._masked = false;\n this._fin = false;\n this._opcode = 0;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragments = [];\n\n this._errored = false;\n this._loop = false;\n this._state = GET_INFO;\n }\n\n /**\n * Implements `Writable.prototype._write()`.\n *\n * @param {Buffer} chunk The chunk of data to write\n * @param {String} encoding The character encoding of `chunk`\n * @param {Function} cb Callback\n * @private\n */\n _write(chunk, encoding, cb) {\n if (this._opcode === 0x08 && this._state == GET_INFO) return cb();\n\n this._bufferedBytes += chunk.length;\n this._buffers.push(chunk);\n this.startLoop(cb);\n }\n\n /**\n * Consumes `n` bytes from the buffered data.\n *\n * @param {Number} n The number of bytes to consume\n * @return {Buffer} The consumed bytes\n * @private\n */\n consume(n) {\n this._bufferedBytes -= n;\n\n if (n === this._buffers[0].length) return this._buffers.shift();\n\n if (n < this._buffers[0].length) {\n const buf = this._buffers[0];\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n\n return new FastBuffer(buf.buffer, buf.byteOffset, n);\n }\n\n const dst = Buffer.allocUnsafe(n);\n\n do {\n const buf = this._buffers[0];\n const offset = dst.length - n;\n\n if (n >= buf.length) {\n dst.set(this._buffers.shift(), offset);\n } else {\n dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n }\n\n n -= buf.length;\n } while (n > 0);\n\n return dst;\n }\n\n /**\n * Starts the parsing loop.\n *\n * @param {Function} cb Callback\n * @private\n */\n startLoop(cb) {\n this._loop = true;\n\n do {\n switch (this._state) {\n case GET_INFO:\n this.getInfo(cb);\n break;\n case GET_PAYLOAD_LENGTH_16:\n this.getPayloadLength16(cb);\n break;\n case GET_PAYLOAD_LENGTH_64:\n this.getPayloadLength64(cb);\n break;\n case GET_MASK:\n this.getMask();\n break;\n case GET_DATA:\n this.getData(cb);\n break;\n case INFLATING:\n case DEFER_EVENT:\n this._loop = false;\n return;\n }\n } while (this._loop);\n\n if (!this._errored) cb();\n }\n\n /**\n * Reads the first two bytes of a frame.\n *\n * @param {Function} cb Callback\n * @private\n */\n getInfo(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(2);\n\n if ((buf[0] & 0x30) !== 0x00) {\n const error = this.createError(\n RangeError,\n 'RSV2 and RSV3 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_2_3'\n );\n\n cb(error);\n return;\n }\n\n const compressed = (buf[0] & 0x40) === 0x40;\n\n if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n this._fin = (buf[0] & 0x80) === 0x80;\n this._opcode = buf[0] & 0x0f;\n this._payloadLength = buf[1] & 0x7f;\n\n if (this._opcode === 0x00) {\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fragmented) {\n const error = this.createError(\n RangeError,\n 'invalid opcode 0',\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._opcode = this._fragmented;\n } else if (this._opcode === 0x01 || this._opcode === 0x02) {\n if (this._fragmented) {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._compressed = compressed;\n } else if (this._opcode > 0x07 && this._opcode < 0x0b) {\n if (!this._fin) {\n const error = this.createError(\n RangeError,\n 'FIN must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_FIN'\n );\n\n cb(error);\n return;\n }\n\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (\n this._payloadLength > 0x7d ||\n (this._opcode === 0x08 && this._payloadLength === 1)\n ) {\n const error = this.createError(\n RangeError,\n `invalid payload length ${this._payloadLength}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n } else {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fin && !this._fragmented) this._fragmented = this._opcode;\n this._masked = (buf[1] & 0x80) === 0x80;\n\n if (this._isServer) {\n if (!this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n } else if (this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n\n if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;\n else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;\n else this.haveLength(cb);\n }\n\n /**\n * Gets extended payload length (7+16).\n *\n * @param {Function} cb Callback\n * @private\n */\n getPayloadLength16(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n this._payloadLength = this.consume(2).readUInt16BE(0);\n this.haveLength(cb);\n }\n\n /**\n * Gets extended payload length (7+64).\n *\n * @param {Function} cb Callback\n * @private\n */\n getPayloadLength64(cb) {\n if (this._bufferedBytes < 8) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(8);\n const num = buf.readUInt32BE(0);\n\n //\n // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned\n // if payload length is greater than this number.\n //\n if (num > Math.pow(2, 53 - 32) - 1) {\n const error = this.createError(\n RangeError,\n 'Unsupported WebSocket frame: payload length > 2^53 - 1',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n\n this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);\n this.haveLength(cb);\n }\n\n /**\n * Payload length has been read.\n *\n * @param {Function} cb Callback\n * @private\n */\n haveLength(cb) {\n if (this._payloadLength && this._opcode < 0x08) {\n this._totalPayloadLength += this._payloadLength;\n if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {\n const error = this.createError(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n\n cb(error);\n return;\n }\n }\n\n if (this._masked) this._state = GET_MASK;\n else this._state = GET_DATA;\n }\n\n /**\n * Reads mask bytes.\n *\n * @private\n */\n getMask() {\n if (this._bufferedBytes < 4) {\n this._loop = false;\n return;\n }\n\n this._mask = this.consume(4);\n this._state = GET_DATA;\n }\n\n /**\n * Reads data bytes.\n *\n * @param {Function} cb Callback\n * @private\n */\n getData(cb) {\n let data = EMPTY_BUFFER;\n\n if (this._payloadLength) {\n if (this._bufferedBytes < this._payloadLength) {\n this._loop = false;\n return;\n }\n\n data = this.consume(this._payloadLength);\n\n if (\n this._masked &&\n (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0\n ) {\n unmask(data, this._mask);\n }\n }\n\n if (this._opcode > 0x07) {\n this.controlMessage(data, cb);\n return;\n }\n\n if (this._compressed) {\n this._state = INFLATING;\n this.decompress(data, cb);\n return;\n }\n\n if (data.length) {\n //\n // This message is not compressed so its length is the sum of the payload\n // length of all fragments.\n //\n this._messageLength = this._totalPayloadLength;\n this._fragments.push(data);\n }\n\n this.dataMessage(cb);\n }\n\n /**\n * Decompresses data.\n *\n * @param {Buffer} data Compressed data\n * @param {Function} cb Callback\n * @private\n */\n decompress(data, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n perMessageDeflate.decompress(data, this._fin, (err, buf) => {\n if (err) return cb(err);\n\n if (buf.length) {\n this._messageLength += buf.length;\n if (this._messageLength > this._maxPayload && this._maxPayload > 0) {\n const error = this.createError(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n\n cb(error);\n return;\n }\n\n this._fragments.push(buf);\n }\n\n this.dataMessage(cb);\n if (this._state === GET_INFO) this.startLoop(cb);\n });\n }\n\n /**\n * Handles a data message.\n *\n * @param {Function} cb Callback\n * @private\n */\n dataMessage(cb) {\n if (!this._fin) {\n this._state = GET_INFO;\n return;\n }\n\n const messageLength = this._messageLength;\n const fragments = this._fragments;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragmented = 0;\n this._fragments = [];\n\n if (this._opcode === 2) {\n let data;\n\n if (this._binaryType === 'nodebuffer') {\n data = concat(fragments, messageLength);\n } else if (this._binaryType === 'arraybuffer') {\n data = toArrayBuffer(concat(fragments, messageLength));\n } else if (this._binaryType === 'blob') {\n data = new Blob(fragments);\n } else {\n data = fragments;\n }\n\n if (this._allowSynchronousEvents) {\n this.emit('message', data, true);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit('message', data, true);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n } else {\n const buf = concat(fragments, messageLength);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n const error = this.createError(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n\n cb(error);\n return;\n }\n\n if (this._state === INFLATING || this._allowSynchronousEvents) {\n this.emit('message', buf, false);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit('message', buf, false);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n }\n }\n\n /**\n * Handles a control message.\n *\n * @param {Buffer} data Data to handle\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n controlMessage(data, cb) {\n if (this._opcode === 0x08) {\n if (data.length === 0) {\n this._loop = false;\n this.emit('conclude', 1005, EMPTY_BUFFER);\n this.end();\n } else {\n const code = data.readUInt16BE(0);\n\n if (!isValidStatusCode(code)) {\n const error = this.createError(\n RangeError,\n `invalid status code ${code}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CLOSE_CODE'\n );\n\n cb(error);\n return;\n }\n\n const buf = new FastBuffer(\n data.buffer,\n data.byteOffset + 2,\n data.length - 2\n );\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n const error = this.createError(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n\n cb(error);\n return;\n }\n\n this._loop = false;\n this.emit('conclude', code, buf);\n this.end();\n }\n\n this._state = GET_INFO;\n return;\n }\n\n if (this._allowSynchronousEvents) {\n this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n }\n\n /**\n * Builds an error object.\n *\n * @param {function(new:Error|RangeError)} ErrorCtor The error constructor\n * @param {String} message The error message\n * @param {Boolean} prefix Specifies whether or not to add a default prefix to\n * `message`\n * @param {Number} statusCode The status code\n * @param {String} errorCode The exposed error code\n * @return {(Error|RangeError)} The error\n * @private\n */\n createError(ErrorCtor, message, prefix, statusCode, errorCode) {\n this._loop = false;\n this._errored = true;\n\n const err = new ErrorCtor(\n prefix ? `Invalid WebSocket frame: ${message}` : message\n );\n\n Error.captureStackTrace(err, this.createError);\n err.code = errorCode;\n err[kStatusCode] = statusCode;\n return err;\n }\n}\n\nmodule.exports = Receiver;\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex\" }] */\n\n'use strict';\n\nconst { Duplex } = require('stream');\nconst { randomFillSync } = require('crypto');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst { EMPTY_BUFFER, kWebSocket, NOOP } = require('./constants');\nconst { isBlob, isValidStatusCode } = require('./validation');\nconst { mask: applyMask, toBuffer } = require('./buffer-util');\n\nconst kByteLength = Symbol('kByteLength');\nconst maskBuffer = Buffer.alloc(4);\nconst RANDOM_POOL_SIZE = 8 * 1024;\nlet randomPool;\nlet randomPoolPointer = RANDOM_POOL_SIZE;\n\nconst DEFAULT = 0;\nconst DEFLATING = 1;\nconst GET_BLOB_DATA = 2;\n\n/**\n * HyBi Sender implementation.\n */\nclass Sender {\n /**\n * Creates a Sender instance.\n *\n * @param {Duplex} socket The connection socket\n * @param {Object} [extensions] An object containing the negotiated extensions\n * @param {Function} [generateMask] The function used to generate the masking\n * key\n */\n constructor(socket, extensions, generateMask) {\n this._extensions = extensions || {};\n\n if (generateMask) {\n this._generateMask = generateMask;\n this._maskBuffer = Buffer.alloc(4);\n }\n\n this._socket = socket;\n\n this._firstFragment = true;\n this._compress = false;\n\n this._bufferedBytes = 0;\n this._queue = [];\n this._state = DEFAULT;\n this.onerror = NOOP;\n this[kWebSocket] = undefined;\n }\n\n /**\n * Frames a piece of data according to the HyBi WebSocket protocol.\n *\n * @param {(Buffer|String)} data The data to frame\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @return {(Buffer|String)[]} The framed data\n * @public\n */\n static frame(data, options) {\n let mask;\n let merge = false;\n let offset = 2;\n let skipMasking = false;\n\n if (options.mask) {\n mask = options.maskBuffer || maskBuffer;\n\n if (options.generateMask) {\n options.generateMask(mask);\n } else {\n if (randomPoolPointer === RANDOM_POOL_SIZE) {\n /* istanbul ignore else */\n if (randomPool === undefined) {\n //\n // This is lazily initialized because server-sent frames must not\n // be masked so it may never be used.\n //\n randomPool = Buffer.alloc(RANDOM_POOL_SIZE);\n }\n\n randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);\n randomPoolPointer = 0;\n }\n\n mask[0] = randomPool[randomPoolPointer++];\n mask[1] = randomPool[randomPoolPointer++];\n mask[2] = randomPool[randomPoolPointer++];\n mask[3] = randomPool[randomPoolPointer++];\n }\n\n skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;\n offset = 6;\n }\n\n let dataLength;\n\n if (typeof data === 'string') {\n if (\n (!options.mask || skipMasking) &&\n options[kByteLength] !== undefined\n ) {\n dataLength = options[kByteLength];\n } else {\n data = Buffer.from(data);\n dataLength = data.length;\n }\n } else {\n dataLength = data.length;\n merge = options.mask && options.readOnly && !skipMasking;\n }\n\n let payloadLength = dataLength;\n\n if (dataLength >= 65536) {\n offset += 8;\n payloadLength = 127;\n } else if (dataLength > 125) {\n offset += 2;\n payloadLength = 126;\n }\n\n const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);\n\n target[0] = options.fin ? options.opcode | 0x80 : options.opcode;\n if (options.rsv1) target[0] |= 0x40;\n\n target[1] = payloadLength;\n\n if (payloadLength === 126) {\n target.writeUInt16BE(dataLength, 2);\n } else if (payloadLength === 127) {\n target[2] = target[3] = 0;\n target.writeUIntBE(dataLength, 4, 6);\n }\n\n if (!options.mask) return [target, data];\n\n target[1] |= 0x80;\n target[offset - 4] = mask[0];\n target[offset - 3] = mask[1];\n target[offset - 2] = mask[2];\n target[offset - 1] = mask[3];\n\n if (skipMasking) return [target, data];\n\n if (merge) {\n applyMask(data, mask, target, offset, dataLength);\n return [target];\n }\n\n applyMask(data, mask, data, 0, dataLength);\n return [target, data];\n }\n\n /**\n * Sends a close message to the other peer.\n *\n * @param {Number} [code] The status code component of the body\n * @param {(String|Buffer)} [data] The message component of the body\n * @param {Boolean} [mask=false] Specifies whether or not to mask the message\n * @param {Function} [cb] Callback\n * @public\n */\n close(code, data, mask, cb) {\n let buf;\n\n if (code === undefined) {\n buf = EMPTY_BUFFER;\n } else if (typeof code !== 'number' || !isValidStatusCode(code)) {\n throw new TypeError('First argument must be a valid error code number');\n } else if (data === undefined || !data.length) {\n buf = Buffer.allocUnsafe(2);\n buf.writeUInt16BE(code, 0);\n } else {\n const length = Buffer.byteLength(data);\n\n if (length > 123) {\n throw new RangeError('The message must not be greater than 123 bytes');\n }\n\n buf = Buffer.allocUnsafe(2 + length);\n buf.writeUInt16BE(code, 0);\n\n if (typeof data === 'string') {\n buf.write(data, 2);\n } else {\n buf.set(data, 2);\n }\n }\n\n const options = {\n [kByteLength]: buf.length,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x08,\n readOnly: false,\n rsv1: false\n };\n\n if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, buf, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(buf, options), cb);\n }\n }\n\n /**\n * Sends a ping message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n ping(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x09,\n readOnly,\n rsv1: false\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, false, options, cb]);\n } else {\n this.getBlobData(data, false, options, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a pong message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n pong(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x0a,\n readOnly,\n rsv1: false\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, false, options, cb]);\n } else {\n this.getBlobData(data, false, options, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a data message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Object} options Options object\n * @param {Boolean} [options.binary=false] Specifies whether `data` is binary\n * or text\n * @param {Boolean} [options.compress=false] Specifies whether or not to\n * compress `data`\n * @param {Boolean} [options.fin=false] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Function} [cb] Callback\n * @public\n */\n send(data, options, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n let opcode = options.binary ? 2 : 1;\n let rsv1 = options.compress;\n\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (this._firstFragment) {\n this._firstFragment = false;\n if (\n rsv1 &&\n perMessageDeflate &&\n perMessageDeflate.params[\n perMessageDeflate._isServer\n ? 'server_no_context_takeover'\n : 'client_no_context_takeover'\n ]\n ) {\n rsv1 = byteLength >= perMessageDeflate._threshold;\n }\n this._compress = rsv1;\n } else {\n rsv1 = false;\n opcode = 0;\n }\n\n if (options.fin) this._firstFragment = true;\n\n const opts = {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, this._compress, opts, cb]);\n } else {\n this.getBlobData(data, this._compress, opts, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, this._compress, opts, cb]);\n } else {\n this.dispatch(data, this._compress, opts, cb);\n }\n }\n\n /**\n * Gets the contents of a blob as binary data.\n *\n * @param {Blob} blob The blob\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * the data\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n getBlobData(blob, compress, options, cb) {\n this._bufferedBytes += options[kByteLength];\n this._state = GET_BLOB_DATA;\n\n blob\n .arrayBuffer()\n .then((arrayBuffer) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while the blob was being read'\n );\n\n //\n // `callCallbacks` is called in the next tick to ensure that errors\n // that might be thrown in the callbacks behave like errors thrown\n // outside the promise chain.\n //\n process.nextTick(callCallbacks, this, err, cb);\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n const data = toBuffer(arrayBuffer);\n\n if (!compress) {\n this._state = DEFAULT;\n this.sendFrame(Sender.frame(data, options), cb);\n this.dequeue();\n } else {\n this.dispatch(data, compress, options, cb);\n }\n })\n .catch((err) => {\n //\n // `onError` is called in the next tick for the same reason that\n // `callCallbacks` above is.\n //\n process.nextTick(onError, this, err, cb);\n });\n }\n\n /**\n * Dispatches a message.\n *\n * @param {(Buffer|String)} data The message to send\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * `data`\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n dispatch(data, compress, options, cb) {\n if (!compress) {\n this.sendFrame(Sender.frame(data, options), cb);\n return;\n }\n\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n this._bufferedBytes += options[kByteLength];\n this._state = DEFLATING;\n perMessageDeflate.compress(data, options.fin, (_, buf) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while data was being compressed'\n );\n\n callCallbacks(this, err, cb);\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n this._state = DEFAULT;\n options.readOnly = false;\n this.sendFrame(Sender.frame(buf, options), cb);\n this.dequeue();\n });\n }\n\n /**\n * Executes queued send operations.\n *\n * @private\n */\n dequeue() {\n while (this._state === DEFAULT && this._queue.length) {\n const params = this._queue.shift();\n\n this._bufferedBytes -= params[3][kByteLength];\n Reflect.apply(params[0], this, params.slice(1));\n }\n }\n\n /**\n * Enqueues a send operation.\n *\n * @param {Array} params Send operation parameters.\n * @private\n */\n enqueue(params) {\n this._bufferedBytes += params[3][kByteLength];\n this._queue.push(params);\n }\n\n /**\n * Sends a frame.\n *\n * @param {(Buffer | String)[]} list The frame to send\n * @param {Function} [cb] Callback\n * @private\n */\n sendFrame(list, cb) {\n if (list.length === 2) {\n this._socket.cork();\n this._socket.write(list[0]);\n this._socket.write(list[1], cb);\n this._socket.uncork();\n } else {\n this._socket.write(list[0], cb);\n }\n }\n}\n\nmodule.exports = Sender;\n\n/**\n * Calls queued callbacks with an error.\n *\n * @param {Sender} sender The `Sender` instance\n * @param {Error} err The error to call the callbacks with\n * @param {Function} [cb] The first callback\n * @private\n */\nfunction callCallbacks(sender, err, cb) {\n if (typeof cb === 'function') cb(err);\n\n for (let i = 0; i < sender._queue.length; i++) {\n const params = sender._queue[i];\n const callback = params[params.length - 1];\n\n if (typeof callback === 'function') callback(err);\n }\n}\n\n/**\n * Handles a `Sender` error.\n *\n * @param {Sender} sender The `Sender` instance\n * @param {Error} err The error\n * @param {Function} [cb] The first pending callback\n * @private\n */\nfunction onError(sender, err, cb) {\n callCallbacks(sender, err, cb);\n sender.onerror(err);\n}\n","'use strict';\n\nconst { kForOnEventAttribute, kListener } = require('./constants');\n\nconst kCode = Symbol('kCode');\nconst kData = Symbol('kData');\nconst kError = Symbol('kError');\nconst kMessage = Symbol('kMessage');\nconst kReason = Symbol('kReason');\nconst kTarget = Symbol('kTarget');\nconst kType = Symbol('kType');\nconst kWasClean = Symbol('kWasClean');\n\n/**\n * Class representing an event.\n */\nclass Event {\n /**\n * Create a new `Event`.\n *\n * @param {String} type The name of the event\n * @throws {TypeError} If the `type` argument is not specified\n */\n constructor(type) {\n this[kTarget] = null;\n this[kType] = type;\n }\n\n /**\n * @type {*}\n */\n get target() {\n return this[kTarget];\n }\n\n /**\n * @type {String}\n */\n get type() {\n return this[kType];\n }\n}\n\nObject.defineProperty(Event.prototype, 'target', { enumerable: true });\nObject.defineProperty(Event.prototype, 'type', { enumerable: true });\n\n/**\n * Class representing a close event.\n *\n * @extends Event\n */\nclass CloseEvent extends Event {\n /**\n * Create a new `CloseEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {Number} [options.code=0] The status code explaining why the\n * connection was closed\n * @param {String} [options.reason=''] A human-readable string explaining why\n * the connection was closed\n * @param {Boolean} [options.wasClean=false] Indicates whether or not the\n * connection was cleanly closed\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kCode] = options.code === undefined ? 0 : options.code;\n this[kReason] = options.reason === undefined ? '' : options.reason;\n this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;\n }\n\n /**\n * @type {Number}\n */\n get code() {\n return this[kCode];\n }\n\n /**\n * @type {String}\n */\n get reason() {\n return this[kReason];\n }\n\n /**\n * @type {Boolean}\n */\n get wasClean() {\n return this[kWasClean];\n }\n}\n\nObject.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });\n\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent extends Event {\n /**\n * Create a new `ErrorEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.error=null] The error that generated this event\n * @param {String} [options.message=''] The error message\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kError] = options.error === undefined ? null : options.error;\n this[kMessage] = options.message === undefined ? '' : options.message;\n }\n\n /**\n * @type {*}\n */\n get error() {\n return this[kError];\n }\n\n /**\n * @type {String}\n */\n get message() {\n return this[kMessage];\n }\n}\n\nObject.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });\n\n/**\n * Class representing a message event.\n *\n * @extends Event\n */\nclass MessageEvent extends Event {\n /**\n * Create a new `MessageEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.data=null] The message content\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kData] = options.data === undefined ? null : options.data;\n }\n\n /**\n * @type {*}\n */\n get data() {\n return this[kData];\n }\n}\n\nObject.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });\n\n/**\n * This provides methods for emulating the `EventTarget` interface. It's not\n * meant to be used directly.\n *\n * @mixin\n */\nconst EventTarget = {\n /**\n * Register an event listener.\n *\n * @param {String} type A string representing the event type to listen for\n * @param {(Function|Object)} handler The listener to add\n * @param {Object} [options] An options object specifies characteristics about\n * the event listener\n * @param {Boolean} [options.once=false] A `Boolean` indicating that the\n * listener should be invoked at most once after being added. If `true`,\n * the listener would be automatically removed when invoked.\n * @public\n */\n addEventListener(type, handler, options = {}) {\n for (const listener of this.listeners(type)) {\n if (\n !options[kForOnEventAttribute] &&\n listener[kListener] === handler &&\n !listener[kForOnEventAttribute]\n ) {\n return;\n }\n }\n\n let wrapper;\n\n if (type === 'message') {\n wrapper = function onMessage(data, isBinary) {\n const event = new MessageEvent('message', {\n data: isBinary ? data : data.toString()\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'close') {\n wrapper = function onClose(code, message) {\n const event = new CloseEvent('close', {\n code,\n reason: message.toString(),\n wasClean: this._closeFrameReceived && this._closeFrameSent\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'error') {\n wrapper = function onError(error) {\n const event = new ErrorEvent('error', {\n error,\n message: error.message\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'open') {\n wrapper = function onOpen() {\n const event = new Event('open');\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else {\n return;\n }\n\n wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];\n wrapper[kListener] = handler;\n\n if (options.once) {\n this.once(type, wrapper);\n } else {\n this.on(type, wrapper);\n }\n },\n\n /**\n * Remove an event listener.\n *\n * @param {String} type A string representing the event type to remove\n * @param {(Function|Object)} handler The listener to remove\n * @public\n */\n removeEventListener(type, handler) {\n for (const listener of this.listeners(type)) {\n if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {\n this.removeListener(type, listener);\n break;\n }\n }\n }\n};\n\nmodule.exports = {\n CloseEvent,\n ErrorEvent,\n Event,\n EventTarget,\n MessageEvent\n};\n\n/**\n * Call an event listener\n *\n * @param {(Function|Object)} listener The listener to call\n * @param {*} thisArg The value to use as `this`` when calling the listener\n * @param {Event} event The event to pass to the listener\n * @private\n */\nfunction callListener(listener, thisArg, event) {\n if (typeof listener === 'object' && listener.handleEvent) {\n listener.handleEvent.call(listener, event);\n } else {\n listener.call(thisArg, event);\n }\n}\n","'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Adds an offer to the map of extension offers or a parameter to the map of\n * parameters.\n *\n * @param {Object} dest The map of extension offers or parameters\n * @param {String} name The extension or parameter name\n * @param {(Object|Boolean|String)} elem The extension parameters or the\n * parameter value\n * @private\n */\nfunction push(dest, name, elem) {\n if (dest[name] === undefined) dest[name] = [elem];\n else dest[name].push(elem);\n}\n\n/**\n * Parses the `Sec-WebSocket-Extensions` header into an object.\n *\n * @param {String} header The field value of the header\n * @return {Object} The parsed object\n * @public\n */\nfunction parse(header) {\n const offers = Object.create(null);\n let params = Object.create(null);\n let mustUnescape = false;\n let isEscaping = false;\n let inQuotes = false;\n let extensionName;\n let paramName;\n let start = -1;\n let code = -1;\n let end = -1;\n let i = 0;\n\n for (; i < header.length; i++) {\n code = header.charCodeAt(i);\n\n if (extensionName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n const name = header.slice(start, end);\n if (code === 0x2c) {\n push(offers, name, params);\n params = Object.create(null);\n } else {\n extensionName = name;\n }\n\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (paramName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x20 || code === 0x09) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n push(params, header.slice(start, end), true);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n start = end = -1;\n } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {\n paramName = header.slice(start, i);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else {\n //\n // The value of a quoted-string after unescaping must conform to the\n // token ABNF, so only token characters are valid.\n // Ref: https://tools.ietf.org/html/rfc6455#section-9.1\n //\n if (isEscaping) {\n if (tokenChars[code] !== 1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n if (start === -1) start = i;\n else if (!mustUnescape) mustUnescape = true;\n isEscaping = false;\n } else if (inQuotes) {\n if (tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x22 /* '\"' */ && start !== -1) {\n inQuotes = false;\n end = i;\n } else if (code === 0x5c /* '\\' */) {\n isEscaping = true;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {\n inQuotes = true;\n } else if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (start !== -1 && (code === 0x20 || code === 0x09)) {\n if (end === -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n let value = header.slice(start, end);\n if (mustUnescape) {\n value = value.replace(/\\\\/g, '');\n mustUnescape = false;\n }\n push(params, paramName, value);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n paramName = undefined;\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n }\n\n if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n if (end === -1) end = i;\n const token = header.slice(start, end);\n if (extensionName === undefined) {\n push(offers, token, params);\n } else {\n if (paramName === undefined) {\n push(params, token, true);\n } else if (mustUnescape) {\n push(params, paramName, token.replace(/\\\\/g, ''));\n } else {\n push(params, paramName, token);\n }\n push(offers, extensionName, params);\n }\n\n return offers;\n}\n\n/**\n * Builds the `Sec-WebSocket-Extensions` header field value.\n *\n * @param {Object} extensions The map of extensions and parameters to format\n * @return {String} A string representing the given object\n * @public\n */\nfunction format(extensions) {\n return Object.keys(extensions)\n .map((extension) => {\n let configurations = extensions[extension];\n if (!Array.isArray(configurations)) configurations = [configurations];\n return configurations\n .map((params) => {\n return [extension]\n .concat(\n Object.keys(params).map((k) => {\n let values = params[k];\n if (!Array.isArray(values)) values = [values];\n return values\n .map((v) => (v === true ? k : `${k}=${v}`))\n .join('; ');\n })\n )\n .join('; ');\n })\n .join(', ');\n })\n .join(', ');\n}\n\nmodule.exports = { format, parse };\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex|Readable$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst { randomBytes, createHash } = require('crypto');\nconst { Duplex, Readable } = require('stream');\nconst { URL } = require('url');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst { isBlob } = require('./validation');\n\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: { addEventListener, removeEventListener }\n} = require('./event-target');\nconst { format, parse } = require('./extension');\nconst { toBuffer } = require('./buffer-util');\n\nconst closeTimeout = 30 * 1000;\nconst kAborted = Symbol('kAborted');\nconst protocolVersions = [8, 13];\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._errorEmitted = false;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n\n initAsClient(this, address, protocols, options);\n } else {\n this._autoPong = options.autoPong;\n this._isServer = true;\n }\n }\n\n /**\n * For historical reasons, the custom \"nodebuffer\" type is used by the default\n * instead of \"blob\".\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n allowSynchronousEvents: options.allowSynchronousEvents,\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n\n const sender = new Sender(socket, this._extensions, options.generateMask);\n\n this._receiver = receiver;\n this._sender = sender;\n this._socket = socket;\n\n receiver[kWebSocket] = this;\n sender[kWebSocket] = this;\n socket[kWebSocket] = this;\n\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n\n sender.onerror = senderOnError;\n\n //\n // These methods may not be available if `socket` is just a `Duplex`.\n //\n if (socket.setTimeout) socket.setTimeout(0);\n if (socket.setNoDelay) socket.setNoDelay();\n\n if (head.length > 0) socket.unshift(head);\n\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this.readyState === WebSocket.CLOSING) {\n if (\n this._closeFrameSent &&\n (this._closeFrameReceived || this._receiver._writableState.errorEmitted)\n ) {\n this._socket.end();\n }\n\n return;\n }\n\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, (err) => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n\n this._closeFrameSent = true;\n\n if (\n this._closeFrameReceived ||\n this._receiver._writableState.errorEmitted\n ) {\n this._socket.end();\n }\n });\n\n setCloseTimer(this);\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n[\n 'binaryType',\n 'bufferedAmount',\n 'extensions',\n 'isPaused',\n 'protocol',\n 'readyState',\n 'url'\n].forEach((property) => {\n Object.defineProperty(WebSocket.prototype, property, { enumerable: true });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach((method) => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n\n if (typeof handler !== 'function') return;\n\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\n\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\n\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any\n * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple\n * times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Function} [options.finishRequest] A function which can be used to\n * customize the headers of each http request before it is sent\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n allowSynchronousEvents: true,\n autoPong: true,\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: 'GET',\n host: undefined,\n path: undefined,\n port: undefined\n };\n\n websocket._autoPong = opts.autoPong;\n\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(\n `Unsupported protocol version: ${opts.protocolVersion} ` +\n `(supported versions: ${protocolVersions.join(', ')})`\n );\n }\n\n let parsedUrl;\n\n if (address instanceof URL) {\n parsedUrl = address;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n }\n\n if (parsedUrl.protocol === 'http:') {\n parsedUrl.protocol = 'ws:';\n } else if (parsedUrl.protocol === 'https:') {\n parsedUrl.protocol = 'wss:';\n }\n\n websocket._url = parsedUrl.href;\n\n const isSecure = parsedUrl.protocol === 'wss:';\n const isIpcUrl = parsedUrl.protocol === 'ws+unix:';\n let invalidUrlMessage;\n\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {\n invalidUrlMessage =\n 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", ' +\n '\"http:\", \"https:\", or \"ws+unix:\"';\n } else if (isIpcUrl && !parsedUrl.pathname) {\n invalidUrlMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidUrlMessage = 'The URL contains a fragment identifier';\n }\n\n if (invalidUrlMessage) {\n const err = new SyntaxError(invalidUrlMessage);\n\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const request = isSecure ? https.request : http.request;\n const protocolSet = new Set();\n let perMessageDeflate;\n\n opts.createConnection =\n opts.createConnection || (isSecure ? tlsConnect : netConnect);\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[')\n ? parsedUrl.hostname.slice(1, -1)\n : parsedUrl.hostname;\n opts.headers = {\n ...opts.headers,\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket'\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(\n opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},\n false,\n opts.maxPayload\n );\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (\n typeof protocol !== 'string' ||\n !subprotocolRegex.test(protocol) ||\n protocolSet.has(protocol)\n ) {\n throw new SyntaxError(\n 'An invalid or duplicated subprotocol was specified'\n );\n }\n\n protocolSet.add(protocol);\n }\n\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n\n if (isIpcUrl) {\n const parts = opts.path.split(':');\n\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n\n let req;\n\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalIpc = isIpcUrl;\n websocket._originalSecure = isSecure;\n websocket._originalHostOrSocketPath = isIpcUrl\n ? opts.socketPath\n : parsedUrl.host;\n\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = { ...options, headers: {} };\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (websocket.listenerCount('redirect') === 0) {\n const isSameHost = isIpcUrl\n ? websocket._originalIpc\n ? opts.socketPath === websocket._originalHostOrSocketPath\n : false\n : websocket._originalIpc\n ? false\n : parsedUrl.host === websocket._originalHostOrSocketPath;\n\n if (!isSameHost || (websocket._originalSecure && !isSecure)) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n\n if (!isSameHost) delete opts.headers.host;\n\n opts.auth = undefined;\n }\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization =\n 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n\n req = websocket._req = request(opts);\n\n if (websocket._redirects) {\n //\n // Unlike what is done for the `'upgrade'` event, no early exit is\n // triggered here if the user calls `websocket.close()` or\n // `websocket.terminate()` from a listener of the `'redirect'` event. This\n // is because the user can also call `request.destroy()` with an error\n // before calling `websocket.close()` or `websocket.terminate()` and this\n // would result in an error being emitted on the `request` object with no\n // `'error'` event listeners attached.\n //\n websocket.emit('redirect', websocket.url, req);\n }\n } else {\n req = websocket._req = request(opts);\n }\n\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n\n req.on('error', (err) => {\n if (req === null || req[kAborted]) return;\n\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n\n req.on('response', (res) => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n\n if (\n location &&\n opts.followRedirects &&\n statusCode >= 300 &&\n statusCode < 400\n ) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n\n req.abort();\n\n let addr;\n\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(\n websocket,\n req,\n `Unexpected server response: ${res.statusCode}`\n );\n }\n });\n\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the\n // `'upgrade'` event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n\n req = websocket._req = null;\n\n const upgrade = res.headers.upgrade;\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n abortHandshake(websocket, socket, 'Invalid Upgrade header');\n return;\n }\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n\n if (serverProt) websocket._protocol = serverProt;\n\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message =\n 'Server sent a Sec-WebSocket-Extensions header but no extension ' +\n 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n let extensions;\n\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n const extensionNames = Object.keys(extensions);\n\n if (\n extensionNames.length !== 1 ||\n extensionNames[0] !== PerMessageDeflate.extensionName\n ) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n websocket._extensions[PerMessageDeflate.extensionName] =\n perMessageDeflate;\n }\n\n websocket.setSocket(socket, head, {\n allowSynchronousEvents: opts.allowSynchronousEvents,\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n\n if (opts.finishRequest) {\n opts.finishRequest(req, websocket);\n } else {\n req.end();\n }\n}\n\n/**\n * Emit the `'error'` and `'close'` events.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n //\n // The following assignment is practically useless and is done only for\n // consistency.\n //\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n\n if (stream.setHeader) {\n stream[kAborted] = true;\n stream.abort();\n\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n\n process.nextTick(emitErrorAndClose, websocket, err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = isBlob(data) ? data.size : toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;\n else websocket._bufferedAmount += length;\n }\n\n if (cb) {\n const err = new Error(\n `WebSocket is not open: readyState ${websocket.readyState} ` +\n `(${readyStates[websocket.readyState]})`\n );\n process.nextTick(cb, err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n\n if (websocket._socket[kWebSocket] === undefined) return;\n\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n\n if (code === 1005) websocket.close();\n else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n\n websocket.close(err[kStatusCode]);\n }\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n\n if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The `Sender` error event handler.\n *\n * @param {Error} The error\n * @private\n */\nfunction senderOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket.readyState === WebSocket.CLOSED) return;\n if (websocket.readyState === WebSocket.OPEN) {\n websocket._readyState = WebSocket.CLOSING;\n setCloseTimer(websocket);\n }\n\n //\n // `socket.end()` is used instead of `socket.destroy()` to allow the other\n // peer to finish sending queued data. There is no need to set a timer here\n // because `CLOSING` means that it is already set or not needed.\n //\n this._socket.end();\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * Set a timer to destroy the underlying raw socket of a WebSocket.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @private\n */\nfunction setCloseTimer(websocket) {\n websocket._closeTimer = setTimeout(\n websocket._socket.destroy.bind(websocket._socket),\n closeTimeout\n );\n}\n\n/**\n * The listener of the socket `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n\n websocket._readyState = WebSocket.CLOSING;\n\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (\n !this._readableState.endEmitted &&\n !websocket._closeFrameReceived &&\n !websocket._receiver._writableState.errorEmitted &&\n (chunk = websocket._socket.read()) !== null\n ) {\n websocket._receiver.write(chunk);\n }\n\n websocket._receiver.end();\n\n this[kWebSocket] = undefined;\n\n clearTimeout(websocket._closeTimer);\n\n if (\n websocket._receiver._writableState.finished ||\n websocket._receiver._writableState.errorEmitted\n ) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the socket `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the socket `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the socket `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^WebSocket$\" }] */\n'use strict';\n\nconst WebSocket = require('./websocket');\nconst { Duplex } = require('stream');\n\n/**\n * Emits the `'close'` event on a stream.\n *\n * @param {Duplex} stream The stream.\n * @private\n */\nfunction emitClose(stream) {\n stream.emit('close');\n}\n\n/**\n * The listener of the `'end'` event.\n *\n * @private\n */\nfunction duplexOnEnd() {\n if (!this.destroyed && this._writableState.finished) {\n this.destroy();\n }\n}\n\n/**\n * The listener of the `'error'` event.\n *\n * @param {Error} err The error\n * @private\n */\nfunction duplexOnError(err) {\n this.removeListener('error', duplexOnError);\n this.destroy();\n if (this.listenerCount('error') === 0) {\n // Do not suppress the throwing behavior.\n this.emit('error', err);\n }\n}\n\n/**\n * Wraps a `WebSocket` in a duplex stream.\n *\n * @param {WebSocket} ws The `WebSocket` to wrap\n * @param {Object} [options] The options for the `Duplex` constructor\n * @return {Duplex} The duplex stream\n * @public\n */\nfunction createWebSocketStream(ws, options) {\n let terminateOnDestroy = true;\n\n const duplex = new Duplex({\n ...options,\n autoDestroy: false,\n emitClose: false,\n objectMode: false,\n writableObjectMode: false\n });\n\n ws.on('message', function message(msg, isBinary) {\n const data =\n !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;\n\n if (!duplex.push(data)) ws.pause();\n });\n\n ws.once('error', function error(err) {\n if (duplex.destroyed) return;\n\n // Prevent `ws.terminate()` from being called by `duplex._destroy()`.\n //\n // - If the `'error'` event is emitted before the `'open'` event, then\n // `ws.terminate()` is a noop as no socket is assigned.\n // - Otherwise, the error is re-emitted by the listener of the `'error'`\n // event of the `Receiver` object. The listener already closes the\n // connection by calling `ws.close()`. This allows a close frame to be\n // sent to the other peer. If `ws.terminate()` is called right after this,\n // then the close frame might not be sent.\n terminateOnDestroy = false;\n duplex.destroy(err);\n });\n\n ws.once('close', function close() {\n if (duplex.destroyed) return;\n\n duplex.push(null);\n });\n\n duplex._destroy = function (err, callback) {\n if (ws.readyState === ws.CLOSED) {\n callback(err);\n process.nextTick(emitClose, duplex);\n return;\n }\n\n let called = false;\n\n ws.once('error', function error(err) {\n called = true;\n callback(err);\n });\n\n ws.once('close', function close() {\n if (!called) callback(err);\n process.nextTick(emitClose, duplex);\n });\n\n if (terminateOnDestroy) ws.terminate();\n };\n\n duplex._final = function (callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._final(callback);\n });\n return;\n }\n\n // If the value of the `_socket` property is `null` it means that `ws` is a\n // client websocket and the handshake failed. In fact, when this happens, a\n // socket is never assigned to the websocket. Wait for the `'error'` event\n // that will be emitted by the websocket.\n if (ws._socket === null) return;\n\n if (ws._socket._writableState.finished) {\n callback();\n if (duplex._readableState.endEmitted) duplex.destroy();\n } else {\n ws._socket.once('finish', function finish() {\n // `duplex` is not destroyed here because the `'end'` event will be\n // emitted on `duplex` after this `'finish'` event. The EOF signaling\n // `null` chunk is, in fact, pushed when the websocket emits `'close'`.\n callback();\n });\n ws.close();\n }\n };\n\n duplex._read = function () {\n if (ws.isPaused) ws.resume();\n };\n\n duplex._write = function (chunk, encoding, callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._write(chunk, encoding, callback);\n });\n return;\n }\n\n ws.send(chunk, callback);\n };\n\n duplex.on('end', duplexOnEnd);\n duplex.on('error', duplexOnError);\n return duplex;\n}\n\nmodule.exports = createWebSocketStream;\n","'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.\n *\n * @param {String} header The field value of the header\n * @return {Set} The subprotocol names\n * @public\n */\nfunction parse(header) {\n const protocols = new Set();\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (i; i < header.length; i++) {\n const code = header.charCodeAt(i);\n\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n\n const protocol = header.slice(start, end);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n\n if (start === -1 || end !== -1) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n const protocol = header.slice(start, i);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n return protocols;\n}\n\nmodule.exports = { parse };\n","/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst http = require('http');\nconst { Duplex } = require('stream');\nconst { createHash } = require('crypto');\n\nconst extension = require('./extension');\nconst PerMessageDeflate = require('./permessage-deflate');\nconst subprotocol = require('./subprotocol');\nconst WebSocket = require('./websocket');\nconst { GUID, kWebSocket } = require('./constants');\n\nconst keyRegex = /^[+/0-9A-Za-z]{22}==$/;\n\nconst RUNNING = 0;\nconst CLOSING = 1;\nconst CLOSED = 2;\n\n/**\n * Class representing a WebSocket server.\n *\n * @extends EventEmitter\n */\nclass WebSocketServer extends EventEmitter {\n /**\n * Create a `WebSocketServer` instance.\n *\n * @param {Object} options Configuration options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Number} [options.backlog=511] The maximum length of the queue of\n * pending connections\n * @param {Boolean} [options.clientTracking=true] Specifies whether or not to\n * track clients\n * @param {Function} [options.handleProtocols] A hook to handle protocols\n * @param {String} [options.host] The hostname where to bind the server\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Boolean} [options.noServer=false] Enable no server mode\n * @param {String} [options.path] Accept only connections matching this path\n * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable\n * permessage-deflate\n * @param {Number} [options.port] The port where to bind the server\n * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S\n * server to use\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @param {Function} [options.verifyClient] A hook to reject connections\n * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`\n * class to use. It must be the `WebSocket` class or class that extends it\n * @param {Function} [callback] A listener for the `listening` event\n */\n constructor(options, callback) {\n super();\n\n options = {\n allowSynchronousEvents: true,\n autoPong: true,\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: false,\n handleProtocols: null,\n clientTracking: true,\n verifyClient: null,\n noServer: false,\n backlog: null, // use default (511 as implemented in net.js)\n server: null,\n host: null,\n path: null,\n port: null,\n WebSocket,\n ...options\n };\n\n if (\n (options.port == null && !options.server && !options.noServer) ||\n (options.port != null && (options.server || options.noServer)) ||\n (options.server && options.noServer)\n ) {\n throw new TypeError(\n 'One and only one of the \"port\", \"server\", or \"noServer\" options ' +\n 'must be specified'\n );\n }\n\n if (options.port != null) {\n this._server = http.createServer((req, res) => {\n const body = http.STATUS_CODES[426];\n\n res.writeHead(426, {\n 'Content-Length': body.length,\n 'Content-Type': 'text/plain'\n });\n res.end(body);\n });\n this._server.listen(\n options.port,\n options.host,\n options.backlog,\n callback\n );\n } else if (options.server) {\n this._server = options.server;\n }\n\n if (this._server) {\n const emitConnection = this.emit.bind(this, 'connection');\n\n this._removeListeners = addListeners(this._server, {\n listening: this.emit.bind(this, 'listening'),\n error: this.emit.bind(this, 'error'),\n upgrade: (req, socket, head) => {\n this.handleUpgrade(req, socket, head, emitConnection);\n }\n });\n }\n\n if (options.perMessageDeflate === true) options.perMessageDeflate = {};\n if (options.clientTracking) {\n this.clients = new Set();\n this._shouldEmitClose = false;\n }\n\n this.options = options;\n this._state = RUNNING;\n }\n\n /**\n * Returns the bound address, the address family name, and port of the server\n * as reported by the operating system if listening on an IP socket.\n * If the server is listening on a pipe or UNIX domain socket, the name is\n * returned as a string.\n *\n * @return {(Object|String|null)} The address of the server\n * @public\n */\n address() {\n if (this.options.noServer) {\n throw new Error('The server is operating in \"noServer\" mode');\n }\n\n if (!this._server) return null;\n return this._server.address();\n }\n\n /**\n * Stop the server from accepting new connections and emit the `'close'` event\n * when all existing connections are closed.\n *\n * @param {Function} [cb] A one-time listener for the `'close'` event\n * @public\n */\n close(cb) {\n if (this._state === CLOSED) {\n if (cb) {\n this.once('close', () => {\n cb(new Error('The server is not running'));\n });\n }\n\n process.nextTick(emitClose, this);\n return;\n }\n\n if (cb) this.once('close', cb);\n\n if (this._state === CLOSING) return;\n this._state = CLOSING;\n\n if (this.options.noServer || this.options.server) {\n if (this._server) {\n this._removeListeners();\n this._removeListeners = this._server = null;\n }\n\n if (this.clients) {\n if (!this.clients.size) {\n process.nextTick(emitClose, this);\n } else {\n this._shouldEmitClose = true;\n }\n } else {\n process.nextTick(emitClose, this);\n }\n } else {\n const server = this._server;\n\n this._removeListeners();\n this._removeListeners = this._server = null;\n\n //\n // The HTTP/S server was created internally. Close it, and rely on its\n // `'close'` event.\n //\n server.close(() => {\n emitClose(this);\n });\n }\n }\n\n /**\n * See if a given request should be handled by this server instance.\n *\n * @param {http.IncomingMessage} req Request object to inspect\n * @return {Boolean} `true` if the request is valid, else `false`\n * @public\n */\n shouldHandle(req) {\n if (this.options.path) {\n const index = req.url.indexOf('?');\n const pathname = index !== -1 ? req.url.slice(0, index) : req.url;\n\n if (pathname !== this.options.path) return false;\n }\n\n return true;\n }\n\n /**\n * Handle a HTTP Upgrade request.\n *\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @public\n */\n handleUpgrade(req, socket, head, cb) {\n socket.on('error', socketOnError);\n\n const key = req.headers['sec-websocket-key'];\n const upgrade = req.headers.upgrade;\n const version = +req.headers['sec-websocket-version'];\n\n if (req.method !== 'GET') {\n const message = 'Invalid HTTP method';\n abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);\n return;\n }\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n const message = 'Invalid Upgrade header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (key === undefined || !keyRegex.test(key)) {\n const message = 'Missing or invalid Sec-WebSocket-Key header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (version !== 13 && version !== 8) {\n const message = 'Missing or invalid Sec-WebSocket-Version header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {\n 'Sec-WebSocket-Version': '13, 8'\n });\n return;\n }\n\n if (!this.shouldHandle(req)) {\n abortHandshake(socket, 400);\n return;\n }\n\n const secWebSocketProtocol = req.headers['sec-websocket-protocol'];\n let protocols = new Set();\n\n if (secWebSocketProtocol !== undefined) {\n try {\n protocols = subprotocol.parse(secWebSocketProtocol);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Protocol header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n const secWebSocketExtensions = req.headers['sec-websocket-extensions'];\n const extensions = {};\n\n if (\n this.options.perMessageDeflate &&\n secWebSocketExtensions !== undefined\n ) {\n const perMessageDeflate = new PerMessageDeflate(\n this.options.perMessageDeflate,\n true,\n this.options.maxPayload\n );\n\n try {\n const offers = extension.parse(secWebSocketExtensions);\n\n if (offers[PerMessageDeflate.extensionName]) {\n perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);\n extensions[PerMessageDeflate.extensionName] = perMessageDeflate;\n }\n } catch (err) {\n const message =\n 'Invalid or unacceptable Sec-WebSocket-Extensions header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n //\n // Optionally call external client verification handler.\n //\n if (this.options.verifyClient) {\n const info = {\n origin:\n req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],\n secure: !!(req.socket.authorized || req.socket.encrypted),\n req\n };\n\n if (this.options.verifyClient.length === 2) {\n this.options.verifyClient(info, (verified, code, message, headers) => {\n if (!verified) {\n return abortHandshake(socket, code || 401, message, headers);\n }\n\n this.completeUpgrade(\n extensions,\n key,\n protocols,\n req,\n socket,\n head,\n cb\n );\n });\n return;\n }\n\n if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);\n }\n\n this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);\n }\n\n /**\n * Upgrade the connection to WebSocket.\n *\n * @param {Object} extensions The accepted extensions\n * @param {String} key The value of the `Sec-WebSocket-Key` header\n * @param {Set} protocols The subprotocols\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @throws {Error} If called more than once with the same socket\n * @private\n */\n completeUpgrade(extensions, key, protocols, req, socket, head, cb) {\n //\n // Destroy the socket if the client has already sent a FIN packet.\n //\n if (!socket.readable || !socket.writable) return socket.destroy();\n\n if (socket[kWebSocket]) {\n throw new Error(\n 'server.handleUpgrade() was called more than once with the same ' +\n 'socket, possibly due to a misconfiguration'\n );\n }\n\n if (this._state > RUNNING) return abortHandshake(socket, 503);\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n const headers = [\n 'HTTP/1.1 101 Switching Protocols',\n 'Upgrade: websocket',\n 'Connection: Upgrade',\n `Sec-WebSocket-Accept: ${digest}`\n ];\n\n const ws = new this.options.WebSocket(null, undefined, this.options);\n\n if (protocols.size) {\n //\n // Optionally call external protocol selection handler.\n //\n const protocol = this.options.handleProtocols\n ? this.options.handleProtocols(protocols, req)\n : protocols.values().next().value;\n\n if (protocol) {\n headers.push(`Sec-WebSocket-Protocol: ${protocol}`);\n ws._protocol = protocol;\n }\n }\n\n if (extensions[PerMessageDeflate.extensionName]) {\n const params = extensions[PerMessageDeflate.extensionName].params;\n const value = extension.format({\n [PerMessageDeflate.extensionName]: [params]\n });\n headers.push(`Sec-WebSocket-Extensions: ${value}`);\n ws._extensions = extensions;\n }\n\n //\n // Allow external modification/inspection of handshake headers.\n //\n this.emit('headers', headers, req);\n\n socket.write(headers.concat('\\r\\n').join('\\r\\n'));\n socket.removeListener('error', socketOnError);\n\n ws.setSocket(socket, head, {\n allowSynchronousEvents: this.options.allowSynchronousEvents,\n maxPayload: this.options.maxPayload,\n skipUTF8Validation: this.options.skipUTF8Validation\n });\n\n if (this.clients) {\n this.clients.add(ws);\n ws.on('close', () => {\n this.clients.delete(ws);\n\n if (this._shouldEmitClose && !this.clients.size) {\n process.nextTick(emitClose, this);\n }\n });\n }\n\n cb(ws, req);\n }\n}\n\nmodule.exports = WebSocketServer;\n\n/**\n * Add event listeners on an `EventEmitter` using a map of <event, listener>\n * pairs.\n *\n * @param {EventEmitter} server The event emitter\n * @param {Object.<String, Function>} map The listeners to add\n * @return {Function} A function that will remove the added listeners when\n * called\n * @private\n */\nfunction addListeners(server, map) {\n for (const event of Object.keys(map)) server.on(event, map[event]);\n\n return function removeListeners() {\n for (const event of Object.keys(map)) {\n server.removeListener(event, map[event]);\n }\n };\n}\n\n/**\n * Emit a `'close'` event on an `EventEmitter`.\n *\n * @param {EventEmitter} server The event emitter\n * @private\n */\nfunction emitClose(server) {\n server._state = CLOSED;\n server.emit('close');\n}\n\n/**\n * Handle socket errors.\n *\n * @private\n */\nfunction socketOnError() {\n this.destroy();\n}\n\n/**\n * Close the connection when preconditions are not fulfilled.\n *\n * @param {Duplex} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} [message] The HTTP response body\n * @param {Object} [headers] Additional HTTP response headers\n * @private\n */\nfunction abortHandshake(socket, code, message, headers) {\n //\n // The socket is writable unless the user destroyed or ended it before calling\n // `server.handleUpgrade()` or in the `verifyClient` function, which is a user\n // error. Handling this does not make much sense as the worst that can happen\n // is that some of the data written by the user might be discarded due to the\n // call to `socket.end()` below, which triggers an `'error'` event that in\n // turn causes the socket to be destroyed.\n //\n message = message || http.STATUS_CODES[code];\n headers = {\n Connection: 'close',\n 'Content-Type': 'text/html',\n 'Content-Length': Buffer.byteLength(message),\n ...headers\n };\n\n socket.once('finish', socket.destroy);\n\n socket.end(\n `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\\r\\n` +\n Object.keys(headers)\n .map((h) => `${h}: ${headers[h]}`)\n .join('\\r\\n') +\n '\\r\\n\\r\\n' +\n message\n );\n}\n\n/**\n * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least\n * one listener for it, otherwise call `abortHandshake()`.\n *\n * @param {WebSocketServer} server The WebSocket server\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} message The HTTP response body\n * @param {Object} [headers] The HTTP response headers\n * @private\n */\nfunction abortHandshakeOrEmitwsClientError(\n server,\n req,\n socket,\n code,\n message,\n headers\n) {\n if (server.listenerCount('wsClientError')) {\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);\n\n server.emit('wsClientError', err, socket, req);\n } else {\n abortHandshake(socket, code, message, headers);\n }\n}\n","/**\n * Native Messaging Host 入口\n * Chrome 通过 stdin/stdout 与此进程通信\n * 协议: 32位小端长度前缀 + UTF-8 JSON\n */\n\nimport { stdin, stdout } from 'node:process'\nimport { isServerRunning, startServerDaemon, getServerStatus } from '../server/daemon.js'\nimport { encodeMessage, decodeMessage } from './protocol.js'\n\n// ==================== 消息类型 ====================\n\ninterface NativeRequest {\n type: 'ensure_server' | 'get_status' | 'stop_server' | 'ping'\n port?: number\n}\n\ninterface NativeResponse {\n type: string\n success: boolean\n data?: {\n running: boolean\n port?: number\n pid?: number\n startedAt?: string\n uptime?: string\n version?: string\n }\n error?: string\n}\n\n// ==================== 消息处理 ====================\n\nfunction sendMessage(message: NativeResponse): void {\n const encoded = encodeMessage(message)\n stdout.write(encoded)\n}\n\nasync function handleMessage(request: NativeRequest): Promise<void> {\n try {\n switch (request.type) {\n case 'ensure_server': {\n // 确保 Server 运行(幂等操作)\n const { running, info } = isServerRunning()\n if (running && info) {\n sendMessage({\n type: 'server_status',\n success: true,\n data: {\n running: true,\n port: info.port,\n pid: info.pid,\n startedAt: info.startedAt,\n version: info.version,\n },\n })\n } else {\n try {\n const newInfo = await startServerDaemon(request.port)\n sendMessage({\n type: 'server_started',\n success: true,\n data: {\n running: true,\n port: newInfo.port,\n pid: newInfo.pid,\n startedAt: newInfo.startedAt,\n version: newInfo.version,\n },\n })\n } catch (error) {\n sendMessage({\n type: 'error',\n success: false,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n break\n }\n\n case 'get_status': {\n const status = getServerStatus()\n sendMessage({\n type: 'status',\n success: true,\n data: status,\n })\n break\n }\n\n case 'ping': {\n sendMessage({ type: 'pong', success: true })\n break\n }\n\n default:\n sendMessage({\n type: 'error',\n success: false,\n error: `Unknown message type: ${(request as { type: string }).type}`,\n })\n }\n } catch (error) {\n sendMessage({\n type: 'error',\n success: false,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n// ==================== 主循环 ====================\n\nfunction main(): void {\n let buffer: Buffer = Buffer.alloc(0)\n\n stdin.on('readable', () => {\n let chunk: Buffer | null\n while ((chunk = stdin.read() as Buffer | null) !== null) {\n buffer = Buffer.concat([buffer, chunk])\n\n // 尝试解析完整消息\n let result: ReturnType<typeof decodeMessage>\n while ((result = decodeMessage(buffer)) !== null) {\n buffer = result.remaining\n handleMessage(result.message as NativeRequest)\n }\n }\n })\n\n stdin.on('end', () => {\n process.exit(0)\n })\n\n stdin.on('error', () => {\n process.exit(1)\n })\n}\n\nmain()\n","/**\n * 守护进程管理\n */\n\nimport { spawn, ChildProcess } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, join } from 'node:path'\nimport {\n readServerInfo,\n writeServerInfo,\n deleteServerInfo,\n isProcessRunning,\n killProcess,\n ensureConfigDir,\n getCurrentISOTime,\n formatDuration,\n} from '../shared/utils.js'\nimport { SERVER_START_TIMEOUT, DEFAULT_PORT } from '../shared/constants.js'\nimport { ErrorCode, MGError } from '../shared/errors.js'\nimport type { ServerInfo } from '../shared/types.js'\nimport { createServer } from './websocket-server.js'\nimport { createLogger, LogLevel } from './logger.js'\nimport { getVersion } from '../shared/version.js'\n\n/**\n * 检查 Server 是否在运行\n */\nexport function isServerRunning(): { running: boolean; info: ServerInfo | null } {\n const info = readServerInfo()\n\n if (!info) {\n return { running: false, info: null }\n }\n\n // 检查进程是否存在\n if (!isProcessRunning(info.pid)) {\n // 进程不存在,清理旧文件\n deleteServerInfo()\n return { running: false, info: null }\n }\n\n return { running: true, info }\n}\n\n/**\n * 启动 Server(前台模式)\n */\nexport async function startServerForeground(port?: number): Promise<void> {\n const { running, info } = isServerRunning()\n\n if (running && info) {\n throw new MGError(\n ErrorCode.SERVER_ALREADY_RUNNING,\n `Server 已在运行中 (PID: ${info.pid}, 端口: ${info.port})`\n )\n }\n\n ensureConfigDir()\n\n const logger = createLogger({\n console: true,\n file: true,\n minLevel: LogLevel.INFO,\n })\n\n const server = createServer({\n port: port || DEFAULT_PORT,\n logger,\n })\n\n // 注册信号处理\n const cleanup = async () => {\n console.log('\\n正在停止 Server...')\n await server.stop()\n deleteServerInfo()\n process.exit(0)\n }\n\n process.on('SIGINT', cleanup)\n process.on('SIGTERM', cleanup)\n\n try {\n const actualPort = await server.start()\n\n // 写入 Server 信息(包含版本号)\n writeServerInfo({\n port: actualPort,\n pid: process.pid,\n startedAt: getCurrentISOTime(),\n version: getVersion(),\n })\n\n console.log(`\\nMG Server 启动成功`)\n console.log(`监听端口: ${actualPort}`)\n console.log(`进程 PID: ${process.pid}`)\n console.log(`运行模式: 前台`)\n console.log(`\\n按 Ctrl+C 停止...`)\n } catch (error) {\n logger.error('Server 启动失败:', error)\n throw error\n }\n}\n\n/**\n * 启动 Server(守护进程模式)\n */\nexport async function startServerDaemon(port?: number): Promise<ServerInfo> {\n const { running, info } = isServerRunning()\n\n if (running && info) {\n throw new MGError(\n ErrorCode.SERVER_ALREADY_RUNNING,\n `Server 已在运行中 (PID: ${info.pid}, 端口: ${info.port})`\n )\n }\n\n ensureConfigDir()\n\n // 获取当前模块的路径\n const currentFile = fileURLToPath(import.meta.url)\n const currentDir = dirname(currentFile)\n const serverScript = join(currentDir, 'daemon-runner.js')\n\n // 启动子进程\n const args = ['--foreground']\n if (port) {\n args.push('--port', String(port))\n }\n\n const child: ChildProcess = spawn(process.execPath, [serverScript, ...args], {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n MG_DAEMON: '1',\n },\n })\n\n child.unref()\n\n // 等待 Server 启动\n const startTime = Date.now()\n while (Date.now() - startTime < SERVER_START_TIMEOUT) {\n await new Promise((resolve) => setTimeout(resolve, 200))\n\n const { running, info } = isServerRunning()\n if (running && info) {\n return info\n }\n }\n\n throw new MGError(ErrorCode.SERVER_START_FAILED, 'Server 启动超时')\n}\n\n/**\n * 停止 Server\n */\nexport function stopServer(): { stopped: boolean; info: ServerInfo | null } {\n const { running, info } = isServerRunning()\n\n if (!running || !info) {\n return { stopped: false, info: null }\n }\n\n // 终止进程\n const killed = killProcess(info.pid)\n\n if (killed) {\n deleteServerInfo()\n }\n\n return { stopped: killed, info }\n}\n\n/**\n * 重启 Server\n */\nexport async function restartServer(port?: number): Promise<ServerInfo> {\n const { info: oldInfo } = stopServer()\n\n // 等待旧进程完全停止\n await new Promise((resolve) => setTimeout(resolve, 500))\n\n // 启动新 Server\n return startServerDaemon(port || oldInfo?.port)\n}\n\n/**\n * 获取 Server 状态\n */\nexport function getServerStatus(): {\n running: boolean\n port?: number\n pid?: number\n startedAt?: string\n uptime?: string\n version?: string\n} {\n const { running, info } = isServerRunning()\n\n if (!running || !info) {\n return { running: false }\n }\n\n const uptimeMs = Date.now() - new Date(info.startedAt).getTime()\n\n return {\n running: true,\n port: info.port,\n pid: info.pid,\n startedAt: info.startedAt,\n uptime: formatDuration(uptimeMs),\n version: info.version,\n }\n}\n","/**\n * MG Plugin 工具函数\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs'\nimport { dirname, resolve, isAbsolute } from 'node:path'\nimport { CONFIG_DIR, SERVER_INFO_FILE, LOG_DIR } from './constants.js'\nimport type { ServerInfo, SpaceNodeInfo, NodeInfo } from './types.js'\n\n// ==================== 文件操作 ====================\n\n/**\n * 确保目录存在\n */\nexport function ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\n/**\n * 确保配置目录存在\n */\nexport function ensureConfigDir(): void {\n ensureDir(CONFIG_DIR)\n ensureDir(LOG_DIR)\n}\n\n/**\n * 读取 Server 信息文件\n */\nexport function readServerInfo(): ServerInfo | null {\n try {\n if (!existsSync(SERVER_INFO_FILE)) {\n return null\n }\n const content = readFileSync(SERVER_INFO_FILE, 'utf-8')\n return JSON.parse(content) as ServerInfo\n } catch {\n return null\n }\n}\n\n/**\n * 写入 Server 信息文件\n */\nexport function writeServerInfo(info: ServerInfo): void {\n ensureConfigDir()\n writeFileSync(SERVER_INFO_FILE, JSON.stringify(info, null, 2), 'utf-8')\n}\n\n/**\n * 删除 Server 信息文件\n */\nexport function deleteServerInfo(): void {\n try {\n if (existsSync(SERVER_INFO_FILE)) {\n unlinkSync(SERVER_INFO_FILE)\n }\n } catch {\n // 忽略删除错误\n }\n}\n\n/**\n * 解析输出路径(支持相对路径和绝对路径)\n */\nexport function resolveOutputPath(outputPath: string): string {\n if (isAbsolute(outputPath)) {\n return outputPath\n }\n return resolve(process.cwd(), outputPath)\n}\n\n/**\n * 确保输出路径的目录存在\n */\nexport function ensureOutputDir(outputPath: string): void {\n const dir = dirname(outputPath)\n ensureDir(dir)\n}\n\n// ==================== 进程管理 ====================\n\n/**\n * 检查进程是否存在\n */\nexport function isProcessRunning(pid: number): boolean {\n try {\n // 发送信号 0 不会终止进程,但如果进程不存在会抛出错误\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 终止进程\n */\nexport function killProcess(pid: number): boolean {\n try {\n process.kill(pid, 'SIGTERM')\n return true\n } catch {\n return false\n }\n}\n\n// ==================== URL 处理 ====================\n\n/**\n * 标准化页面 URL\n *\n * 输入: https://mastergo.netease.com/file/174135798361888?fileOpenFrom=home&page_id=0%3A8347\n * 输出: mastergo.netease.com/file/174135798361888\n */\nexport function normalizePageUrl(url: string): string {\n try {\n // 已标准化的 URL(无协议)直接去掉查询参数\n if (!url.includes('://') && !url.startsWith('//')) {\n return url.split('?')[0].split('#')[0]\n }\n\n const urlObj = new URL(url)\n // 返回 host + pathname,去掉 https:// 前缀和查询参数\n return urlObj.host + urlObj.pathname\n } catch {\n // 如果已经是标准化的格式,直接返回\n return url\n }\n}\n\n/**\n * 标准化页面 URL(保留 page_id)\n * 用于导航时精确匹配页面,不同 page_id 视为不同页面\n * MasterGo 不支持在同一个 Tab 中切换 Page,所以需要精确匹配\n *\n * @example\n * normalizePageUrlWithPageId('https://mastergo.netease.com/file/123?page_id=456%3A789&other=foo')\n * // => 'mastergo.netease.com/file/123?page_id=456:789'\n *\n * normalizePageUrlWithPageId('https://mastergo.netease.com/file/123')\n * // => 'mastergo.netease.com/file/123'\n */\nexport function normalizePageUrlWithPageId(url: string): string {\n try {\n let urlObj: URL\n\n // 如果已经是标准化格式(没有协议),添加临时协议以便解析\n if (!url.includes('://') && !url.startsWith('//')) {\n urlObj = new URL(`https://${url}`)\n } else {\n urlObj = new URL(url)\n }\n\n const basePath = `${urlObj.host}${urlObj.pathname}`\n\n // 提取 page_id 参数\n const pageId = urlObj.searchParams.get('page_id')\n if (pageId) {\n // page_id 可能是 URL 编码的,解码后返回\n const decodedPageId = decodeURIComponent(pageId)\n return `${basePath}?page_id=${decodedPageId}`\n }\n\n return basePath\n } catch {\n // 解析失败,尝试简单处理\n const withoutProtocol = url\n .replace(/^https?:\\/\\//, '')\n .replace(/^\\/\\//, '')\n\n // 尝试提取 page_id\n const pageIdMatch = withoutProtocol.match(/[?&]page_id=([^&#]+)/)\n const basePath = withoutProtocol.split('?')[0].split('#')[0]\n\n if (pageIdMatch) {\n const decodedPageId = decodeURIComponent(pageIdMatch[1])\n return `${basePath}?page_id=${decodedPageId}`\n }\n\n return basePath\n }\n}\n\n/**\n * 检查是否是设计页面 URL\n * 支持 /file/ 和 /prototyping/ 两种路径\n */\nexport function isDesignPageUrl(url: string): boolean {\n // 匹配 /file/数字 或 /prototyping/数字 格式\n return /\\/(file|prototyping)\\/\\d+/.test(url)\n}\n\n// ==================== 页面 URL 构建 ====================\n\n/** 页面类型 */\nexport type PageType = 'file' | 'prototyping'\n\n/**\n * 构建页面 URL\n * 统一 pageUrl 构建逻辑,避免多处重复代码\n *\n * @param domain MasterGo 域名(如 mastergo.netease.com)\n * @param fileId 文件 ID\n * @param pageType 页面类型:file(默认)或 prototyping\n * @returns 标准化的页面 URL(如 mastergo.netease.com/file/123456)\n */\nexport function buildPageUrl(\n domain: string,\n fileId: string | number,\n pageType: PageType = 'file'\n): string {\n // 规范化 domain,去掉末尾 /\n const normalizedDomain = domain.replace(/\\/$/, '')\n return `${normalizedDomain}/${pageType}/${fileId}`\n}\n\n/**\n * 解析 mgp:// 链接\n *\n * 支持的格式 (queryParams 格式,nodeId/pageId 需要 URL 编码):\n * - mgp://mastergo.netease.com/file/174135798361888?nodeId=123%3A456 (单个节点)\n * - mgp://mastergo.netease.com/file/174135798361888?page_id=321:11979&nodeId=123%3A456 (带 page_id)\n * - mgp://mastergo.netease.com/file/174135798361888?nodeId=0%3A8633&nodePath=314%3A13190%2F0%3A8633 (带父节点路径)\n * - mgp://mastergo.netease.com/file/174135798361888?nodeId=100%3A200&childNodeIds=100%3A201,100%3A202 (多选链接)\n * - mgp://mastergo.netease.com/file/174135798361888?pageId=0%3A1 (页面链接)\n *\n * 输出: { pageUrl: 'mastergo.netease.com/file/174135798361888?page_id=321:11979', nodeId: '123:456' }\n * 或 { pageUrl: 'mastergo.netease.com/file/174135798361888', pageId: '0:1' }\n * 或 { pageUrl: 'mastergo.netease.com/file/174135798361888', nodeId: '100:200', childNodeIds: ['100:201', '100:202'] }\n */\nexport function parseMgpLink(link: string): { pageUrl: string; nodeId?: string; pageId?: string; nodePath?: string[]; childNodeIds?: string[] } | null {\n // 检查是否是 mgp:// 协议\n if (!link.startsWith('mgp://')) {\n return null\n }\n\n try {\n // 移除 mgp:// 前缀,构造为可解析的 URL\n const urlPart = link.slice(6) // 移除 'mgp://'\n const questionMarkIndex = urlPart.indexOf('?')\n\n if (questionMarkIndex === -1) {\n // 没有查询参数,无效格式\n return null\n }\n\n const basePath = urlPart.slice(0, questionMarkIndex)\n const queryString = urlPart.slice(questionMarkIndex + 1)\n\n // 解析查询参数\n const params = new URLSearchParams(queryString)\n const encodedNodeId = params.get('nodeId')\n const encodedPageId = params.get('pageId')\n const mgPageId = params.get('page_id') // MasterGo 页面 ID(用于区分同一文件的不同 page)\n\n // nodeId 和 pageId 必须有一个\n if (!encodedNodeId && !encodedPageId) {\n return null\n }\n\n // 不能同时有 nodeId 和 pageId\n if (encodedNodeId && encodedPageId) {\n return null\n }\n\n // 构建 pageUrl(包含 page_id 如果存在)\n let pageUrl = basePath\n if (mgPageId) {\n pageUrl = `${basePath}?page_id=${mgPageId}`\n }\n\n // 解析 nodeId\n if (encodedNodeId) {\n const nodeId = decodeURIComponent(encodedNodeId)\n\n // 验证 nodeId 格式:支持单个节点 (数字:数字) 或带路径的格式 (数字:数字/数字:数字/...)\n if (!/^(\\d+:\\d+)(\\/\\d+:\\d+)*$/.test(nodeId)) {\n return null\n }\n\n // 解析可选的 nodePath\n const encodedNodePath = params.get('nodePath')\n let nodePath: string[] | undefined\n\n if (encodedNodePath) {\n const decodedNodePath = decodeURIComponent(encodedNodePath)\n nodePath = decodedNodePath.split('/').filter(Boolean)\n // 验证每个路径段的格式\n if (!nodePath.every(segment => /^\\d+:\\d+$/.test(segment))) {\n return null\n }\n }\n\n // 解析可选的 childNodeIds(多选模式,逗号分隔)\n const childNodeIdsRaw = params.get('childNodeIds')\n let childNodeIds: string[] | undefined\n\n if (childNodeIdsRaw) {\n childNodeIds = childNodeIdsRaw.split(',').map(id => decodeURIComponent(id))\n // 验证每个 childNodeId 的格式(支持简单格式和带路径的格式,与 nodeId 一致)\n if (!childNodeIds.every(id => /^(\\d+:\\d+)(\\/\\d+:\\d+)*$/.test(id))) {\n return null\n }\n }\n\n return {\n pageUrl,\n nodeId,\n nodePath,\n childNodeIds,\n }\n }\n\n // 解析 pageId(不做格式校验,MasterGo 支持多种 pageId 格式如 \"0:1\" 或 \"M\")\n if (encodedPageId) {\n const pageId = decodeURIComponent(encodedPageId)\n return {\n pageUrl,\n pageId,\n }\n }\n\n return null\n } catch {\n return null\n }\n}\n\n/**\n * 生成 mgp:// 链接\n *\n * @param pageUrl 页面 URL(会被标准化,保留 page_id)\n * @param nodeId 节点 ID(会被 URL 编码)\n * @param nodePath 可选的父节点路径(会被 URL 编码)\n */\nexport function generateMgpLink(pageUrl: string, nodeId: string, nodePath?: string[]): string {\n // 使用保留 page_id 的标准化函数,确保不同 page 生成不同的链接\n const normalizedUrl = normalizePageUrlWithPageId(pageUrl)\n const encodedNodeId = encodeURIComponent(nodeId)\n\n // 注意:normalizedUrl 可能包含 ?page_id=xxx,所以使用 & 连接后续参数\n const separator = normalizedUrl.includes('?') ? '&' : '?'\n let link = `mgp://${normalizedUrl}${separator}nodeId=${encodedNodeId}`\n\n if (nodePath && nodePath.length > 0) {\n const encodedNodePath = encodeURIComponent(nodePath.join('/'))\n link += `&nodePath=${encodedNodePath}`\n }\n\n return link\n}\n\n/**\n * 生成 mgp:// 页面链接\n *\n * @param pageUrl 页面 URL(会被标准化,保留 page_id)\n * @param pageId 页面 ID(会被 URL 编码)\n */\nexport function generatePageLink(pageUrl: string, pageId: string): string {\n // 使用不保留 page_id 的标准化函数,避免 page_id 和 pageId 重复\n const normalizedUrl = normalizePageUrl(pageUrl)\n const encodedPageId = encodeURIComponent(pageId)\n\n // normalizedUrl 不包含查询参数,使用 ? 连接\n return `mgp://${normalizedUrl}?pageId=${encodedPageId}`\n}\n\n/**\n * 生成多节点 mgp:// 链接\n * 用于多选场景:以公共父元素为主节点,用 childNodeIds 参数指定选中的子节点\n *\n * 格式: mgp://[页面URL]?nodeId=[公共父元素ID]&childNodeIds=[子节点1],[子节点2]...\n *\n * @param pageUrl 页面 URL(会被标准化,保留 page_id)\n * @param parentNodeId 公共父元素 ID(作为 nodeId)\n * @param childNodeIds 选中的子节点 ID 数组(逗号分隔)\n * @returns mgp:// 格式的链接\n *\n * @example\n * generateMultiNodeMgpLink('https://mastergo.netease.com/file/123', '100:200', ['100:201', '100:202'])\n * // => 'mgp://mastergo.netease.com/file/123?nodeId=100%3A200&childNodeIds=100%3A201,100%3A202'\n */\nexport function generateMultiNodeMgpLink(\n pageUrl: string,\n parentNodeId: string,\n childNodeIds: string[]\n): string {\n // 使用保留 page_id 的标准化函数\n const normalizedUrl = normalizePageUrlWithPageId(pageUrl)\n const encodedParentNodeId = encodeURIComponent(parentNodeId)\n\n // 构建基础 URL\n const separator = normalizedUrl.includes('?') ? '&' : '?'\n let link = `mgp://${normalizedUrl}${separator}nodeId=${encodedParentNodeId}`\n\n // 添加 childNodeIds 参数(逗号分隔)\n const encodedChildIds = childNodeIds.map(id => encodeURIComponent(id)).join(',')\n link += `&childNodeIds=${encodedChildIds}`\n\n return link\n}\n\n// ==================== 输出格式化 ====================\n\n/**\n * 格式化文件大小\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} 字节`\n }\n const kb = bytes / 1024\n if (kb < 1024) {\n return `${kb.toFixed(2)} KB`\n }\n const mb = kb / 1024\n return `${mb.toFixed(2)} MB`\n}\n\n/**\n * 格式化时间间隔\n */\nexport function formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n const minutes = Math.floor(seconds / 60)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n\n if (days > 0) {\n return `${days} 天 ${hours % 24} 小时`\n }\n if (hours > 0) {\n return `${hours} 小时 ${minutes % 60} 分钟`\n }\n if (minutes > 0) {\n return `${minutes} 分钟 ${seconds % 60} 秒`\n }\n return `${seconds} 秒`\n}\n\n/**\n * 生成唯一 ID\n */\nexport function generateId(): string {\n return `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`\n}\n\n/**\n * 获取当前时间的 ISO 格式字符串\n */\nexport function getCurrentISOTime(): string {\n return new Date().toISOString()\n}\n\n/**\n * 格式化日期时间用于日志\n */\nexport function formatLogTime(date: Date = new Date()): string {\n const year = date.getFullYear()\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n const seconds = String(date.getSeconds()).padStart(2, '0')\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`\n}\n\n// ==================== FileId 提取 ====================\n\n/**\n * 从完整 URL 提取 fileId\n * \n * 支持格式:\n * - https://mastergo.netease.com/file/174875497054651?page_id=321%3A11979\n * - mastergo.netease.com/file/174875497054651\n * \n * @returns fileId 或 null\n */\nexport function extractFileIdFromUrl(url: string): string | null {\n // 匹配 /file/数字 格式\n const match = url.match(/\\/file\\/(\\d+)/)\n return match ? match[1] : null\n}\n\n/**\n * 从 mgp:// 链接提取 fileId\n * \n * 支持格式:\n * - mgp://mastergo.netease.com/file/174875497054651?nodeId=xxx\n * \n * @returns fileId 或 null\n */\nexport function extractFileIdFromMgpLink(link: string): string | null {\n if (!link.startsWith('mgp://')) {\n return null\n }\n return extractFileIdFromUrl(link)\n}\n\n/**\n * 统一处理输入,提取 fileId\n * \n * 支持三种输入格式:\n * 1. 完整 URL: https://mastergo.netease.com/file/174875497054651?page_id=xxx\n * 2. mgp 协议: mgp://mastergo.netease.com/file/174875497054651?nodeId=xxx\n * 3. 纯 fileId: 174875497054651\n * \n * @returns fileId 或 null\n */\nexport function extractFileId(input: string): string | null {\n const trimmed = input.trim()\n \n // 1. 纯数字 fileId\n if (/^\\d+$/.test(trimmed)) {\n return trimmed\n }\n \n // 2. mgp:// 协议\n if (trimmed.startsWith('mgp://')) {\n return extractFileIdFromMgpLink(trimmed)\n }\n \n // 3. 完整 URL (http:// 或 https://)\n if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) {\n return extractFileIdFromUrl(trimmed)\n }\n \n // 4. 尝试作为不带协议的 URL 解析\n return extractFileIdFromUrl(trimmed)\n}\n\n// ==================== 节点数据精简 ====================\n\n/**\n * 需要四舍五入的数值字段\n */\nconst NUMERIC_FIELDS = [\n 'x', 'y', 'width', 'height',\n 'rotation',\n 'opacity',\n 'cornerRadius', 'topLeftRadius', 'topRightRadius', 'bottomLeftRadius', 'bottomRightRadius',\n 'strokeWeight', 'strokeTopWeight', 'strokeLeftWeight', 'strokeBottomWeight', 'strokeRightWeight',\n 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',\n 'itemSpacing', 'crossAxisSpacing',\n 'flexGrow',\n]\n\n/**\n * 四舍五入到一位小数\n * 25.666667938232422 -> 25.7\n */\nexport function roundToOneDecimal(value: number): number {\n return Math.round(value * 10) / 10\n}\n\n/**\n * MasterGo 节点属性默认值\n * 基于官方文档定义,当值等于默认值时可以省略以减少 JSON 体积\n */\nexport const NODE_DEFAULTS: Record<string, unknown> = {\n // Scene Node 属性\n visible: true,\n isVisible: true,\n isLocked: false,\n\n // Blend 属性\n opacity: 1,\n blendMode: 'NORMAL',\n isMask: false,\n isMaskOutline: false,\n isMaskVisible: false,\n effectStyleId: '',\n\n // Geometry 属性\n strokeStyle: 'SOLID',\n strokeWeight: 0,\n strokeTopWeight: 0,\n strokeLeftWeight: 0,\n strokeBottomWeight: 0,\n strokeRightWeight: 0,\n strokeAlign: 'CENTER',\n strokeCap: 'NONE',\n strokeJoin: 'MITER',\n dashCap: 'NONE',\n fillStyleId: '',\n strokeStyleId: '',\n strokeFillStyleId: '',\n strokeWidthStyleId: '',\n\n // Corner 属性\n cornerSmooth: 0,\n cornerRadius: 0,\n topLeftRadius: 0,\n topRightRadius: 0,\n bottomLeftRadius: 0,\n bottomRightRadius: 0,\n cornerRadiusStyleId: '',\n\n // Layout 属性\n rotation: 0,\n flexGrow: 0,\n alignSelf: 'INHERIT',\n layoutPositioning: 'AUTO',\n constrainProportions: false,\n\n // 容器专属属性 (FrameNode)\n flexWrap: 'NO_WRAP',\n itemSpacing: 0,\n crossAxisSpacing: 0,\n paddingTop: 0,\n paddingRight: 0,\n paddingBottom: 0,\n paddingLeft: 0,\n paddingStyleId: '',\n spacingStyleId: '',\n clipsContent: false,\n itemReverseZIndex: false,\n strokesIncludedInLayout: false,\n overflowDirection: 'NONE',\n gridStyleId: '',\n\n // 其他属性\n componentPropertyReferences: null,\n}\n\n/**\n * 需要检查是否为空数组的字段\n */\nconst EMPTY_ARRAY_FIELDS = [\n 'fills',\n 'strokes',\n 'effects',\n 'strokeDashes',\n 'exportSettings',\n 'reactions',\n 'attachedConnectors',\n 'layoutGrids',\n]\n\n/**\n * 检查值是否为空数组\n */\nfunction isEmptyArray(value: unknown): boolean {\n return Array.isArray(value) && value.length === 0\n}\n\n/**\n * 检查两个值是否相等(简单比较)\n */\nfunction isEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (a === null || b === null) return a === b\n if (typeof a !== typeof b) return false\n return false\n}\n\n/**\n * 精简节点数据,移除等于默认值的字段\n * 递归处理 children 数组\n *\n * @param node 原始节点数据\n * @returns 精简后的节点数据\n */\nexport function trimNodeDefaults<T extends Record<string, unknown>>(node: T): T {\n const result: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(node)) {\n // 递归处理 children 数组\n if (key === 'children' && Array.isArray(value)) {\n const trimmedChildren = value.map((child) =>\n typeof child === 'object' && child !== null\n ? trimNodeDefaults(child as Record<string, unknown>)\n : child\n )\n // 只有非空时才保留\n if (trimmedChildren.length > 0) {\n result[key] = trimmedChildren\n }\n continue\n }\n\n // 检查是否是需要检查空数组的字段\n if (EMPTY_ARRAY_FIELDS.includes(key) && isEmptyArray(value)) {\n continue // 跳过空数组\n }\n\n // 对数值字段进行四舍五入\n if (NUMERIC_FIELDS.includes(key) && typeof value === 'number') {\n const roundedValue = roundToOneDecimal(value)\n // 检查四舍五入后是否等于默认值\n if (key in NODE_DEFAULTS && isEqual(roundedValue, NODE_DEFAULTS[key])) {\n continue // 跳过等于默认值的字段\n }\n result[key] = roundedValue\n continue\n }\n\n // 检查是否有默认值定义\n if (key in NODE_DEFAULTS) {\n const defaultValue = NODE_DEFAULTS[key]\n if (isEqual(value, defaultValue)) {\n continue // 跳过等于默认值的字段\n }\n }\n\n // 保留此字段\n result[key] = value\n }\n\n return result as T\n}\n\n// ==================== 空间信息提取 ====================\n\n/**\n * 提取节点的空间信息\n * 只保留 id、name、x、y、width、height、absoluteX、absoluteY 和 children 字段\n * 用于让 AI 以最少的字段理解节点的空间布局关系\n *\n * @param node 原始节点数据\n * @returns 精简的空间节点信息\n */\nexport function extractSpaceInfo(node: NodeInfo): SpaceNodeInfo {\n const result: SpaceNodeInfo = {\n id: node.id,\n name: node.name,\n x: roundToOneDecimal(typeof node.x === 'number' ? node.x : 0),\n y: roundToOneDecimal(typeof node.y === 'number' ? node.y : 0),\n width: roundToOneDecimal(typeof node.width === 'number' ? node.width : 0),\n height: roundToOneDecimal(typeof node.height === 'number' ? node.height : 0),\n }\n\n // 添加绝对坐标(如果存在)\n if (typeof node.absoluteX === 'number') {\n result.absoluteX = roundToOneDecimal(node.absoluteX)\n }\n if (typeof node.absoluteY === 'number') {\n result.absoluteY = roundToOneDecimal(node.absoluteY)\n }\n\n // 递归处理 children\n if (node.children && Array.isArray(node.children) && node.children.length > 0) {\n result.children = node.children.map((child) => extractSpaceInfo(child))\n }\n\n return result\n}\n","/**\n * MG Plugin 常量定义\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\n// ==================== 运行模式 ====================\n\n/** 是否为开发模式(通过环境变量 MG_DEV_MODE=true 设置) */\nexport const IS_DEV_MODE = process.env.MG_DEV_MODE === 'true'\n\n// ==================== 端口配置 ====================\n\n/** 生产环境默认端口 */\nexport const PROD_DEFAULT_PORT = 9527\n\n/** 生产环境端口范围:起始 */\nexport const PROD_PORT_RANGE_START = 9527\n\n/** 生产环境端口范围:结束 */\nexport const PROD_PORT_RANGE_END = 9536\n\n/** 开发环境默认端口 */\nexport const DEV_DEFAULT_PORT = 19527\n\n/** 开发环境端口范围:起始 */\nexport const DEV_PORT_RANGE_START = 19527\n\n/** 开发环境端口范围:结束 */\nexport const DEV_PORT_RANGE_END = 19536\n\n/** 默认端口(根据运行模式自动选择) */\nexport const DEFAULT_PORT = IS_DEV_MODE ? DEV_DEFAULT_PORT : PROD_DEFAULT_PORT\n\n/** 端口范围:起始(根据运行模式自动选择) */\nexport const PORT_RANGE_START = IS_DEV_MODE ? DEV_PORT_RANGE_START : PROD_PORT_RANGE_START\n\n/** 端口范围:结束(根据运行模式自动选择) */\nexport const PORT_RANGE_END = IS_DEV_MODE ? DEV_PORT_RANGE_END : PROD_PORT_RANGE_END\n\n/** 最大尝试端口数 */\nexport const MAX_PORT_ATTEMPTS = 10\n\n/** 端口扫描超时(毫秒) */\nexport const PORT_SCAN_TIMEOUT = 500\n\n// ==================== 路径配置 ====================\n\n/** 配置目录 */\nexport const CONFIG_DIR = join(homedir(), '.mg-plugin')\n\n/** Server 状态文件 */\nexport const SERVER_INFO_FILE = join(CONFIG_DIR, 'server.json')\n\n/** 日志目录 */\nexport const LOG_DIR = join(CONFIG_DIR, 'logs')\n\n/** Server 日志文件 */\nexport const SERVER_LOG_FILE = join(LOG_DIR, 'server.log')\n\n// ==================== 超时配置 ====================\n\n/** 心跳间隔(毫秒)- 30 秒 */\nexport const HEARTBEAT_INTERVAL = 30000\n\n/** 心跳超时(毫秒)- 90 秒(3 次心跳) */\nexport const HEARTBEAT_TIMEOUT = 90000\n\n/** 请求超时(毫秒)- 30 秒 */\nexport const REQUEST_TIMEOUT = 30000\n\n/** 请求超时上限(毫秒)- 10 分钟。写操作(如 create_node 大树)可通过\n * 请求消息的 timeoutMs 字段放宽超时,此常量防止传入过大值长期占用资源 */\nexport const MAX_REQUEST_TIMEOUT = 600000\n\n/** Server 启动等待超时(毫秒)- 5 秒 */\nexport const SERVER_START_TIMEOUT = 5000\n\n/** CLI 重试间隔(毫秒) */\nexport const RETRY_INTERVALS = [1000, 2000, 4000]\n\n/** 最大重试次数 */\nexport const MAX_RETRY_COUNT = 3\n\n// ==================== 连接类型 ====================\n\n/** 连接类型 */\nexport enum ConnectionType {\n /** 获取端 (CLI/MCP) */\n CONSUMER = 'consumer',\n /** 提供端 (Injector) */\n PROVIDER = 'provider',\n /** Chrome 扩展 (Background Script) */\n CHROME_EXTENSION = 'chrome_extension',\n}\n\n// ==================== 消息类型 ====================\n\n/** WebSocket 消息类型 */\nexport enum MessageType {\n // 系统消息\n PING = 'ping',\n PONG = 'pong',\n REGISTER = 'register',\n REGISTER_ACK = 'register_ack',\n\n // 业务消息\n GET_NODE_BY_ID = 'get_node_by_id',\n GET_NODE_CONTEXT = 'get_node_context',\n GET_PAGE_BY_ID = 'get_page_by_id',\n GET_ALL_NODES = 'get_all_nodes',\n GET_SELECTION = 'get_selection',\n EXPORT_IMAGE = 'export_image',\n EXECUTE_CODE = 'execute_code',\n LIST_FONTS = 'list_fonts',\n LIST_LIBRARY = 'list_library',\n IMPORT_COMPONENT = 'import_component',\n GET_ALL_PAGES = 'get_all_pages',\n GET_COMMENTS = 'get_comments',\n CREATE_PAGE = 'create_page',\n CREATE_NODE = 'create_node',\n DELETE_NODE = 'delete_node',\n UPDATE_NODE = 'update_node',\n\n // 扩展管理消息\n LIST_EXTENSIONS = 'list_extensions',\n OPEN_PAGE = 'open_page',\n NAVIGATE_TO_NODE = 'navigate_to_node',\n\n // Server 状态消息(本地请求,不转发到 Provider)\n GET_SERVER_STATUS = 'get_server_status',\n\n // 统计分析消息(CLI -> Server,fire-and-forget)\n TRACK_ANALYTICS = 'track_analytics',\n\n // 响应\n RESPONSE = 'response',\n ERROR = 'error',\n}\n","/**\n * MG Plugin 错误码定义\n */\n\n/** 错误码枚举 */\nexport enum ErrorCode {\n /** 无法连接到 MG Server */\n CONNECTION_FAILED = 'E001',\n /** 连接超时 */\n CONNECTION_TIMEOUT = 'E002',\n /** 没有 MasterGo 页面连接到 Server */\n NO_PAGE_CONNECTED = 'E003',\n /** 未找到匹配的页面 */\n PAGE_NOT_FOUND = 'E004',\n /** 节点不存在 */\n NODE_NOT_FOUND = 'E005',\n /** 没有选中任何节点 */\n NO_SELECTION = 'E006',\n /** mg 对象不可用 */\n MG_UNAVAILABLE = 'E007',\n /** 导出图片失败 */\n EXPORT_FAILED = 'E008',\n /** 文件写入失败 */\n FILE_WRITE_FAILED = 'E009',\n /** 无效的 mgp:// 链接格式 */\n INVALID_LINK = 'E010',\n /** 参数校验失败 */\n INVALID_PARAMS = 'E011',\n /** 请求超时 */\n REQUEST_TIMEOUT = 'E012',\n /** 所有备选端口均被占用 */\n PORT_EXHAUSTED = 'E013',\n /** 无法发现 Server (端口扫描失败) */\n SERVER_DISCOVERY_FAILED = 'E014',\n /** 自动启动 Server 失败 */\n SERVER_START_FAILED = 'E015',\n /** Server 已在运行中 */\n SERVER_ALREADY_RUNNING = 'E016',\n /** 连接断开 */\n CONNECTION_LOST = 'E017',\n /** 没有扩展连接到 Server */\n NO_EXTENSION_CONNECTED = 'E018',\n /** 页面只读 / 无编辑权限,无法执行写操作 */\n EDIT_NOT_ALLOWED = 'E019',\n /** 创建节点整体性失败(根节点都建不出来) */\n CREATE_NODE_FAILED = 'E020',\n /** 未知错误 */\n UNKNOWN_ERROR = 'E099',\n}\n\n/** 错误码对应的错误名称 */\nexport const ErrorNames: Record<ErrorCode, string> = {\n [ErrorCode.CONNECTION_FAILED]: 'CONNECTION_FAILED',\n [ErrorCode.CONNECTION_TIMEOUT]: 'CONNECTION_TIMEOUT',\n [ErrorCode.NO_PAGE_CONNECTED]: 'NO_PAGE_CONNECTED',\n [ErrorCode.PAGE_NOT_FOUND]: 'PAGE_NOT_FOUND',\n [ErrorCode.NODE_NOT_FOUND]: 'NODE_NOT_FOUND',\n [ErrorCode.NO_SELECTION]: 'NO_SELECTION',\n [ErrorCode.MG_UNAVAILABLE]: 'MG_UNAVAILABLE',\n [ErrorCode.EXPORT_FAILED]: 'EXPORT_FAILED',\n [ErrorCode.FILE_WRITE_FAILED]: 'FILE_WRITE_FAILED',\n [ErrorCode.INVALID_LINK]: 'INVALID_LINK',\n [ErrorCode.INVALID_PARAMS]: 'INVALID_PARAMS',\n [ErrorCode.REQUEST_TIMEOUT]: 'REQUEST_TIMEOUT',\n [ErrorCode.PORT_EXHAUSTED]: 'PORT_EXHAUSTED',\n [ErrorCode.SERVER_DISCOVERY_FAILED]: 'SERVER_DISCOVERY_FAILED',\n [ErrorCode.SERVER_START_FAILED]: 'SERVER_START_FAILED',\n [ErrorCode.SERVER_ALREADY_RUNNING]: 'SERVER_ALREADY_RUNNING',\n [ErrorCode.CONNECTION_LOST]: 'CONNECTION_LOST',\n [ErrorCode.NO_EXTENSION_CONNECTED]: 'NO_EXTENSION_CONNECTED',\n [ErrorCode.EDIT_NOT_ALLOWED]: 'EDIT_NOT_ALLOWED',\n [ErrorCode.CREATE_NODE_FAILED]: 'CREATE_NODE_FAILED',\n [ErrorCode.UNKNOWN_ERROR]: 'UNKNOWN_ERROR',\n}\n\n/** 错误码对应的默认消息 */\nexport const ErrorMessages: Record<ErrorCode, string> = {\n [ErrorCode.CONNECTION_FAILED]: '无法连接到 MG Server',\n [ErrorCode.CONNECTION_TIMEOUT]: '连接超时',\n [ErrorCode.NO_PAGE_CONNECTED]: '没有 MasterGo 页面连接到 Server。请安装 MG Plugin 浏览器扩展: https://chromewebstore.google.com/detail/mg-plugin/ddhihanlpcdneicohnglnaliefnkaeja',\n [ErrorCode.PAGE_NOT_FOUND]: '未找到匹配的页面',\n [ErrorCode.NODE_NOT_FOUND]: '节点不存在',\n [ErrorCode.NO_SELECTION]: '没有选中任何节点',\n [ErrorCode.MG_UNAVAILABLE]: 'mg 对象不可用',\n [ErrorCode.EXPORT_FAILED]: '导出图片失败',\n [ErrorCode.FILE_WRITE_FAILED]: '文件写入失败',\n [ErrorCode.INVALID_LINK]: '无效的 mgp:// 链接格式',\n [ErrorCode.INVALID_PARAMS]: '参数校验失败',\n [ErrorCode.REQUEST_TIMEOUT]: '请求超时',\n [ErrorCode.PORT_EXHAUSTED]: '所有备选端口均被占用',\n [ErrorCode.SERVER_DISCOVERY_FAILED]: '无法发现 Server (端口扫描失败)',\n [ErrorCode.SERVER_START_FAILED]: '自动启动 Server 失败',\n [ErrorCode.SERVER_ALREADY_RUNNING]: 'Server 已在运行中',\n [ErrorCode.CONNECTION_LOST]: '连接断开',\n [ErrorCode.NO_EXTENSION_CONNECTED]: '没有 Chrome 扩展连接到 Server。请确保浏览器已打开并安装了 MG Plugin',\n [ErrorCode.EDIT_NOT_ALLOWED]: '页面只读或无编辑权限,无法执行写操作',\n [ErrorCode.CREATE_NODE_FAILED]: '创建节点失败(根节点无法创建)',\n [ErrorCode.UNKNOWN_ERROR]: '未知错误',\n}\n\n/** MG Plugin 错误类 */\nexport class MGError extends Error {\n /** 错误码 */\n code: ErrorCode\n /** 错误名称 */\n errorName: string\n /** 额外详情 */\n details?: Record<string, unknown>\n\n constructor(code: ErrorCode, message?: string, details?: Record<string, unknown>) {\n super(message || ErrorMessages[code])\n this.name = 'MGError'\n this.code = code\n this.errorName = ErrorNames[code]\n this.details = details\n }\n\n /** 转换为 JSON 格式 */\n toJSON() {\n return {\n code: this.code,\n name: this.errorName,\n message: this.message,\n details: this.details,\n }\n }\n\n /** 格式化输出 */\n toString() {\n return `错误 [${this.code}]: ${this.message}`\n }\n}\n\n/**\n * 创建错误\n */\nexport function createError(\n code: ErrorCode,\n message?: string,\n details?: Record<string, unknown>\n): MGError {\n return new MGError(code, message, details)\n}\n","import createWebSocketStream from './lib/stream.js';\nimport Receiver from './lib/receiver.js';\nimport Sender from './lib/sender.js';\nimport WebSocket from './lib/websocket.js';\nimport WebSocketServer from './lib/websocket-server.js';\n\nexport { createWebSocketStream, Receiver, Sender, WebSocket, WebSocketServer };\nexport default WebSocket;\n","/**\n * 日志模块\n */\n\nimport { appendFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { SERVER_LOG_FILE } from '../shared/constants.js'\nimport { formatLogTime } from '../shared/utils.js'\n\nexport enum LogLevel {\n DEBUG = 'DEBUG',\n INFO = 'INFO',\n WARN = 'WARN',\n ERROR = 'ERROR',\n}\n\nexport interface LoggerOptions {\n /** 是否输出到控制台 */\n console?: boolean\n /** 是否输出到文件 */\n file?: boolean\n /** 日志文件路径 */\n filePath?: string\n /** 最小日志级别 */\n minLevel?: LogLevel\n}\n\nconst levelPriority: Record<LogLevel, number> = {\n [LogLevel.DEBUG]: 0,\n [LogLevel.INFO]: 1,\n [LogLevel.WARN]: 2,\n [LogLevel.ERROR]: 3,\n}\n\n/**\n * 日志记录器\n */\nexport class Logger {\n private options: Required<LoggerOptions>\n\n constructor(options: LoggerOptions = {}) {\n this.options = {\n console: options.console ?? true,\n file: options.file ?? false,\n filePath: options.filePath ?? SERVER_LOG_FILE,\n minLevel: options.minLevel ?? LogLevel.INFO,\n }\n\n // 确保日志目录存在\n if (this.options.file) {\n const dir = dirname(this.options.filePath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n }\n }\n\n /**\n * 记录日志\n */\n private log(level: LogLevel, message: string, ...args: unknown[]): void {\n // 检查日志级别\n if (levelPriority[level] < levelPriority[this.options.minLevel]) {\n return\n }\n\n const timestamp = formatLogTime()\n const formattedMessage = `[${timestamp}] [${level}] ${message}`\n\n // 输出到控制台\n if (this.options.console) {\n const consoleMethod = level === LogLevel.ERROR ? console.error : console.log\n if (args.length > 0) {\n consoleMethod(formattedMessage, ...args)\n } else {\n consoleMethod(formattedMessage)\n }\n }\n\n // 输出到文件\n if (this.options.file) {\n try {\n const fileMessage =\n args.length > 0\n ? `${formattedMessage} ${JSON.stringify(args)}\\n`\n : `${formattedMessage}\\n`\n appendFileSync(this.options.filePath, fileMessage)\n } catch (error) {\n // 文件写入失败时静默处理\n if (this.options.console) {\n console.error('日志文件写入失败:', error)\n }\n }\n }\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.log(LogLevel.DEBUG, message, ...args)\n }\n\n info(message: string, ...args: unknown[]): void {\n this.log(LogLevel.INFO, message, ...args)\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.log(LogLevel.WARN, message, ...args)\n }\n\n error(message: string, ...args: unknown[]): void {\n this.log(LogLevel.ERROR, message, ...args)\n }\n}\n\n/** 创建默认日志记录器 */\nexport function createLogger(options?: LoggerOptions): Logger {\n return new Logger(options)\n}\n","/**\n * 版本管理模块\n * 提供获取当前 CLI 版本的函数\n * 优先从 package.json 读取版本号(本地开发默认 9.9.9)\n * CI 发布时会用 VERSION 文件覆盖 package.json\n */\n\nimport { readFileSync, existsSync } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, join } from 'node:path'\n\n/** 缓存的版本号 */\nlet cachedVersion: string | null = null\n\n/**\n * 获取当前 CLI 版本号\n * 优先从 package.json 读取(本地开发默认 9.9.9)\n * CI 发布时会用 VERSION 文件的值覆盖 package.json\n */\nexport function getVersion(): string {\n if (cachedVersion !== null) {\n return cachedVersion\n }\n\n try {\n // 获取当前模块的目录\n const currentFile = fileURLToPath(import.meta.url)\n const currentDir = dirname(currentFile)\n\n // 优先从 package.json 读取版本号\n // 本地开发时 package.json 固定为 9.9.9\n // CI 发布时会用 VERSION 文件覆盖 package.json 后再打包\n const packageJsonPaths = [\n join(currentDir, '..', 'package.json'), // dist/xxx.js -> ../package.json\n join(currentDir, '..', '..', 'package.json'), // src/shared/version.ts -> ../../package.json\n ]\n\n for (const packageJsonPath of packageJsonPaths) {\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))\n if (packageJson.name === '@hangox/mg-cli') {\n cachedVersion = (packageJson.version as string) || '0.0.0'\n return cachedVersion\n }\n }\n }\n\n // 如果找不到,返回默认版本\n cachedVersion = '0.0.0'\n return cachedVersion\n } catch {\n // 如果读取失败,返回默认版本\n cachedVersion = '0.0.0'\n return cachedVersion\n }\n}\n\n/** 开发版本标识 */\nconst DEV_VERSION = '9.9.9'\n\n/**\n * 比较两个版本是否一致\n * 9.9.9 是开发版本,与任何版本都视为匹配\n */\nexport function isVersionMatch(version1: string, version2: string): boolean {\n // 开发版本 9.9.9 与任何版本都视为匹配\n if (version1 === DEV_VERSION || version2 === DEV_VERSION) {\n return true\n }\n return version1 === version2\n}\n\n/**\n * 清除缓存的版本号(用于测试)\n */\nexport function clearVersionCache(): void {\n cachedVersion = null\n}\n","import { dirname, posix, sep } from \"path\";\nfunction createModulerModifier() {\n const getModuleFromFileName = createGetModuleFromFilename();\n return async (frames)=>{\n for (const frame of frames)frame.module = getModuleFromFileName(frame.filename);\n return frames;\n };\n}\nfunction createGetModuleFromFilename(basePath = process.argv[1] ? dirname(process.argv[1]) : process.cwd(), isWindows = '\\\\' === sep) {\n const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;\n return (filename)=>{\n if (!filename) return;\n const normalizedFilename = isWindows ? normalizeWindowsPath(filename) : filename;\n let { dir, base: file, ext } = posix.parse(normalizedFilename);\n if ('.js' === ext || '.mjs' === ext || '.cjs' === ext) file = file.slice(0, -1 * ext.length);\n const decodedFile = decodeURIComponent(file);\n if (!dir) dir = '.';\n const n = dir.lastIndexOf('/node_modules');\n if (n > -1) return `${dir.slice(n + 14).replace(/\\//g, '.')}:${decodedFile}`;\n if (dir.startsWith(normalizedBase)) {\n const moduleName = dir.slice(normalizedBase.length + 1).replace(/\\//g, '.');\n return moduleName ? `${moduleName}:${decodedFile}` : decodedFile;\n }\n return decodedFile;\n };\n}\nfunction normalizeWindowsPath(path) {\n return path.replace(/^[A-Z]:/, '').replace(/\\\\/g, '/');\n}\nexport { createModulerModifier };\n","/*! For license information please see uuidv7.mjs.LICENSE.txt */\n/**\n * uuidv7: An experimental implementation of the proposed UUID Version 7\n *\n * @license Apache-2.0\n * @copyright 2021-2023 LiosK\n * @packageDocumentation\n */ const DIGITS = \"0123456789abcdef\";\nclass UUID {\n constructor(bytes){\n this.bytes = bytes;\n }\n static ofInner(bytes) {\n if (16 === bytes.length) return new UUID(bytes);\n throw new TypeError(\"not 128-bit length\");\n }\n static fromFieldsV7(unixTsMs, randA, randBHi, randBLo) {\n if (!Number.isInteger(unixTsMs) || !Number.isInteger(randA) || !Number.isInteger(randBHi) || !Number.isInteger(randBLo) || unixTsMs < 0 || randA < 0 || randBHi < 0 || randBLo < 0 || unixTsMs > 0xffffffffffff || randA > 0xfff || randBHi > 0x3fffffff || randBLo > 0xffffffff) throw new RangeError(\"invalid field value\");\n const bytes = new Uint8Array(16);\n bytes[0] = unixTsMs / 2 ** 40;\n bytes[1] = unixTsMs / 2 ** 32;\n bytes[2] = unixTsMs / 2 ** 24;\n bytes[3] = unixTsMs / 2 ** 16;\n bytes[4] = unixTsMs / 256;\n bytes[5] = unixTsMs;\n bytes[6] = 0x70 | randA >>> 8;\n bytes[7] = randA;\n bytes[8] = 0x80 | randBHi >>> 24;\n bytes[9] = randBHi >>> 16;\n bytes[10] = randBHi >>> 8;\n bytes[11] = randBHi;\n bytes[12] = randBLo >>> 24;\n bytes[13] = randBLo >>> 16;\n bytes[14] = randBLo >>> 8;\n bytes[15] = randBLo;\n return new UUID(bytes);\n }\n static parse(uuid) {\n let hex;\n switch(uuid.length){\n case 32:\n hex = /^[0-9a-f]{32}$/i.exec(uuid)?.[0];\n break;\n case 36:\n hex = /^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i.exec(uuid)?.slice(1, 6).join(\"\");\n break;\n case 38:\n hex = /^\\{([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})\\}$/i.exec(uuid)?.slice(1, 6).join(\"\");\n break;\n case 45:\n hex = /^urn:uuid:([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i.exec(uuid)?.slice(1, 6).join(\"\");\n break;\n default:\n break;\n }\n if (hex) {\n const inner = new Uint8Array(16);\n for(let i = 0; i < 16; i += 4){\n const n = parseInt(hex.substring(2 * i, 2 * i + 8), 16);\n inner[i + 0] = n >>> 24;\n inner[i + 1] = n >>> 16;\n inner[i + 2] = n >>> 8;\n inner[i + 3] = n;\n }\n return new UUID(inner);\n }\n throw new SyntaxError(\"could not parse UUID string\");\n }\n toString() {\n let text = \"\";\n for(let i = 0; i < this.bytes.length; i++){\n text += DIGITS.charAt(this.bytes[i] >>> 4);\n text += DIGITS.charAt(0xf & this.bytes[i]);\n if (3 === i || 5 === i || 7 === i || 9 === i) text += \"-\";\n }\n return text;\n }\n toHex() {\n let text = \"\";\n for(let i = 0; i < this.bytes.length; i++){\n text += DIGITS.charAt(this.bytes[i] >>> 4);\n text += DIGITS.charAt(0xf & this.bytes[i]);\n }\n return text;\n }\n toJSON() {\n return this.toString();\n }\n getVariant() {\n const n = this.bytes[8] >>> 4;\n if (n < 0) throw new Error(\"unreachable\");\n if (n <= 7) return this.bytes.every((e)=>0 === e) ? \"NIL\" : \"VAR_0\";\n if (n <= 11) return \"VAR_10\";\n if (n <= 13) return \"VAR_110\";\n if (n <= 15) return this.bytes.every((e)=>0xff === e) ? \"MAX\" : \"VAR_RESERVED\";\n else throw new Error(\"unreachable\");\n }\n getVersion() {\n return \"VAR_10\" === this.getVariant() ? this.bytes[6] >>> 4 : void 0;\n }\n clone() {\n return new UUID(this.bytes.slice(0));\n }\n equals(other) {\n return 0 === this.compareTo(other);\n }\n compareTo(other) {\n for(let i = 0; i < 16; i++){\n const diff = this.bytes[i] - other.bytes[i];\n if (0 !== diff) return Math.sign(diff);\n }\n return 0;\n }\n}\nclass V7Generator {\n constructor(randomNumberGenerator){\n this.timestamp = 0;\n this.counter = 0;\n this.random = randomNumberGenerator ?? getDefaultRandom();\n }\n generate() {\n return this.generateOrResetCore(Date.now(), 10000);\n }\n generateOrAbort() {\n return this.generateOrAbortCore(Date.now(), 10000);\n }\n generateOrResetCore(unixTsMs, rollbackAllowance) {\n let value = this.generateOrAbortCore(unixTsMs, rollbackAllowance);\n if (void 0 === value) {\n this.timestamp = 0;\n value = this.generateOrAbortCore(unixTsMs, rollbackAllowance);\n }\n return value;\n }\n generateOrAbortCore(unixTsMs, rollbackAllowance) {\n const MAX_COUNTER = 0x3ffffffffff;\n if (!Number.isInteger(unixTsMs) || unixTsMs < 1 || unixTsMs > 0xffffffffffff) throw new RangeError(\"`unixTsMs` must be a 48-bit positive integer\");\n if (rollbackAllowance < 0 || rollbackAllowance > 0xffffffffffff) throw new RangeError(\"`rollbackAllowance` out of reasonable range\");\n if (unixTsMs > this.timestamp) {\n this.timestamp = unixTsMs;\n this.resetCounter();\n } else {\n if (!(unixTsMs + rollbackAllowance >= this.timestamp)) return;\n this.counter++;\n if (this.counter > MAX_COUNTER) {\n this.timestamp++;\n this.resetCounter();\n }\n }\n return UUID.fromFieldsV7(this.timestamp, Math.trunc(this.counter / 2 ** 30), this.counter & 2 ** 30 - 1, this.random.nextUint32());\n }\n resetCounter() {\n this.counter = 0x400 * this.random.nextUint32() + (0x3ff & this.random.nextUint32());\n }\n generateV4() {\n const bytes = new Uint8Array(Uint32Array.of(this.random.nextUint32(), this.random.nextUint32(), this.random.nextUint32(), this.random.nextUint32()).buffer);\n bytes[6] = 0x40 | bytes[6] >>> 4;\n bytes[8] = 0x80 | bytes[8] >>> 2;\n return UUID.ofInner(bytes);\n }\n}\nconst getDefaultRandom = ()=>({\n nextUint32: ()=>0x10000 * Math.trunc(0x10000 * Math.random()) + Math.trunc(0x10000 * Math.random())\n });\nlet defaultGenerator;\nconst uuidv7 = ()=>uuidv7obj().toString();\nconst uuidv7obj = ()=>(defaultGenerator || (defaultGenerator = new V7Generator())).generate();\nconst uuidv4 = ()=>uuidv4obj().toString();\nconst uuidv4obj = ()=>(defaultGenerator || (defaultGenerator = new V7Generator())).generateV4();\nexport { UUID, V7Generator, uuidv4, uuidv4obj, uuidv7, uuidv7obj };\n","import { knownUnsafeEditableEvent } from \"../types.mjs\";\nimport { includes } from \"./string-utils.mjs\";\nconst nativeIsArray = Array.isArray;\nconst ObjProto = Object.prototype;\nconst type_utils_hasOwnProperty = ObjProto.hasOwnProperty;\nconst type_utils_toString = ObjProto.toString;\nconst isArray = nativeIsArray || function(obj) {\n return '[object Array]' === type_utils_toString.call(obj);\n};\nconst isFunction = (x)=>'function' == typeof x;\nconst isNativeFunction = (x)=>isFunction(x) && -1 !== x.toString().indexOf('[native code]');\nconst isObject = (x)=>x === Object(x) && !isArray(x);\nconst isEmptyObject = (x)=>{\n if (isObject(x)) {\n for(const key in x)if (type_utils_hasOwnProperty.call(x, key)) return false;\n return true;\n }\n return false;\n};\nconst isUndefined = (x)=>void 0 === x;\nconst isString = (x)=>'[object String]' == type_utils_toString.call(x);\nconst isEmptyString = (x)=>isString(x) && 0 === x.trim().length;\nconst isNull = (x)=>null === x;\nconst isNullish = (x)=>isUndefined(x) || isNull(x);\nconst isNumber = (x)=>'[object Number]' == type_utils_toString.call(x);\nconst isBoolean = (x)=>'[object Boolean]' === type_utils_toString.call(x);\nconst isFormData = (x)=>x instanceof FormData;\nconst isFile = (x)=>x instanceof File;\nconst isPlainError = (x)=>x instanceof Error;\nconst isKnownUnsafeEditableEvent = (x)=>includes(knownUnsafeEditableEvent, x);\nfunction isInstanceOf(candidate, base) {\n try {\n return candidate instanceof base;\n } catch {\n return false;\n }\n}\nfunction isPrimitive(value) {\n return null === value || 'object' != typeof value;\n}\nfunction isBuiltin(candidate, className) {\n return Object.prototype.toString.call(candidate) === `[object ${className}]`;\n}\nfunction isError(candidate) {\n switch(Object.prototype.toString.call(candidate)){\n case '[object Error]':\n case '[object Exception]':\n case '[object DOMException]':\n case '[object DOMError]':\n case '[object WebAssembly.Exception]':\n return true;\n default:\n return isInstanceOf(candidate, Error);\n }\n}\nfunction isErrorEvent(event) {\n return isBuiltin(event, 'ErrorEvent');\n}\nfunction isEvent(candidate) {\n return !isUndefined(Event) && isInstanceOf(candidate, Event);\n}\nfunction isPlainObject(candidate) {\n return isBuiltin(candidate, 'Object');\n}\nconst yesLikeValues = [\n true,\n 'true',\n 1,\n '1',\n 'yes'\n];\nconst isYesLike = (val)=>includes(yesLikeValues, val);\nconst noLikeValues = [\n false,\n 'false',\n 0,\n '0',\n 'no'\n];\nconst isNoLike = (val)=>includes(noLikeValues, val);\nexport { type_utils_hasOwnProperty as hasOwnProperty, isArray, isBoolean, isBuiltin, isEmptyObject, isEmptyString, isError, isErrorEvent, isEvent, isFile, isFormData, isFunction, isInstanceOf, isKnownUnsafeEditableEvent, isNativeFunction, isNoLike, isNull, isNullish, isNumber, isObject, isPlainError, isPlainObject, isPrimitive, isString, isUndefined, isYesLike, noLikeValues, yesLikeValues };\n","import { isNumber } from \"./type-utils.mjs\";\nfunction clampToRange(value, min, max, logger, fallbackValue) {\n if (min > max) {\n logger.warn('min cannot be greater than max.');\n min = max;\n }\n if (isNumber(value)) if (value > max) {\n logger.warn(' cannot be greater than max: ' + max + '. Using max value instead.');\n return max;\n } else {\n if (!(value < min)) return value;\n logger.warn(' cannot be less than min: ' + min + '. Using min value instead.');\n return min;\n }\n logger.warn(' must be a number. using max or fallback. max: ' + max + ', fallback: ' + fallbackValue);\n return clampToRange(fallbackValue || max, min, max, logger);\n}\nexport { clampToRange };\n","import { clampToRange } from \"./number-utils.mjs\";\nconst ONE_DAY_IN_MS = 86400000;\nclass BucketedRateLimiter {\n constructor(options){\n this._buckets = {};\n this._onBucketRateLimited = options._onBucketRateLimited;\n this._bucketSize = clampToRange(options.bucketSize, 0, 100, options._logger);\n this._refillRate = clampToRange(options.refillRate, 0, this._bucketSize, options._logger);\n this._refillInterval = clampToRange(options.refillInterval, 0, ONE_DAY_IN_MS, options._logger);\n }\n _applyRefill(bucket, now) {\n const elapsedMs = now - bucket.lastAccess;\n const refillIntervals = Math.floor(elapsedMs / this._refillInterval);\n if (refillIntervals > 0) {\n const tokensToAdd = refillIntervals * this._refillRate;\n bucket.tokens = Math.min(bucket.tokens + tokensToAdd, this._bucketSize);\n bucket.lastAccess = bucket.lastAccess + refillIntervals * this._refillInterval;\n }\n }\n consumeRateLimit(key) {\n const now = Date.now();\n const keyStr = String(key);\n let bucket = this._buckets[keyStr];\n if (bucket) this._applyRefill(bucket, now);\n else {\n bucket = {\n tokens: this._bucketSize,\n lastAccess: now\n };\n this._buckets[keyStr] = bucket;\n }\n if (0 === bucket.tokens) return true;\n bucket.tokens--;\n if (0 === bucket.tokens) this._onBucketRateLimited?.(key);\n return 0 === bucket.tokens;\n }\n stop() {\n this._buckets = {};\n }\n}\nexport { BucketedRateLimiter };\n","import { includes } from \"./string-utils.mjs\";\nimport { isFunction, isUndefined } from \"./type-utils.mjs\";\nconst FACEBOOK = 'Facebook';\nconst MOBILE = 'Mobile';\nconst IOS = 'iOS';\nconst ANDROID = 'Android';\nconst TABLET = 'Tablet';\nconst ANDROID_TABLET = ANDROID + ' ' + TABLET;\nconst IPAD = 'iPad';\nconst APPLE = 'Apple';\nconst APPLE_WATCH = APPLE + ' Watch';\nconst SAFARI = 'Safari';\nconst BLACKBERRY = 'BlackBerry';\nconst SAMSUNG = 'Samsung';\nconst SAMSUNG_BROWSER = SAMSUNG + 'Browser';\nconst SAMSUNG_INTERNET = SAMSUNG + ' Internet';\nconst CHROME = 'Chrome';\nconst CHROME_OS = CHROME + ' OS';\nconst CHROME_IOS = CHROME + ' ' + IOS;\nconst INTERNET_EXPLORER = 'Internet Explorer';\nconst INTERNET_EXPLORER_MOBILE = INTERNET_EXPLORER + ' ' + MOBILE;\nconst OPERA = 'Opera';\nconst OPERA_MINI = OPERA + ' Mini';\nconst EDGE = 'Edge';\nconst MICROSOFT_EDGE = 'Microsoft ' + EDGE;\nconst FIREFOX = 'Firefox';\nconst FIREFOX_IOS = FIREFOX + ' ' + IOS;\nconst NINTENDO = 'Nintendo';\nconst PLAYSTATION = 'PlayStation';\nconst XBOX = 'Xbox';\nconst ANDROID_MOBILE = ANDROID + ' ' + MOBILE;\nconst MOBILE_SAFARI = MOBILE + ' ' + SAFARI;\nconst WINDOWS = 'Windows';\nconst WINDOWS_PHONE = WINDOWS + ' Phone';\nconst NOKIA = 'Nokia';\nconst OUYA = 'Ouya';\nconst GENERIC = 'Generic';\nconst GENERIC_MOBILE = GENERIC + ' ' + MOBILE.toLowerCase();\nconst GENERIC_TABLET = GENERIC + ' ' + TABLET.toLowerCase();\nconst KONQUEROR = 'Konqueror';\nconst BROWSER_VERSION_REGEX_SUFFIX = '(\\\\d+(\\\\.\\\\d+)?)';\nconst DEFAULT_BROWSER_VERSION_REGEX = new RegExp('Version/' + BROWSER_VERSION_REGEX_SUFFIX);\nconst XBOX_REGEX = new RegExp(XBOX, 'i');\nconst PLAYSTATION_REGEX = new RegExp(PLAYSTATION + ' \\\\w+', 'i');\nconst NINTENDO_REGEX = new RegExp(NINTENDO + ' \\\\w+', 'i');\nconst BLACKBERRY_REGEX = new RegExp(BLACKBERRY + '|PlayBook|BB10', 'i');\nconst windowsVersionMap = {\n 'NT3.51': 'NT 3.11',\n 'NT4.0': 'NT 4.0',\n '5.0': '2000',\n '5.1': 'XP',\n '5.2': 'XP',\n '6.0': 'Vista',\n '6.1': '7',\n '6.2': '8',\n '6.3': '8.1',\n '6.4': '10',\n '10.0': '10'\n};\nfunction isSafari(userAgent) {\n return includes(userAgent, SAFARI) && !includes(userAgent, CHROME) && !includes(userAgent, ANDROID);\n}\nconst safariCheck = (ua, vendor)=>vendor && includes(vendor, APPLE) || isSafari(ua);\nconst detectBrowser = function(user_agent, vendor) {\n vendor = vendor || '';\n if (includes(user_agent, ' OPR/') && includes(user_agent, 'Mini')) return OPERA_MINI;\n if (includes(user_agent, ' OPR/')) return OPERA;\n if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n if (includes(user_agent, 'IE' + MOBILE) || includes(user_agent, 'WPDesktop')) return INTERNET_EXPLORER_MOBILE;\n if (includes(user_agent, SAMSUNG_BROWSER)) return SAMSUNG_INTERNET;\n else if (includes(user_agent, EDGE) || includes(user_agent, 'Edg/')) return MICROSOFT_EDGE;\n else if (includes(user_agent, 'FBIOS')) return FACEBOOK + ' ' + MOBILE;\n else if (includes(user_agent, 'UCWEB') || includes(user_agent, 'UCBrowser')) return 'UC Browser';\n else if (includes(user_agent, 'CriOS')) return CHROME_IOS;\n else if (includes(user_agent, 'CrMo')) return CHROME;\n else if (includes(user_agent, CHROME)) return CHROME;\n else if (includes(user_agent, ANDROID) && includes(user_agent, SAFARI)) return ANDROID_MOBILE;\n else if (includes(user_agent, 'FxiOS')) return FIREFOX_IOS;\n else if (includes(user_agent.toLowerCase(), KONQUEROR.toLowerCase())) return KONQUEROR;\n else if (safariCheck(user_agent, vendor)) return includes(user_agent, MOBILE) ? MOBILE_SAFARI : SAFARI;\n else if (includes(user_agent, FIREFOX)) return FIREFOX;\n else if (includes(user_agent, 'MSIE') || includes(user_agent, 'Trident/')) return INTERNET_EXPLORER;\n else if (includes(user_agent, 'Gecko')) return FIREFOX;\n return '';\n};\nconst versionRegexes = {\n [INTERNET_EXPLORER_MOBILE]: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [MICROSOFT_EDGE]: [\n new RegExp(EDGE + '?\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME]: [\n new RegExp('(' + CHROME + '|CrMo)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME_IOS]: [\n new RegExp('CriOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n 'UC Browser': [\n new RegExp('(UCBrowser|UCWEB)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [MOBILE_SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [OPERA]: [\n new RegExp('(' + OPERA + '|OPR)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX]: [\n new RegExp(FIREFOX + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX_IOS]: [\n new RegExp('FxiOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [KONQUEROR]: [\n new RegExp('Konqueror[:/]?' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [BLACKBERRY]: [\n new RegExp(BLACKBERRY + ' ' + BROWSER_VERSION_REGEX_SUFFIX),\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [ANDROID_MOBILE]: [\n new RegExp('android\\\\s' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [SAMSUNG_INTERNET]: [\n new RegExp(SAMSUNG_BROWSER + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [INTERNET_EXPLORER]: [\n new RegExp('(rv:|MSIE )' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n Mozilla: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ]\n};\nconst detectBrowserVersion = function(userAgent, vendor) {\n const browser = detectBrowser(userAgent, vendor);\n const regexes = versionRegexes[browser];\n if (isUndefined(regexes)) return null;\n for(let i = 0; i < regexes.length; i++){\n const regex = regexes[i];\n const matches = userAgent.match(regex);\n if (matches) return parseFloat(matches[matches.length - 2]);\n }\n return null;\n};\nconst osMatchers = [\n [\n new RegExp(XBOX + '; ' + XBOX + ' (.*?)[);]', 'i'),\n (match)=>[\n XBOX,\n match && match[1] || ''\n ]\n ],\n [\n new RegExp(NINTENDO, 'i'),\n [\n NINTENDO,\n ''\n ]\n ],\n [\n new RegExp(PLAYSTATION, 'i'),\n [\n PLAYSTATION,\n ''\n ]\n ],\n [\n BLACKBERRY_REGEX,\n [\n BLACKBERRY,\n ''\n ]\n ],\n [\n new RegExp(WINDOWS, 'i'),\n (_, user_agent)=>{\n if (/Phone/.test(user_agent) || /WPDesktop/.test(user_agent)) return [\n WINDOWS_PHONE,\n ''\n ];\n if (new RegExp(MOBILE).test(user_agent) && !/IEMobile\\b/.test(user_agent)) return [\n WINDOWS + ' ' + MOBILE,\n ''\n ];\n const match = /Windows NT ([0-9.]+)/i.exec(user_agent);\n if (match && match[1]) {\n const version = match[1];\n let osVersion = windowsVersionMap[version] || '';\n if (/arm/i.test(user_agent)) osVersion = 'RT';\n return [\n WINDOWS,\n osVersion\n ];\n }\n return [\n WINDOWS,\n ''\n ];\n }\n ],\n [\n /((iPhone|iPad|iPod).*?OS (\\d+)_(\\d+)_?(\\d+)?|iPhone)/,\n (match)=>{\n if (match && match[3]) {\n const versionParts = [\n match[3],\n match[4],\n match[5] || '0'\n ];\n return [\n IOS,\n versionParts.join('.')\n ];\n }\n return [\n IOS,\n ''\n ];\n }\n ],\n [\n /(watch.*\\/(\\d+\\.\\d+\\.\\d+)|watch os,(\\d+\\.\\d+),)/i,\n (match)=>{\n let version = '';\n if (match && match.length >= 3) version = isUndefined(match[2]) ? match[3] : match[2];\n return [\n 'watchOS',\n version\n ];\n }\n ],\n [\n new RegExp('(' + ANDROID + ' (\\\\d+)\\\\.(\\\\d+)\\\\.?(\\\\d+)?|' + ANDROID + ')', 'i'),\n (match)=>{\n if (match && match[2]) {\n const versionParts = [\n match[2],\n match[3],\n match[4] || '0'\n ];\n return [\n ANDROID,\n versionParts.join('.')\n ];\n }\n return [\n ANDROID,\n ''\n ];\n }\n ],\n [\n /Mac OS X (\\d+)[_.](\\d+)[_.]?(\\d+)?/i,\n (match)=>{\n const result = [\n 'Mac OS X',\n ''\n ];\n if (match && match[1]) {\n const versionParts = [\n match[1],\n match[2],\n match[3] || '0'\n ];\n result[1] = versionParts.join('.');\n }\n return result;\n }\n ],\n [\n /Mac/i,\n [\n 'Mac OS X',\n ''\n ]\n ],\n [\n /CrOS/,\n [\n CHROME_OS,\n ''\n ]\n ],\n [\n /Linux|debian/i,\n [\n 'Linux',\n ''\n ]\n ]\n];\nconst detectOS = function(user_agent) {\n for(let i = 0; i < osMatchers.length; i++){\n const [rgex, resultOrFn] = osMatchers[i];\n const match = rgex.exec(user_agent);\n const result = match && (isFunction(resultOrFn) ? resultOrFn(match, user_agent) : resultOrFn);\n if (result) return result;\n }\n return [\n '',\n ''\n ];\n};\nconst detectDevice = function(user_agent) {\n if (NINTENDO_REGEX.test(user_agent)) return NINTENDO;\n if (PLAYSTATION_REGEX.test(user_agent)) return PLAYSTATION;\n if (XBOX_REGEX.test(user_agent)) return XBOX;\n if (new RegExp(OUYA, 'i').test(user_agent)) return OUYA;\n if (new RegExp('(' + WINDOWS_PHONE + '|WPDesktop)', 'i').test(user_agent)) return WINDOWS_PHONE;\n else if (/iPad/.test(user_agent)) return IPAD;\n else if (/iPod/.test(user_agent)) return 'iPod Touch';\n else if (/iPhone/.test(user_agent)) return 'iPhone';\n else if (/(watch)(?: ?os[,/]|\\d,\\d\\/)[\\d.]+/i.test(user_agent)) return APPLE_WATCH;\n else if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n else if (/(kobo)\\s(ereader|touch)/i.test(user_agent)) return 'Kobo';\n else if (new RegExp(NOKIA, 'i').test(user_agent)) return NOKIA;\n else if (/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\\))/i.test(user_agent) || /(kf[a-z]+)( bui|\\)).+silk\\//i.test(user_agent)) return 'Kindle Fire';\n else if (/(Android|ZTE)/i.test(user_agent)) if (!(!new RegExp(MOBILE).test(user_agent) || /(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(user_agent))) return ANDROID;\n else {\n if (/pixel[\\daxl ]{1,6}/i.test(user_agent) && !/pixel c/i.test(user_agent) || /(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(user_agent) || /lmy47v/i.test(user_agent) && !/QTAQZ3/i.test(user_agent)) return ANDROID;\n return ANDROID_TABLET;\n }\n else if (new RegExp('(pda|' + MOBILE + ')', 'i').test(user_agent)) return GENERIC_MOBILE;\n else if (new RegExp(TABLET, 'i').test(user_agent) && !new RegExp(TABLET + ' pc', 'i').test(user_agent)) return GENERIC_TABLET;\n else return '';\n};\nconst detectDeviceType = function(user_agent) {\n const device = detectDevice(user_agent);\n if (device === IPAD || device === ANDROID_TABLET || 'Kobo' === device || 'Kindle Fire' === device || device === GENERIC_TABLET) return TABLET;\n if (device === NINTENDO || device === XBOX || device === PLAYSTATION || device === OUYA) return 'Console';\n if (device === APPLE_WATCH) return 'Wearable';\n if (device) return MOBILE;\n return 'Desktop';\n};\nexport { detectBrowser, detectBrowserVersion, detectDevice, detectDeviceType, detectOS };\n","export * from \"./bot-detection.mjs\";\nexport * from \"./bucketed-rate-limiter.mjs\";\nexport * from \"./number-utils.mjs\";\nexport * from \"./string-utils.mjs\";\nexport * from \"./type-utils.mjs\";\nexport * from \"./promise-queue.mjs\";\nexport * from \"./logger.mjs\";\nexport * from \"./user-agent-utils.mjs\";\nconst STRING_FORMAT = 'utf8';\nfunction assert(truthyValue, message) {\n if (!truthyValue || 'string' != typeof truthyValue || isEmpty(truthyValue)) throw new Error(message);\n}\nfunction isEmpty(truthyValue) {\n if (0 === truthyValue.trim().length) return true;\n return false;\n}\nfunction removeTrailingSlash(url) {\n return url?.replace(/\\/+$/, '');\n}\nasync function retriable(fn, props) {\n let lastError = null;\n for(let i = 0; i < props.retryCount + 1; i++){\n if (i > 0) await new Promise((r)=>setTimeout(r, props.retryDelay));\n try {\n const res = await fn();\n return res;\n } catch (e) {\n lastError = e;\n if (!props.retryCheck(e)) throw e;\n }\n }\n throw lastError;\n}\nfunction currentTimestamp() {\n return new Date().getTime();\n}\nfunction currentISOTime() {\n return new Date().toISOString();\n}\nfunction safeSetTimeout(fn, timeout) {\n const t = setTimeout(fn, timeout);\n t?.unref && t?.unref();\n return t;\n}\nconst isPromise = (obj)=>obj && 'function' == typeof obj.then;\nconst isError = (x)=>x instanceof Error;\nfunction getFetch() {\n return 'undefined' != typeof fetch ? fetch : void 0 !== globalThis.fetch ? globalThis.fetch : void 0;\n}\nfunction allSettled(promises) {\n return Promise.all(promises.map((p)=>(p ?? Promise.resolve()).then((value)=>({\n status: 'fulfilled',\n value\n }), (reason)=>({\n status: 'rejected',\n reason\n }))));\n}\nexport { STRING_FORMAT, allSettled, assert, currentISOTime, currentTimestamp, getFetch, isError, isPromise, removeTrailingSlash, retriable, safeSetTimeout };\n","export * from \"./error-properties-builder.mjs\";\nexport * from \"./parsers/index.mjs\";\nexport * from \"./coercers/index.mjs\";\nexport * from \"./utils.mjs\";\n","let parsedStackResults;\nlet lastKeysCount;\nlet cachedFilenameChunkIds;\nfunction getFilenameToChunkIdMap(stackParser) {\n const chunkIdMap = globalThis._posthogChunkIds;\n if (!chunkIdMap) return;\n const chunkIdKeys = Object.keys(chunkIdMap);\n if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;\n lastKeysCount = chunkIdKeys.length;\n cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey)=>{\n if (!parsedStackResults) parsedStackResults = {};\n const result = parsedStackResults[stackKey];\n if (result) acc[result[0]] = result[1];\n else {\n const parsedStack = stackParser(stackKey);\n for(let i = parsedStack.length - 1; i >= 0; i--){\n const stackFrame = parsedStack[i];\n const filename = stackFrame?.filename;\n const chunkId = chunkIdMap[stackKey];\n if (filename && chunkId) {\n acc[filename] = chunkId;\n parsedStackResults[stackKey] = [\n filename,\n chunkId\n ];\n break;\n }\n }\n }\n return acc;\n }, {});\n return cachedFilenameChunkIds;\n}\nexport { getFilenameToChunkIdMap };\n","import { isArray } from \"../utils/index.mjs\";\nimport { getFilenameToChunkIdMap } from \"./chunk-ids.mjs\";\nconst MAX_CAUSE_RECURSION = 4;\nclass ErrorPropertiesBuilder {\n constructor(coercers, stackParser, modifiers = []){\n this.coercers = coercers;\n this.stackParser = stackParser;\n this.modifiers = modifiers;\n }\n buildFromUnknown(input, hint = {}) {\n const providedMechanism = hint && hint.mechanism;\n const mechanism = providedMechanism || {\n handled: true,\n type: 'generic'\n };\n const coercingContext = this.buildCoercingContext(mechanism, hint, 0);\n const exceptionWithCause = coercingContext.apply(input);\n const parsingContext = this.buildParsingContext();\n const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);\n const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);\n return {\n $exception_list: exceptionList,\n $exception_level: 'error'\n };\n }\n async modifyFrames(exceptionList) {\n for (const exc of exceptionList)if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);\n return exceptionList;\n }\n coerceFallback(ctx) {\n return {\n type: 'Error',\n value: 'Unknown error',\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n parseStacktrace(err, ctx) {\n let cause;\n if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);\n let stack;\n if ('' != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? 1 : 0), ctx.chunkIdMap);\n return {\n ...err,\n cause,\n stack\n };\n }\n applyChunkIds(frames, chunkIdMap) {\n return frames.map((frame)=>{\n if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];\n return frame;\n });\n }\n applyCoercers(input, ctx) {\n for (const adapter of this.coercers)if (adapter.match(input)) return adapter.coerce(input, ctx);\n return this.coerceFallback(ctx);\n }\n async applyModifiers(frames) {\n let newFrames = frames;\n for (const modifier of this.modifiers)newFrames = await modifier(newFrames);\n return newFrames;\n }\n convertToExceptionList(exceptionWithStack, mechanism) {\n const currentException = {\n type: exceptionWithStack.type,\n value: exceptionWithStack.value,\n mechanism: {\n type: mechanism.type ?? 'generic',\n handled: mechanism.handled ?? true,\n synthetic: exceptionWithStack.synthetic ?? false\n }\n };\n if (exceptionWithStack.stack) currentException.stacktrace = {\n type: 'raw',\n frames: exceptionWithStack.stack\n };\n const exceptionList = [\n currentException\n ];\n if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {\n ...mechanism,\n handled: true\n }));\n return exceptionList;\n }\n buildParsingContext() {\n const context = {\n chunkIdMap: getFilenameToChunkIdMap(this.stackParser)\n };\n return context;\n }\n buildCoercingContext(mechanism, hint, depth = 0) {\n const coerce = (input, depth)=>{\n if (!(depth <= MAX_CAUSE_RECURSION)) return;\n {\n const ctx = this.buildCoercingContext(mechanism, hint, depth);\n return this.applyCoercers(input, ctx);\n }\n };\n const context = {\n ...hint,\n syntheticException: 0 == depth ? hint.syntheticException : void 0,\n mechanism,\n apply: (input)=>coerce(input, depth),\n next: (input)=>coerce(input, depth + 1)\n };\n return context;\n }\n}\nexport { ErrorPropertiesBuilder };\n","import { isUndefined } from \"../../utils/index.mjs\";\nconst UNKNOWN_FUNCTION = '?';\nfunction createFrame(platform, filename, func, lineno, colno) {\n const frame = {\n platform,\n filename,\n function: '<anonymous>' === func ? UNKNOWN_FUNCTION : func,\n in_app: true\n };\n if (!isUndefined(lineno)) frame.lineno = lineno;\n if (!isUndefined(colno)) frame.colno = colno;\n return frame;\n}\nexport { UNKNOWN_FUNCTION, createFrame };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nconst extractSafariExtensionDetails = (func, filename)=>{\n const isSafariExtension = -1 !== func.indexOf('safari-extension');\n const isSafariWebExtension = -1 !== func.indexOf('safari-web-extension');\n return isSafariExtension || isSafariWebExtension ? [\n -1 !== func.indexOf('@') ? func.split('@')[0] : UNKNOWN_FUNCTION,\n isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`\n ] : [\n func,\n filename\n ];\n};\nexport { extractSafariExtensionDetails };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst chromeRegexNoFnName = /^\\s*at (\\S+?)(?::(\\d+))(?::(\\d+))\\s*$/i;\nconst chromeRegex = /^\\s*at (?:(.+?\\)(?: \\[.+\\])?|.*?) ?\\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\\/)?.*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\nconst chromeEvalRegex = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\nconst chromeStackLineParser = (line, platform)=>{\n const noFnParts = chromeRegexNoFnName.exec(line);\n if (noFnParts) {\n const [, filename, line, col] = noFnParts;\n return createFrame(platform, filename, UNKNOWN_FUNCTION, +line, +col);\n }\n const parts = chromeRegex.exec(line);\n if (parts) {\n const isEval = parts[2] && 0 === parts[2].indexOf('eval');\n if (isEval) {\n const subMatch = chromeEvalRegex.exec(parts[2]);\n if (subMatch) {\n parts[2] = subMatch[1];\n parts[3] = subMatch[2];\n parts[4] = subMatch[3];\n }\n }\n const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);\n return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);\n }\n};\nexport { chromeStackLineParser };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nconst winjsRegex = /^\\s*at (?:((?:\\[object object\\])?.+) )?\\(?((?:[-a-z]+):.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i;\nconst winjsStackLineParser = (line, platform)=>{\n const parts = winjsRegex.exec(line);\n return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : void 0) : void 0;\n};\nexport { winjsStackLineParser };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst geckoREgex = /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)?((?:[-a-z]+)?:\\/.*?|\\[native code\\]|[^@]*(?:bundle|\\d+\\.js)|\\/[\\w\\-. /=]+)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\nconst geckoEvalRegex = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\nconst geckoStackLineParser = (line, platform)=>{\n const parts = geckoREgex.exec(line);\n if (parts) {\n const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n if (isEval) {\n const subMatch = geckoEvalRegex.exec(parts[3]);\n if (subMatch) {\n parts[1] = parts[1] || 'eval';\n parts[3] = subMatch[1];\n parts[4] = subMatch[2];\n parts[5] = '';\n }\n }\n let filename = parts[3];\n let func = parts[1] || UNKNOWN_FUNCTION;\n [func, filename] = extractSafariExtensionDetails(func, filename);\n return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);\n }\n};\nexport { geckoStackLineParser };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nconst opera10Regex = / line (\\d+).*script (?:in )?(\\S+)(?:: in function (\\S+))?$/i;\nconst opera10StackLineParser = (line, platform)=>{\n const parts = opera10Regex.exec(line);\n return parts ? createFrame(platform, parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : void 0;\n};\nconst opera11Regex = / line (\\d+), column (\\d+)\\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\\(.*\\))? in (.*):\\s*$/i;\nconst opera11StackLineParser = (line, platform)=>{\n const parts = opera11Regex.exec(line);\n return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : void 0;\n};\nexport { opera10StackLineParser, opera11StackLineParser };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nconst FILENAME_MATCH = /^\\s*[-]{4,}$/;\nconst FULL_MATCH = /at (?:async )?(?:(.+?)\\s+\\()?(?:(.+):(\\d+):(\\d+)?|([^)]+))\\)?/;\nconst nodeStackLineParser = (line, platform)=>{\n const lineMatch = line.match(FULL_MATCH);\n if (lineMatch) {\n let object;\n let method;\n let functionName;\n let typeName;\n let methodName;\n if (lineMatch[1]) {\n functionName = lineMatch[1];\n let methodStart = functionName.lastIndexOf('.');\n if ('.' === functionName[methodStart - 1]) methodStart--;\n if (methodStart > 0) {\n object = functionName.slice(0, methodStart);\n method = functionName.slice(methodStart + 1);\n const objectEnd = object.indexOf('.Module');\n if (objectEnd > 0) {\n functionName = functionName.slice(objectEnd + 1);\n object = object.slice(0, objectEnd);\n }\n }\n typeName = void 0;\n }\n if (method) {\n typeName = object;\n methodName = method;\n }\n if ('<anonymous>' === method) {\n methodName = void 0;\n functionName = void 0;\n }\n if (void 0 === functionName) {\n methodName = methodName || UNKNOWN_FUNCTION;\n functionName = typeName ? `${typeName}.${methodName}` : methodName;\n }\n let filename = lineMatch[2]?.startsWith('file://') ? lineMatch[2].slice(7) : lineMatch[2];\n const isNative = 'native' === lineMatch[5];\n if (filename?.match(/\\/[A-Z]:/)) filename = filename.slice(1);\n if (!filename && lineMatch[5] && !isNative) filename = lineMatch[5];\n return {\n filename: filename ? decodeURI(filename) : void 0,\n module: void 0,\n function: functionName,\n lineno: _parseIntOrUndefined(lineMatch[3]),\n colno: _parseIntOrUndefined(lineMatch[4]),\n in_app: filenameIsInApp(filename || '', isNative),\n platform: platform\n };\n }\n if (line.match(FILENAME_MATCH)) return {\n filename: line,\n platform: platform\n };\n};\nfunction filenameIsInApp(filename, isNative = false) {\n const isInternal = isNative || filename && !filename.startsWith('/') && !filename.match(/^[A-Z]:/) && !filename.startsWith('.') && !filename.match(/^[a-zA-Z]([a-zA-Z0-9.\\-+])*:\\/\\//);\n return !isInternal && void 0 !== filename && !filename.includes('node_modules/');\n}\nfunction _parseIntOrUndefined(input) {\n return parseInt(input || '', 10) || void 0;\n}\nexport { nodeStackLineParser };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nimport { chromeStackLineParser } from \"./chrome.mjs\";\nimport { winjsStackLineParser } from \"./winjs.mjs\";\nimport { geckoStackLineParser } from \"./gecko.mjs\";\nimport { opera10StackLineParser, opera11StackLineParser } from \"./opera.mjs\";\nimport { nodeStackLineParser } from \"./node.mjs\";\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STACKTRACE_FRAME_LIMIT = 50;\nfunction reverseAndStripFrames(stack) {\n if (!stack.length) return [];\n const localStack = Array.from(stack);\n localStack.reverse();\n return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame)=>({\n ...frame,\n filename: frame.filename || getLastStackFrame(localStack).filename,\n function: frame.function || UNKNOWN_FUNCTION\n }));\n}\nfunction getLastStackFrame(arr) {\n return arr[arr.length - 1] || {};\n}\nfunction createStackParser(platform, ...parsers) {\n return (stack, skipFirstLines = 0)=>{\n const frames = [];\n const lines = stack.split('\\n');\n for(let i = skipFirstLines; i < lines.length; i++){\n const line = lines[i];\n if (line.length > 1024) continue;\n const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n if (!cleanedLine.match(/\\S*Error: /)) {\n for (const parser of parsers){\n const frame = parser(cleanedLine, platform);\n if (frame) {\n frames.push(frame);\n break;\n }\n }\n if (frames.length >= STACKTRACE_FRAME_LIMIT) break;\n }\n }\n return reverseAndStripFrames(frames);\n };\n}\nexport { chromeStackLineParser, createStackParser, geckoStackLineParser, nodeStackLineParser, opera10StackLineParser, opera11StackLineParser, reverseAndStripFrames, winjsStackLineParser };\n","import { isBuiltin, isString } from \"../../utils/index.mjs\";\nclass DOMExceptionCoercer {\n match(err) {\n return this.isDOMException(err) || this.isDOMError(err);\n }\n coerce(err, ctx) {\n const hasStack = isString(err.stack);\n return {\n type: this.getType(err),\n value: this.getValue(err),\n stack: hasStack ? err.stack : void 0,\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(candidate) {\n return this.isDOMError(candidate) ? 'DOMError' : 'DOMException';\n }\n getValue(err) {\n const name = err.name || (this.isDOMError(err) ? 'DOMError' : 'DOMException');\n const message = err.message ? `${name}: ${err.message}` : name;\n return message;\n }\n isDOMException(err) {\n return isBuiltin(err, 'DOMException');\n }\n isDOMError(err) {\n return isBuiltin(err, 'DOMError');\n }\n}\nexport { DOMExceptionCoercer };\n","import { isPlainError } from \"../../utils/index.mjs\";\nclass ErrorCoercer {\n match(err) {\n return isPlainError(err);\n }\n coerce(err, ctx) {\n return {\n type: this.getType(err),\n value: this.getMessage(err, ctx),\n stack: this.getStack(err),\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(err) {\n return err.name || err.constructor.name;\n }\n getMessage(err, _ctx) {\n const message = err.message;\n if (message.error && 'string' == typeof message.error.message) return String(message.error.message);\n return String(message);\n }\n getStack(err) {\n return err.stacktrace || err.stack || void 0;\n }\n}\nexport { ErrorCoercer };\n","import { isErrorEvent } from \"../../utils/index.mjs\";\nclass ErrorEventCoercer {\n constructor(){}\n match(err) {\n return isErrorEvent(err) && void 0 != err.error;\n }\n coerce(err, ctx) {\n const exceptionLike = ctx.apply(err.error);\n if (!exceptionLike) return {\n type: 'ErrorEvent',\n value: err.message,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return exceptionLike;\n }\n}\nexport { ErrorEventCoercer };\n","const ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;\nclass StringCoercer {\n match(input) {\n return 'string' == typeof input;\n }\n coerce(input, ctx) {\n const [type, value] = this.getInfos(input);\n return {\n type: type ?? 'Error',\n value: value ?? input,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n getInfos(candidate) {\n let type = 'Error';\n let value = candidate;\n const groups = candidate.match(ERROR_TYPES_PATTERN);\n if (groups) {\n type = groups[1];\n value = groups[2];\n }\n return [\n type,\n value\n ];\n }\n}\nexport { StringCoercer };\n","const severityLevels = [\n 'fatal',\n 'error',\n 'warning',\n 'log',\n 'info',\n 'debug'\n];\nexport { severityLevels };\n","function truncate(str, max = 0) {\n if ('string' != typeof str || 0 === max) return str;\n return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\nfunction extractExceptionKeysForMessage(err, maxLength = 40) {\n const keys = Object.keys(err);\n keys.sort();\n if (!keys.length) return '[object has no keys]';\n for(let i = keys.length; i > 0; i--){\n const serialized = keys.slice(0, i).join(', ');\n if (!(serialized.length > maxLength)) {\n if (i === keys.length) return serialized;\n return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;\n }\n }\n return '';\n}\nexport { extractExceptionKeysForMessage, truncate };\n","import { isEmptyString, isError, isEvent, isString } from \"../../utils/index.mjs\";\nimport { severityLevels } from \"../types.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass ObjectCoercer {\n match(candidate) {\n return 'object' == typeof candidate && null !== candidate;\n }\n coerce(candidate, ctx) {\n const errorProperty = this.getErrorPropertyFromObject(candidate);\n if (errorProperty) return ctx.apply(errorProperty);\n return {\n type: this.getType(candidate),\n value: this.getValue(candidate),\n stack: ctx.syntheticException?.stack,\n level: this.isSeverityLevel(candidate.level) ? candidate.level : 'error',\n synthetic: true\n };\n }\n getType(err) {\n return isEvent(err) ? err.constructor.name : 'Error';\n }\n getValue(err) {\n if ('name' in err && 'string' == typeof err.name) {\n let message = `'${err.name}' captured as exception`;\n if ('message' in err && 'string' == typeof err.message) message += ` with message: '${err.message}'`;\n return message;\n }\n if ('message' in err && 'string' == typeof err.message) return err.message;\n const className = this.getObjectClassName(err);\n const keys = extractExceptionKeysForMessage(err);\n return `${className && 'Object' !== className ? `'${className}'` : 'Object'} captured as exception with keys: ${keys}`;\n }\n isSeverityLevel(x) {\n return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;\n }\n getErrorPropertyFromObject(obj) {\n for(const prop in obj)if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n const value = obj[prop];\n if (isError(value)) return value;\n }\n }\n getObjectClassName(obj) {\n try {\n const prototype = Object.getPrototypeOf(obj);\n return prototype ? prototype.constructor.name : void 0;\n } catch (e) {\n return;\n }\n }\n}\nexport { ObjectCoercer };\n","import { isEvent } from \"../../utils/index.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass EventCoercer {\n match(err) {\n return isEvent(err);\n }\n coerce(evt, ctx) {\n const constructorName = evt.constructor.name;\n return {\n type: constructorName,\n value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { EventCoercer };\n","import { isPrimitive } from \"../../utils/index.mjs\";\nclass PrimitiveCoercer {\n match(candidate) {\n return isPrimitive(candidate);\n }\n coerce(value, ctx) {\n return {\n type: 'Error',\n value: `Primitive value captured as exception: ${String(value)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { PrimitiveCoercer };\n","import { isBuiltin, isPrimitive } from \"../../utils/index.mjs\";\nclass PromiseRejectionEventCoercer {\n match(err) {\n return isBuiltin(err, 'PromiseRejectionEvent');\n }\n coerce(err, ctx) {\n const reason = this.getUnhandledRejectionReason(err);\n if (isPrimitive(reason)) return {\n type: 'UnhandledRejection',\n value: `Non-Error promise rejection captured with value: ${String(reason)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return ctx.apply(reason);\n }\n getUnhandledRejectionReason(error) {\n if (isPrimitive(error)) return error;\n try {\n if ('reason' in error) return error.reason;\n if ('detail' in error && 'reason' in error.detail) return error.detail.reason;\n } catch {}\n return error;\n }\n}\nexport { PromiseRejectionEventCoercer };\n","class ReduceableCache {\n constructor(_maxSize){\n this._maxSize = _maxSize;\n this._cache = new Map();\n }\n get(key) {\n const value = this._cache.get(key);\n if (void 0 === value) return;\n this._cache.delete(key);\n this._cache.set(key, value);\n return value;\n }\n set(key, value) {\n this._cache.set(key, value);\n }\n reduce() {\n while(this._cache.size >= this._maxSize){\n const value = this._cache.keys().next().value;\n if (value) this._cache.delete(value);\n }\n }\n}\nexport { ReduceableCache };\n","import { ErrorTracking } from \"@posthog/core\";\nimport { createReadStream } from \"node:fs\";\nimport { createInterface } from \"node:readline\";\nconst LRU_FILE_CONTENTS_CACHE = new ErrorTracking.ReduceableCache(25);\nconst LRU_FILE_CONTENTS_FS_READ_FAILED = new ErrorTracking.ReduceableCache(20);\nconst DEFAULT_LINES_OF_CONTEXT = 7;\nconst MAX_CONTEXTLINES_COLNO = 1000;\nconst MAX_CONTEXTLINES_LINENO = 10000;\nasync function addSourceContext(frames) {\n const filesToLines = {};\n for(let i = frames.length - 1; i >= 0; i--){\n const frame = frames[i];\n const filename = frame?.filename;\n if (!frame || 'string' != typeof filename || 'number' != typeof frame.lineno || shouldSkipContextLinesForFile(filename) || shouldSkipContextLinesForFrame(frame)) continue;\n const filesToLinesOutput = filesToLines[filename];\n if (!filesToLinesOutput) filesToLines[filename] = [];\n filesToLines[filename].push(frame.lineno);\n }\n const files = Object.keys(filesToLines);\n if (0 == files.length) return frames;\n const readlinePromises = [];\n for (const file of files){\n if (LRU_FILE_CONTENTS_FS_READ_FAILED.get(file)) continue;\n const filesToLineRanges = filesToLines[file];\n if (!filesToLineRanges) continue;\n filesToLineRanges.sort((a, b)=>a - b);\n const ranges = makeLineReaderRanges(filesToLineRanges);\n if (ranges.every((r)=>rangeExistsInContentCache(file, r))) continue;\n const cache = emplace(LRU_FILE_CONTENTS_CACHE, file, {});\n readlinePromises.push(getContextLinesFromFile(file, ranges, cache));\n }\n await Promise.all(readlinePromises).catch(()=>{});\n if (frames && frames.length > 0) addSourceContextToFrames(frames, LRU_FILE_CONTENTS_CACHE);\n LRU_FILE_CONTENTS_CACHE.reduce();\n return frames;\n}\nfunction getContextLinesFromFile(path, ranges, output) {\n return new Promise((resolve)=>{\n const stream = createReadStream(path);\n const lineReaded = createInterface({\n input: stream\n });\n function destroyStreamAndResolve() {\n stream.destroy();\n resolve();\n }\n let lineNumber = 0;\n let currentRangeIndex = 0;\n const range = ranges[currentRangeIndex];\n if (void 0 === range) return void destroyStreamAndResolve();\n let rangeStart = range[0];\n let rangeEnd = range[1];\n function onStreamError() {\n LRU_FILE_CONTENTS_FS_READ_FAILED.set(path, 1);\n lineReaded.close();\n lineReaded.removeAllListeners();\n destroyStreamAndResolve();\n }\n stream.on('error', onStreamError);\n lineReaded.on('error', onStreamError);\n lineReaded.on('close', destroyStreamAndResolve);\n lineReaded.on('line', (line)=>{\n lineNumber++;\n if (lineNumber < rangeStart) return;\n output[lineNumber] = snipLine(line, 0);\n if (lineNumber >= rangeEnd) {\n if (currentRangeIndex === ranges.length - 1) {\n lineReaded.close();\n lineReaded.removeAllListeners();\n return;\n }\n currentRangeIndex++;\n const range = ranges[currentRangeIndex];\n if (void 0 === range) {\n lineReaded.close();\n lineReaded.removeAllListeners();\n return;\n }\n rangeStart = range[0];\n rangeEnd = range[1];\n }\n });\n });\n}\nfunction addSourceContextToFrames(frames, cache) {\n for (const frame of frames)if (frame.filename && void 0 === frame.context_line && 'number' == typeof frame.lineno) {\n const contents = cache.get(frame.filename);\n if (void 0 === contents) continue;\n addContextToFrame(frame.lineno, frame, contents);\n }\n}\nfunction addContextToFrame(lineno, frame, contents) {\n if (void 0 === frame.lineno || void 0 === contents) return;\n frame.pre_context = [];\n for(let i = makeRangeStart(lineno); i < lineno; i++){\n const line = contents[i];\n if (void 0 === line) return void clearLineContext(frame);\n frame.pre_context.push(line);\n }\n if (void 0 === contents[lineno]) return void clearLineContext(frame);\n frame.context_line = contents[lineno];\n const end = makeRangeEnd(lineno);\n frame.post_context = [];\n for(let i = lineno + 1; i <= end; i++){\n const line = contents[i];\n if (void 0 === line) break;\n frame.post_context.push(line);\n }\n}\nfunction clearLineContext(frame) {\n delete frame.pre_context;\n delete frame.context_line;\n delete frame.post_context;\n}\nfunction shouldSkipContextLinesForFile(path) {\n return path.startsWith('node:') || path.endsWith('.min.js') || path.endsWith('.min.cjs') || path.endsWith('.min.mjs') || path.startsWith('data:');\n}\nfunction shouldSkipContextLinesForFrame(frame) {\n if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;\n if (void 0 !== frame.colno && frame.colno > MAX_CONTEXTLINES_COLNO) return true;\n return false;\n}\nfunction rangeExistsInContentCache(file, range) {\n const contents = LRU_FILE_CONTENTS_CACHE.get(file);\n if (void 0 === contents) return false;\n for(let i = range[0]; i <= range[1]; i++)if (void 0 === contents[i]) return false;\n return true;\n}\nfunction makeLineReaderRanges(lines) {\n if (!lines.length) return [];\n let i = 0;\n const line = lines[0];\n if ('number' != typeof line) return [];\n let current = makeContextRange(line);\n const out = [];\n while(true){\n if (i === lines.length - 1) {\n out.push(current);\n break;\n }\n const next = lines[i + 1];\n if ('number' != typeof next) break;\n if (next <= current[1]) current[1] = next + DEFAULT_LINES_OF_CONTEXT;\n else {\n out.push(current);\n current = makeContextRange(next);\n }\n i++;\n }\n return out;\n}\nfunction makeContextRange(line) {\n return [\n makeRangeStart(line),\n makeRangeEnd(line)\n ];\n}\nfunction makeRangeStart(line) {\n return Math.max(1, line - DEFAULT_LINES_OF_CONTEXT);\n}\nfunction makeRangeEnd(line) {\n return line + DEFAULT_LINES_OF_CONTEXT;\n}\nfunction emplace(map, key, contents) {\n const value = map.get(key);\n if (void 0 === value) {\n map.set(key, contents);\n return contents;\n }\n return value;\n}\nfunction snipLine(line, colno) {\n let newLine = line;\n const lineLength = newLine.length;\n if (lineLength <= 150) return newLine;\n if (colno > lineLength) colno = lineLength;\n let start = Math.max(colno - 60, 0);\n if (start < 5) start = 0;\n let end = Math.min(start + 140, lineLength);\n if (end > lineLength - 5) end = lineLength;\n if (end === lineLength) start = Math.max(end - 140, 0);\n newLine = newLine.slice(start, end);\n if (start > 0) newLine = `...${newLine}`;\n if (end < lineLength) newLine += '...';\n return newLine;\n}\nexport { MAX_CONTEXTLINES_COLNO, MAX_CONTEXTLINES_LINENO, addSourceContext };\n","function makeUncaughtExceptionHandler(captureFn, onFatalFn) {\n let calledFatalError = false;\n return Object.assign((error)=>{\n const userProvidedListenersCount = global.process.listeners('uncaughtException').filter((listener)=>'domainUncaughtExceptionClear' !== listener.name && true !== listener._posthogErrorHandler).length;\n const processWouldExit = 0 === userProvidedListenersCount;\n captureFn(error, {\n mechanism: {\n type: 'onuncaughtexception',\n handled: false\n }\n });\n if (!calledFatalError && processWouldExit) {\n calledFatalError = true;\n onFatalFn(error);\n }\n }, {\n _posthogErrorHandler: true\n });\n}\nfunction addUncaughtExceptionListener(captureFn, onFatalFn) {\n globalThis.process?.on('uncaughtException', makeUncaughtExceptionHandler(captureFn, onFatalFn));\n}\nfunction addUnhandledRejectionListener(captureFn) {\n globalThis.process?.on('unhandledRejection', (reason)=>captureFn(reason, {\n mechanism: {\n type: 'onunhandledrejection',\n handled: false\n }\n }));\n}\nexport { addUncaughtExceptionListener, addUnhandledRejectionListener };\n","import { addUncaughtExceptionListener, addUnhandledRejectionListener } from \"./autocapture.mjs\";\nimport { BucketedRateLimiter, uuidv7 } from \"@posthog/core\";\nconst SHUTDOWN_TIMEOUT = 2000;\nclass ErrorTracking {\n constructor(client, options, _logger){\n this.client = client;\n this._exceptionAutocaptureEnabled = options.enableExceptionAutocapture || false;\n this._logger = _logger;\n this._rateLimiter = new BucketedRateLimiter({\n refillRate: 1,\n bucketSize: 10,\n refillInterval: 10000,\n _logger: this._logger\n });\n this.startAutocaptureIfEnabled();\n }\n static async buildEventMessage(error, hint, distinctId, additionalProperties) {\n const properties = {\n ...additionalProperties\n };\n if (!distinctId) properties.$process_person_profile = false;\n const exceptionProperties = this.errorPropertiesBuilder.buildFromUnknown(error, hint);\n exceptionProperties.$exception_list = await this.errorPropertiesBuilder.modifyFrames(exceptionProperties.$exception_list);\n return {\n event: '$exception',\n distinctId: distinctId || uuidv7(),\n properties: {\n ...exceptionProperties,\n ...properties\n }\n };\n }\n startAutocaptureIfEnabled() {\n if (this.isEnabled()) {\n addUncaughtExceptionListener(this.onException.bind(this), this.onFatalError.bind(this));\n addUnhandledRejectionListener(this.onException.bind(this));\n }\n }\n onException(exception, hint) {\n this.client.addPendingPromise((async ()=>{\n const eventMessage = await ErrorTracking.buildEventMessage(exception, hint);\n const exceptionProperties = eventMessage.properties;\n const exceptionType = exceptionProperties?.$exception_list[0]?.type ?? 'Exception';\n const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType);\n if (isRateLimited) return void this._logger.info('Skipping exception capture because of client rate limiting.', {\n exception: exceptionType\n });\n return this.client.capture(eventMessage);\n })());\n }\n async onFatalError(exception) {\n console.error(exception);\n await this.client.shutdown(SHUTDOWN_TIMEOUT);\n process.exit(1);\n }\n isEnabled() {\n return !this.client.isDisabled && this._exceptionAutocaptureEnabled;\n }\n shutdown() {\n this._rateLimiter.stop();\n }\n}\nexport { ErrorTracking as default };\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nclass PostHogContext {\n constructor(){\n this.storage = new AsyncLocalStorage();\n }\n get() {\n return this.storage.getStore();\n }\n run(context, fn, options) {\n const fresh = options?.fresh === true;\n if (fresh) return this.storage.run(context, fn);\n {\n const currentContext = this.get() || {};\n const mergedContext = {\n distinctId: context.distinctId ?? currentContext.distinctId,\n sessionId: context.sessionId ?? currentContext.sessionId,\n properties: {\n ...currentContext.properties || {},\n ...context.properties || {}\n }\n };\n return this.storage.run(mergedContext, fn);\n }\n }\n}\nexport { PostHogContext };\n","const NAME = 'posthog-node';\nfunction createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList = [\n 'error'\n], sendExceptionsToPostHog = true } = {}) {\n return (event)=>{\n const shouldProcessLevel = '*' === severityAllowList || severityAllowList.includes(event.level);\n if (!shouldProcessLevel) return event;\n if (!event.tags) event.tags = {};\n const userId = event.tags[PostHogSentryIntegration.POSTHOG_ID_TAG];\n if (void 0 === userId) return event;\n const uiHost = _posthog.options.host ?? 'https://us.i.posthog.com';\n const personUrl = new URL(`/project/${_posthog.apiKey}/person/${userId}`, uiHost).toString();\n event.tags['PostHog Person URL'] = personUrl;\n const exceptions = event.exception?.values || [];\n const exceptionList = exceptions.map((exception)=>({\n ...exception,\n stacktrace: exception.stacktrace ? {\n ...exception.stacktrace,\n type: 'raw',\n frames: (exception.stacktrace.frames || []).map((frame)=>({\n ...frame,\n platform: \"node:javascript\"\n }))\n } : void 0\n }));\n const properties = {\n $exception_message: exceptions[0]?.value || event.message,\n $exception_type: exceptions[0]?.type,\n $exception_level: event.level,\n $exception_list: exceptionList,\n $sentry_event_id: event.event_id,\n $sentry_exception: event.exception,\n $sentry_exception_message: exceptions[0]?.value || event.message,\n $sentry_exception_type: exceptions[0]?.type,\n $sentry_tags: event.tags\n };\n if (organization && projectId) properties['$sentry_url'] = (prefix || 'https://sentry.io/organizations/') + organization + '/issues/?project=' + projectId + '&query=' + event.event_id;\n if (sendExceptionsToPostHog) _posthog.capture({\n event: '$exception',\n distinctId: userId,\n properties\n });\n return event;\n };\n}\nfunction sentryIntegration(_posthog, options) {\n const processor = createEventProcessor(_posthog, options);\n return {\n name: NAME,\n processEvent (event) {\n return processor(event);\n }\n };\n}\nclass PostHogSentryIntegration {\n static #_ = this.POSTHOG_ID_TAG = 'posthog_distinct_id';\n constructor(_posthog, organization, prefix, severityAllowList, sendExceptionsToPostHog){\n this.name = NAME;\n this.name = NAME;\n this.setupOnce = function(addGlobalEventProcessor, getCurrentHub) {\n const projectId = getCurrentHub()?.getClient()?.getDsn()?.projectId;\n addGlobalEventProcessor(createEventProcessor(_posthog, {\n organization,\n projectId,\n prefix,\n severityAllowList,\n sendExceptionsToPostHog: sendExceptionsToPostHog ?? true\n }));\n };\n }\n}\nexport { PostHogSentryIntegration, createEventProcessor, sentryIntegration };\n","import { createModulerModifier } from \"../extensions/error-tracking/modifiers/module.node.mjs\";\nimport { addSourceContext } from \"../extensions/error-tracking/modifiers/context-lines.node.mjs\";\nimport error_tracking from \"../extensions/error-tracking/index.mjs\";\nimport { PostHogBackendClient } from \"../client.mjs\";\nimport { ErrorTracking } from \"@posthog/core\";\nimport { PostHogContext } from \"../extensions/context/context.mjs\";\nexport * from \"../exports.mjs\";\nerror_tracking.errorPropertiesBuilder = new ErrorTracking.ErrorPropertiesBuilder([\n new ErrorTracking.EventCoercer(),\n new ErrorTracking.ErrorCoercer(),\n new ErrorTracking.ObjectCoercer(),\n new ErrorTracking.StringCoercer(),\n new ErrorTracking.PrimitiveCoercer()\n], ErrorTracking.createStackParser(\"node:javascript\", ErrorTracking.nodeStackLineParser), [\n createModulerModifier(),\n addSourceContext\n]);\nclass PostHog extends PostHogBackendClient {\n getLibraryId() {\n return 'posthog-node';\n }\n initializeContext() {\n return new PostHogContext();\n }\n}\nexport { PostHog };\n","/**\n * Native Messaging 协议层\n * Chrome Native Messaging 使用 32 位小端长度前缀 + UTF-8 JSON\n */\n\n/**\n * 编码消息为 Native Messaging 格式\n * 格式: [4字节长度(小端)] + [JSON字符串]\n */\nexport function encodeMessage(message: unknown): Buffer {\n const json = JSON.stringify(message)\n const body = Buffer.from(json, 'utf-8')\n const header = Buffer.alloc(4)\n header.writeUInt32LE(body.length, 0)\n return Buffer.concat([header, body])\n}\n\n/**\n * 从 Buffer 解码消息\n * 返回: { message, remaining } 或 null(数据不完整)\n */\nexport function decodeMessage(buffer: Buffer): { message: unknown; remaining: Buffer } | null {\n if (buffer.length < 4) return null\n\n const length = buffer.readUInt32LE(0)\n\n // Chrome Native Messaging 消息最大 1MB\n if (length > 1024 * 1024) {\n throw new Error(`消息过大: ${length} 字节(最大 1MB)`)\n }\n\n if (buffer.length < 4 + length) return null\n\n const json = buffer.subarray(4, 4 + length).toString('utf-8')\n const message = JSON.parse(json)\n const remaining = Buffer.from(buffer.subarray(4 + length))\n\n return { message, remaining }\n}\n"],"mappings":"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","names":["data","Receiver","Sender","Event","URL","Receiver","Sender","WebSocket","key","WebSocket","createWebSocketStream","err","protocol","WebSocket","WebSocketServer","version","fileURLToPath","dirname","join","existsSync","mkdirSync","dirname","readFileSync","existsSync","dirname","join","dirname","version","depth","line","resolve","range","fileURLToPath","dirname","join","resolve","running","info"]}
|