@undefineds.co/xpod 0.3.56 → 0.3.58
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/api/container/index.js +3 -0
- package/dist/api/container/index.js.map +1 -1
- package/dist/api/container/local.js +53 -13
- package/dist/api/container/local.js.map +1 -1
- package/dist/api/container/types.d.ts +6 -0
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/AdminHandler.d.ts +15 -0
- package/dist/api/handlers/AdminHandler.js +128 -7
- package/dist/api/handlers/AdminHandler.js.map +1 -1
- package/dist/cli/commands/obj.d.ts +45 -0
- package/dist/cli/commands/obj.js +309 -33
- package/dist/cli/commands/obj.js.map +1 -1
- package/dist/components/components.jsonld +1 -0
- package/dist/components/context.jsonld +36 -0
- package/dist/edge/DdnsManager.d.ts +1 -1
- package/dist/edge/DdnsManager.js.map +1 -1
- package/dist/edge/reachability/P2PRealnetAcceptance.js +4 -3
- package/dist/edge/reachability/P2PRealnetAcceptance.js.map +1 -1
- package/dist/edge/reachability/TcpP2PSignalingSession.js +26 -17
- package/dist/edge/reachability/TcpP2PSignalingSession.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/tunnel/NgrokTunnelProvider.d.ts +46 -0
- package/dist/tunnel/NgrokTunnelProvider.js +344 -0
- package/dist/tunnel/NgrokTunnelProvider.js.map +1 -0
- package/dist/tunnel/NgrokTunnelProvider.jsonld +215 -0
- package/dist/tunnel/TunnelProvider.d.ts +2 -2
- package/dist/tunnel/TunnelProvider.js.map +1 -1
- package/dist/tunnel/index.d.ts +1 -0
- package/dist/tunnel/index.js +3 -1
- package/dist/tunnel/index.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.d.ts +62 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.js +197 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.d.ts +62 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.js +197 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/pod.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/pod.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/package.json +1 -1
- package/package.json +10 -6
- package/static/app/assets/{index-AaQ1qxhy.js → index-C1yksyT4.js} +28 -28
- package/static/app/assets/inrupt-smoke.js +2 -2
- package/static/app/assets/main.css +1 -1
- package/static/app/assets/main.js +10 -50
- package/static/dashboard/assets/dashboard-BssaVKTn.css +1 -0
- package/static/dashboard/assets/dashboard-Ckuadl3C.js +54 -0
- package/static/dashboard/dashboard.html +2 -2
- package/static/dashboard/reachability.html +221 -0
- package/static/dashboard/reachability.svg +7 -0
- package/static/dashboard/reachability.webmanifest +18 -0
- package/static/dashboard/signal-pod.html +293 -0
- package/static/dashboard/assets/dashboard-CTk9cn1-.js +0 -52
- package/static/dashboard/assets/dashboard-VQRsvXx9.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/AdminHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Admin API Handler\n * Provides configuration management, restart functionality, and log streaming\n */\n\nimport type { ServerResponse } from 'node:http';\nimport type { ApiServer, RouteHandler } from '../ApiServer';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport fs from 'fs';\nimport path from 'path';\nimport { createReadStream, statSync } from 'fs';\nimport { createInterface } from 'readline';\nimport { PACKAGE_ROOT } from '../../runtime';\n\nconst CONFIG_DIR = path.resolve(PACKAGE_ROOT, 'config');\n\nfunction getEnvFilePath(): string {\n const envPath = process.env.XPOD_ENV_PATH;\n if (envPath && envPath.trim()) {\n return path.resolve(envPath);\n }\n return path.resolve(process.cwd(), '.env.local');\n}\n\ninterface ConfigFile {\n name: string;\n path: string;\n exists: boolean;\n}\n\ninterface EnvConfig {\n [key: string]: string;\n}\n\n/**\n * Read .env.local file and parse it\n */\nfunction readEnvFile(filePath: string): EnvConfig {\n const config: EnvConfig = {};\n if (!fs.existsSync(filePath)) {\n return config;\n }\n const content = fs.readFileSync(filePath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n // Remove quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n config[key] = value;\n }\n return config;\n}\n\n/**\n * Write .env.local file\n */\nfunction writeEnvFile(filePath: string, config: EnvConfig): void {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(config)) {\n // Quote values that contain spaces or special characters\n const needsQuotes = /[\\s\"'=]/.test(value);\n const quotedValue = needsQuotes ? `\"${value}\"` : value;\n lines.push(`${key}=${quotedValue}`);\n }\n fs.writeFileSync(filePath, lines.join('\\n') + '\\n');\n}\n\n/**\n * List available config files\n */\nfunction listConfigFiles(): ConfigFile[] {\n const files: ConfigFile[] = [];\n const configFiles = ['local.json', 'cloud.json', 'main.json', 'xpod.base.json'];\n\n for (const name of configFiles) {\n const filePath = path.join(CONFIG_DIR, name);\n files.push({\n name,\n path: filePath,\n exists: fs.existsSync(filePath),\n });\n }\n return files;\n}\n\n/**\n * Send JSON response helper\n */\n\nfunction isPrivateIp(host: string): boolean {\n if (host === 'localhost' || host === '::1') return true;\n if (host.startsWith('127.')) return true;\n if (host.startsWith('10.')) return true;\n if (host.startsWith('192.168.')) return true;\n const m = host.match(/^172\\.(\\d+)\\./);\n if (m) {\n const second = Number(m[1]);\n if (second >= 16 && second <= 31) return true;\n }\n return false;\n}\n\nasync function fetchPublicIp(): Promise<string | null> {\n const endpoints = [\n 'https://api.ipify.org?format=json',\n 'https://ifconfig.me/ip',\n ];\n\n for (const url of endpoints) {\n try {\n const res = await fetch(url, { signal: AbortSignal.timeout(3000) });\n if (!res.ok) {\n continue;\n }\n const contentType = res.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n const json = await res.json() as { ip?: string };\n const ip = json.ip?.trim();\n if (ip) {\n return ip;\n }\n } else {\n const ip = (await res.text()).trim();\n if (ip) {\n return ip;\n }\n }\n } catch {\n // ignore and try next endpoint\n }\n }\n\n return null;\n}\n\nfunction sendJson(res: ServerResponse, status: number, data: unknown): void {\n res.statusCode = status;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(data));\n}\n\n/**\n * Parse JSON body from request\n */\nfunction parseJsonBody(req: AuthenticatedRequest): Promise<{ env?: EnvConfig }> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk: Buffer) => {\n body += chunk.toString();\n });\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch (err) {\n reject(err);\n }\n });\n req.on('error', reject);\n });\n}\n\nexport function registerAdminRoutes(server: ApiServer): void {\n const logger = console;\n\n // GET /api/admin/status - Get xpod status\n const statusHandler: RouteHandler = async (\n _req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const envFilePath = getEnvFilePath();\n const env = readEnvFile(envFilePath);\n const configs = listConfigFiles();\n\n sendJson(res, 200, {\n status: 'running',\n pid: process.pid,\n ppid: process.ppid,\n uptime: process.uptime(),\n env: {\n CSS_BASE_URL: env.CSS_BASE_URL || process.env.CSS_BASE_URL,\n XPOD_EDITION: env.XPOD_EDITION || process.env.XPOD_EDITION,\n CSS_PORT: env.CSS_PORT || process.env.CSS_PORT,\n },\n configs,\n });\n } catch (error) {\n logger.error('[Admin] Status error:', error);\n sendJson(res, 500, { error: 'Failed to get status' });\n }\n };\n\n // GET /api/admin/config - Get current configuration\n const getConfigHandler: RouteHandler = async (\n _req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const envFilePath = getEnvFilePath();\n const env = readEnvFile(envFilePath);\n sendJson(res, 200, {\n env,\n configFiles: listConfigFiles(),\n });\n } catch (error) {\n logger.error('[Admin] Get config error:', error);\n sendJson(res, 500, { error: 'Failed to read configuration' });\n }\n };\n\n // PUT /api/admin/config - Update configuration\n const updateConfigHandler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n // Parse body from raw request\n const body = await parseJsonBody(req);\n\n if (body.env) {\n // Merge with existing config\n const envFilePath = getEnvFilePath();\n const currentEnv = readEnvFile(envFilePath);\n const newEnv = { ...currentEnv, ...body.env };\n\n // Remove keys set to null or empty string\n for (const [key, value] of Object.entries(newEnv)) {\n if (value === null || value === '') {\n delete newEnv[key];\n }\n }\n\n writeEnvFile(envFilePath, newEnv);\n logger.log('[Admin] Configuration updated');\n }\n\n sendJson(res, 200, {\n success: true,\n message: 'Configuration updated. Restart required for changes to take effect.',\n });\n } catch (error) {\n logger.error('[Admin] Update config error:', error);\n sendJson(res, 500, { error: 'Failed to update configuration' });\n }\n };\n\n // POST /api/admin/restart - Trigger xpod restart\n const restartHandler: RouteHandler = async (\n _req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const ppid = process.ppid;\n\n if (!ppid) {\n sendJson(res, 500, { error: 'Cannot determine parent process' });\n return;\n }\n\n logger.log(`[Admin] Sending SIGUSR1 to parent process (pid: ${ppid})`);\n\n // Send response before triggering restart\n sendJson(res, 200, {\n success: true,\n message: 'Restart signal sent. Server will restart shortly.',\n });\n\n // Give time for response to be sent, then signal parent\n setTimeout(() => {\n try {\n process.kill(ppid, 'SIGUSR1');\n } catch (err) {\n logger.error('[Admin] Failed to send restart signal:', err);\n }\n }, 100);\n } catch (error) {\n logger.error('[Admin] Restart error:', error);\n sendJson(res, 500, { error: 'Failed to trigger restart' });\n }\n };\n\n // Log buffer for recent logs (in-memory)\n const logBuffer: Array<{\n timestamp: string;\n level: string;\n source: string;\n message: string;\n }> = [];\n const MAX_LOG_BUFFER = 1000;\n\n // Capture stdout/stderr logs\n const originalStdoutWrite = process.stdout.write.bind(process.stdout);\n const originalStderrWrite = process.stderr.write.bind(process.stderr);\n\n function addLog(level: string, source: string, message: string): void {\n const entry = {\n timestamp: new Date().toISOString(),\n level,\n source,\n message: message.trim(),\n };\n logBuffer.push(entry);\n if (logBuffer.length > MAX_LOG_BUFFER) {\n logBuffer.shift();\n }\n }\n\n // Intercept stdout\n process.stdout.write = (chunk: any, ...args: any[]): boolean => {\n const message = chunk.toString();\n addLog('info', 'xpod', message);\n return originalStdoutWrite(chunk, ...args);\n };\n\n // Intercept stderr\n process.stderr.write = (chunk: any, ...args: any[]): boolean => {\n const message = chunk.toString();\n addLog('error', 'xpod', message);\n return originalStderrWrite(chunk, ...args);\n };\n\n // GET /api/admin/logs - Get recent logs\n const getLogsHandler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const url = new URL(req.url || '', `http://${req.headers.host}`);\n const limit = parseInt(url.searchParams.get('limit') || '100', 10);\n const level = url.searchParams.get('level');\n const source = url.searchParams.get('source');\n\n let logs = [...logBuffer];\n\n // Apply filters\n if (level && level !== 'all') {\n logs = logs.filter(log => log.level === level);\n }\n if (source && source !== 'all') {\n logs = logs.filter(log => log.source === source);\n }\n\n // Return last N logs\n logs = logs.slice(-limit);\n\n sendJson(res, 200, { logs });\n } catch (error) {\n logger.error('[Admin] Get logs error:', error);\n sendJson(res, 500, { error: 'Failed to get logs' });\n }\n };\n\n // GET /api/admin/logs/stream - Stream logs via SSE\n const streamLogsHandler: RouteHandler = async (\n _req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n });\n\n // Send initial logs\n const lastIndex = logBuffer.length;\n res.write(`data: ${JSON.stringify({ type: 'init', logs: logBuffer.slice(-100) })}\\n\\n`);\n\n // Send new logs every second\n let currentIndex = lastIndex;\n const interval = setInterval(() => {\n if (logBuffer.length > currentIndex) {\n const newLogs = logBuffer.slice(currentIndex);\n res.write(`data: ${JSON.stringify({ type: 'update', logs: newLogs })}\\n\\n`);\n currentIndex = logBuffer.length;\n }\n }, 1000);\n\n // Clean up on close\n res.on('close', () => {\n clearInterval(interval);\n });\n };\n\n // GET /api/admin/logs/file - Read log file from disk\n const getLogFileHandler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const url = new URL(req.url || '', `http://${req.headers.host}`);\n const lines = parseInt(url.searchParams.get('lines') || '100', 10);\n\n // Try common log file locations\n const logPaths = [\n path.resolve(process.cwd(), 'logs', 'combined.log'),\n path.resolve(process.cwd(), 'logs', 'error.log'),\n path.resolve(process.cwd(), 'xpod.log'),\n path.resolve(process.cwd(), 'combined.log'),\n ];\n\n let logPath: string | null = null;\n for (const p of logPaths) {\n if (fs.existsSync(p)) {\n logPath = p;\n break;\n }\n }\n\n if (!logPath) {\n sendJson(res, 404, { error: 'No log file found' });\n return;\n }\n\n // Read last N lines\n const fileLogs: string[] = [];\n const stats = statSync(logPath);\n const stream = createReadStream(logPath, {\n start: Math.max(0, stats.size - 1024 * 100), // Last 100KB\n end: stats.size,\n });\n\n const rl = createInterface({ input: stream });\n for await (const line of rl) {\n fileLogs.push(line);\n }\n\n const lastLines = fileLogs.slice(-lines);\n sendJson(res, 200, {\n file: logPath,\n lines: lastLines,\n });\n } catch (error) {\n logger.error('[Admin] Get log file error:', error);\n sendJson(res, 500, { error: 'Failed to read log file' });\n }\n };\n\n\n // GET /api/admin/public-ip - Detect outbound public IP and compare with CSS_BASE_URL\n const ipv4Handler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const envFilePath = getEnvFilePath();\n const env = readEnvFile(envFilePath);\n const parsedUrl = new URL(req.url ?? '/', 'http://localhost');\n const baseUrl = parsedUrl.searchParams.get('baseUrl') || env.CSS_BASE_URL || process.env.CSS_BASE_URL || '';\n\n const ip = await fetchPublicIp();\n\n if (!baseUrl) {\n sendJson(res, 200, {\n status: 'unknown',\n ipv4: ip,\n baseUrl,\n detail: ip ? '未配置 Base URL,无法判断是否可直连。' : '未配置 Base URL,且无法获取公网 IP。',\n });\n return;\n }\n\n let hostname = '';\n try {\n hostname = new URL(baseUrl).hostname;\n } catch {\n sendJson(res, 200, {\n status: 'unknown',\n ipv4: ip,\n baseUrl,\n detail: 'Base URL 格式不合法,无法判断。',\n });\n return;\n }\n\n if (isPrivateIp(hostname)) {\n sendJson(res, 200, {\n status: 'fail',\n ipv4: ip,\n baseUrl,\n detail: 'Base URL 为本地/内网地址,默认不可直连。',\n });\n return;\n }\n\n // If hostname is an IP, compare directly.\n const isIpLiteral = /^\\d{1,3}(\\.\\d{1,3}){3}$/.test(hostname);\n if (isIpLiteral) {\n if (!ip) {\n sendJson(res, 200, {\n status: 'unknown',\n ipv4: null,\n baseUrl,\n detail: '无法获取公网出口 IP,无法比对。',\n });\n return;\n }\n const ok = hostname === ip;\n sendJson(res, 200, {\n status: ok ? 'pass' : 'fail',\n ipv4: ip,\n baseUrl,\n detail: ok\n ? 'Base URL IP 与公网出口 IP 一致,默认可直连。'\n : 'Base URL IP 与公网出口 IP 不一致,默认不可直连。',\n });\n return;\n }\n\n // Domain name: we can only do best-effort.\n if (!ip) {\n sendJson(res, 200, {\n status: 'unknown',\n ipv4: null,\n baseUrl,\n detail: '已配置域名,但无法获取公网出口 IP,无法进一步判断。',\n });\n return;\n }\n\n sendJson(res, 200, {\n status: 'pass',\n ipv4: ip,\n baseUrl,\n detail: '已配置域名,默认可直连(仍需确保端口映射/防火墙放行)。',\n });\n } catch (error) {\n logger.error('[Admin] Public IP check error:', error);\n sendJson(res, 500, { error: 'Failed to detect public ip' });\n }\n };\n\n // Register routes - public for now (TODO: add auth for production)\n server.get('/api/admin/status', statusHandler, { public: true });\n server.get('/api/admin/config', getConfigHandler, { public: true });\n server.get('/api/admin/public-ip', ipv4Handler, { public: true });\n server.put('/api/admin/config', updateConfigHandler, { public: true });\n server.post('/api/admin/restart', restartHandler, { public: true });\n server.get('/api/admin/logs', getLogsHandler, { public: true });\n server.get('/api/admin/logs/stream', streamLogsHandler, { public: true });\n server.get('/api/admin/logs/file', getLogFileHandler, { public: true });\n\n logger.log('[Admin] Admin API routes registered');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AdminHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/AdminHandler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;AAwEH,kDAeC;AAED,gDAaC;AAED,sEAYC;AAMD,gDAUC;AAsKD,kDAmYC;AAxqBD,4CAAoB;AACpB,gDAAwB;AACxB,2BAAgD;AAChD,uCAA2C;AAC3C,2CAA6C;AAE7C,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,sBAAY,EAAE,QAAQ,CAAC,CAAC;AAExD,SAAS,cAAc;IACrB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC1C,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,OAAO,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;AACnD,CAAC;AAwBY,QAAA,yBAAyB,GAAG;IACvC,kBAAkB;IAClB,oBAAoB;IACpB,cAAc;IACd,sBAAsB;IACtB,wBAAwB;IACxB,yBAAyB;IACzB,qBAAqB;IACrB,iBAAiB;IACjB,WAAW;IACX,kBAAkB;IAClB,gBAAgB;IAChB,iBAAiB;IACjB,sBAAsB;IACtB,qBAAqB;IACrB,yBAAyB;IACzB,cAAc;IACd,gBAAgB;IAChB,iBAAiB;IACjB,oBAAoB;IACpB,UAAU;IACV,qBAAqB;IACrB,qBAAqB;IACrB,mBAAmB;IACnB,sBAAsB;CACd,CAAC;AAEX,MAAM,4BAA4B,GAAG,IAAI,GAAG,CAAS,iCAAyB,CAAC,CAAC;AAEhF,SAAgB,mBAAmB,CAAC,GAAW;IAC7C,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IACrC,IAAI,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CACL,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC;QAChC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC7B,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC9B,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC/B,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC/B,UAAU,CAAC,QAAQ,CAAC,eAAe,CAAC;QACpC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC9B,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,CACpC,CAAC;AACJ,CAAC;AAED,SAAgB,kBAAkB,CAAC,GAAc;IAC/C,MAAM,SAAS,GAAc,EAAE,CAAC;IAChC,MAAM,OAAO,GAA4C,EAAE,CAAC;IAE5D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,SAAS;QACX,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC;AAED,SAAgB,6BAA6B,CAAC,KAAgB;IAC5D,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,4BAA4B,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACvC,SAAS;QACX,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACrB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED,SAAgB,kBAAkB,CAAC,OAAe,EAAE,GAAc;IAChE,IAAI,SAAS,GAAG,OAAO,CAAC;IACxB,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;SACtC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;SACvE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAE7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,aAAa,EAAE,CAAC;QACzC,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,GAAG,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAe,EAAE,GAAc;IACvD,OAAO;QACL,GAAG,KAAK;QACR,OAAO,EAAE,kBAAkB,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAyB;IACjD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACrD,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC;QACrD,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACxD,IAAI,eAAe,IAAI,aAAa,KAAK,eAAe,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACxE,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC;AAC5F,CAAC;AAED,SAAS,0BAA0B,CAAC,GAAyB,EAAE,GAAmB;IAChF,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;QACjB,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,4FAA4F;KACrG,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,SAAS;QAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,gBAAgB;QAChB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,QAAgB,EAAE,MAAiB;IACvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,yDAAyD;QACzD,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QACvD,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,YAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,SAAS,eAAe;IACtB,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,WAAW,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAEhF,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC;YACT,IAAI;YACJ,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AAEH,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACxD,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,CAAC;QACN,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,MAAM,IAAI,EAAE,IAAI,MAAM,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,MAAM,SAAS,GAAG;QAChB,mCAAmC;QACnC,wBAAwB;KACzB,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,SAAS;YACX,CAAC;YACD,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YAC1D,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAqB,CAAC;gBACjD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;gBAC3B,IAAI,EAAE,EAAE,CAAC;oBACP,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACrC,IAAI,EAAE,EAAE,CAAC;oBACP,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,GAAmB,EAAE,MAAc,EAAE,IAAa;IAClE,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC;IACxB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,GAAyB;IAC9C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,mBAAmB,CAAC,MAAiB;IACnD,MAAM,MAAM,GAAG,OAAO,CAAC;IAEvB,0CAA0C;IAC1C,MAAM,aAAa,GAAiB,KAAK,EACvC,IAA0B,EAC1B,GAAmB,EACnB,EAAE;QACF,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;YAElC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,MAAM,EAAE,SAAS;gBACjB,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;gBACxB,GAAG,EAAE;oBACH,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;oBAC1D,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;oBAC1D,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ;iBAC/C;gBACD,OAAO;aACR,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;YAC7C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,CAAC;IAEF,oDAAoD;IACpD,MAAM,gBAAgB,GAAiB,KAAK,EAC1C,IAA0B,EAC1B,GAAmB,EACnB,EAAE;QACF,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;YACrC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,GAAG,kBAAkB,CAAC,GAAG,CAAC;gBAC1B,WAAW,EAAE,eAAe,EAAE;aAC/B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YACjD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC,CAAC;IAEF,+CAA+C;IAC/C,MAAM,mBAAmB,GAAiB,KAAK,EAC7C,GAAyB,EACzB,GAAmB,EACnB,EAAE;QACF,IAAI,CAAC;YACH,IAAI,CAAC,0BAA0B,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC1C,OAAO;YACT,CAAC;YACD,8BAA8B;YAC9B,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;YAEtC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACb,6BAA6B;gBAC7B,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;gBACrC,MAAM,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;gBAC5C,MAAM,KAAK,GAAG,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtD,MAAM,MAAM,GAAG,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,EAAE,CAAC;gBAE3C,0CAA0C;gBAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;wBACnC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC;gBAED,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;gBAClC,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAC9C,CAAC;YAED,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,qEAAqE;aAC/E,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACpD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC;IAEF,iDAAiD;IACjD,MAAM,cAAc,GAAiB,KAAK,EACxC,GAAyB,EACzB,GAAmB,EACnB,EAAE;QACF,IAAI,CAAC;YACH,IAAI,CAAC,0BAA0B,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC1C,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAE1B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;gBACjE,OAAO;YACT,CAAC;YAED,MAAM,CAAC,GAAG,CAAC,mDAAmD,IAAI,GAAG,CAAC,CAAC;YAEvE,0CAA0C;YAC1C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,mDAAmD;aAC7D,CAAC,CAAC;YAEH,wDAAwD;YACxD,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAChC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC9C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,CAAC;IAEF,yCAAyC;IACzC,MAAM,SAAS,GAAe,EAAE,CAAC;IACjC,MAAM,cAAc,GAAG,IAAI,CAAC;IAE5B,6BAA6B;IAC7B,MAAM,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACtE,MAAM,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtE,SAAS,MAAM,CAAC,KAAa,EAAE,MAAc,EAAE,OAAe;QAC5D,MAAM,KAAK,GAAG;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK;YACL,MAAM;YACN,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;SACxB,CAAC;QACF,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,IAAI,SAAS,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;YACtC,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,KAAU,EAAE,GAAG,IAAW,EAAW,EAAE;QAC7D,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,mBAAmB,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,mBAAmB;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,KAAU,EAAE,GAAG,IAAW,EAAW,EAAE;QAC7D,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,mBAAmB,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,wCAAwC;IACxC,MAAM,cAAc,GAAiB,KAAK,EACxC,GAAyB,EACzB,GAAmB,EACnB,EAAE;QACF,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;YACnE,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC9C,MAAM,GAAG,GAAG,WAAW,CAAC,cAAc,EAAE,CAAC,CAAC;YAE1C,IAAI,IAAI,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;YAE1B,gBAAgB;YAChB,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;gBAC7B,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;YACjD,CAAC;YACD,IAAI,MAAM,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBAC/B,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;YACnD,CAAC;YAED,qBAAqB;YACrB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YAEnE,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAC/C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC;IAEF,mDAAmD;IACnD,MAAM,iBAAiB,GAAiB,KAAK,EAC3C,IAA0B,EAC1B,GAAmB,EACnB,EAAE;QACF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,UAAU;YAC3B,YAAY,EAAE,YAAY;SAC3B,CAAC,CAAC;QAEH,oBAAoB;QACpB,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC;QACnC,IAAI,GAAG,GAAG,WAAW,CAAC,cAAc,EAAE,CAAC,CAAC;QACxC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAEjI,6BAA6B;QAC7B,IAAI,YAAY,GAAG,SAAS,CAAC;QAC7B,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,IAAI,SAAS,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;gBACpC,GAAG,GAAG,WAAW,CAAC,cAAc,EAAE,CAAC,CAAC;gBACpC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;gBACvF,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;gBAC5E,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC;YAClC,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,oBAAoB;QACpB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,qDAAqD;IACrD,MAAM,iBAAiB,GAAiB,KAAK,EAC3C,GAAyB,EACzB,GAAmB,EACnB,EAAE;QACF,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;YACnE,MAAM,GAAG,GAAG,WAAW,CAAC,cAAc,EAAE,CAAC,CAAC;YAE1C,gCAAgC;YAChC,MAAM,QAAQ,GAAG;gBACf,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,cAAc,CAAC;gBACnD,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC;gBAChD,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;gBACvC,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC;aAC5C,CAAC;YAEF,IAAI,OAAO,GAAkB,IAAI,CAAC;YAClC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,YAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrB,OAAO,GAAG,CAAC,CAAC;oBACZ,MAAM;gBACR,CAAC;YACH,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBACnD,OAAO;YACT,CAAC;YAED,oBAAoB;YACpB,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAA,aAAQ,EAAC,OAAO,CAAC,CAAC;YAChC,MAAM,MAAM,GAAG,IAAA,qBAAgB,EAAC,OAAO,EAAE;gBACvC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC,EAAE,aAAa;gBAC1D,GAAG,EAAE,KAAK,CAAC,IAAI;aAChB,CAAC,CAAC;YAEH,MAAM,EAAE,GAAG,IAAA,0BAAe,EAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,EAAE,EAAE,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;YAED,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;YACzC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;aAC9D,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACnD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC;IAGF,qFAAqF;IACrF,MAAM,WAAW,GAAiB,KAAK,EACrC,GAAyB,EACzB,GAAmB,EACnB,EAAE;QACF,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;YAC9D,MAAM,OAAO,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;YAE5G,MAAM,EAAE,GAAG,MAAM,aAAa,EAAE,CAAC;YAEjC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;oBACjB,MAAM,EAAE,SAAS;oBACjB,IAAI,EAAE,EAAE;oBACR,OAAO;oBACP,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,0BAA0B;iBACpE,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,QAAQ,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;oBACjB,MAAM,EAAE,SAAS;oBACjB,IAAI,EAAE,EAAE;oBACR,OAAO;oBACP,MAAM,EAAE,sBAAsB;iBAC/B,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;oBACjB,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,EAAE;oBACR,OAAO;oBACP,MAAM,EAAE,2BAA2B;iBACpC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,0CAA0C;YAC1C,MAAM,WAAW,GAAG,yBAAyB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7D,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,CAAC,EAAE,EAAE,CAAC;oBACR,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;wBACjB,MAAM,EAAE,SAAS;wBACjB,IAAI,EAAE,IAAI;wBACV,OAAO;wBACP,MAAM,EAAE,mBAAmB;qBAC5B,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBACD,MAAM,EAAE,GAAG,QAAQ,KAAK,EAAE,CAAC;gBAC3B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;oBACjB,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;oBAC5B,IAAI,EAAE,EAAE;oBACR,OAAO;oBACP,MAAM,EAAE,EAAE;wBACR,CAAC,CAAC,gCAAgC;wBAClC,CAAC,CAAC,kCAAkC;iBACvC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,2CAA2C;YAC3C,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;oBACjB,MAAM,EAAE,SAAS;oBACjB,IAAI,EAAE,IAAI;oBACV,OAAO;oBACP,MAAM,EAAE,6BAA6B;iBACtC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,EAAE;gBACR,OAAO;gBACP,MAAM,EAAE,8BAA8B;aACvC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YACtD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC;IAEF,mEAAmE;IACnE,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,iBAAiB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1E,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,iBAAiB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAExE,MAAM,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACpD,CAAC","sourcesContent":["/**\n * Admin API Handler\n * Provides configuration management, restart functionality, and log streaming\n */\n\nimport type { ServerResponse } from 'node:http';\nimport type { ApiServer, RouteHandler } from '../ApiServer';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport fs from 'fs';\nimport path from 'path';\nimport { createReadStream, statSync } from 'fs';\nimport { createInterface } from 'readline';\nimport { PACKAGE_ROOT } from '../../runtime';\n\nconst CONFIG_DIR = path.resolve(PACKAGE_ROOT, 'config');\n\nfunction getEnvFilePath(): string {\n const envPath = process.env.XPOD_ENV_PATH;\n if (envPath && envPath.trim()) {\n return path.resolve(envPath);\n }\n return path.resolve(process.cwd(), '.env.local');\n}\n\ninterface ConfigFile {\n name: string;\n path: string;\n exists: boolean;\n}\n\ninterface EnvConfig {\n [key: string]: string;\n}\n\ninterface LogEntry {\n timestamp: string;\n level: string;\n source: string;\n message: string;\n}\n\nexport interface SanitizedEnvRead {\n env: EnvConfig;\n secrets: Record<string, { configured: boolean }>;\n}\n\nexport const ALLOWED_ADMIN_CONFIG_KEYS = [\n 'XPOD_DEPLOY_MODE',\n 'CSS_ROOT_FILE_PATH',\n 'CSS_BASE_URL',\n 'XPOD_TUNNEL_PROVIDER',\n 'XPOD_TUNNEL_PUBLIC_URL',\n 'CLOUDFLARE_TUNNEL_TOKEN',\n 'SAKURA_TUNNEL_TOKEN',\n 'NGROK_AUTHTOKEN',\n 'NGROK_URL',\n 'FRP_TUNNEL_TOKEN',\n 'FRP_TUNNEL_URL',\n 'XPOD_HTTPS_MODE',\n 'XPOD_HTTPS_CERT_PATH',\n 'XPOD_HTTPS_KEY_PATH',\n 'XPOD_CLOUD_API_ENDPOINT',\n 'XPOD_NODE_ID',\n 'XPOD_SP_DOMAIN',\n 'XPOD_NODE_TOKEN',\n 'XPOD_SERVICE_TOKEN',\n 'CSS_PORT',\n 'CSS_SPARQL_ENDPOINT',\n 'CSS_IDENTITY_DB_URL',\n 'CSS_LOGGING_LEVEL',\n 'CSS_SHOW_STACK_TRACE',\n] as const;\n\nconst ALLOWED_ADMIN_CONFIG_KEY_SET = new Set<string>(ALLOWED_ADMIN_CONFIG_KEYS);\n\nexport function isAdminSecretEnvKey(key: string): boolean {\n const normalized = key.toUpperCase();\n if (normalized.endsWith('_KEY_PATH') || normalized.endsWith('_CERT_PATH')) {\n return false;\n }\n return (\n normalized.includes('AUTHTOKEN') ||\n normalized.endsWith('_TOKEN') ||\n normalized.endsWith('_SECRET') ||\n normalized.endsWith('_API_KEY') ||\n normalized.includes('PASSWORD') ||\n normalized.includes('CLIENT_SECRET') ||\n normalized.endsWith('_DB_URL') ||\n normalized.includes('DATABASE_URL')\n );\n}\n\nexport function sanitizeEnvForRead(env: EnvConfig): SanitizedEnvRead {\n const sanitized: EnvConfig = {};\n const secrets: Record<string, { configured: boolean }> = {};\n\n for (const [key, value] of Object.entries(env)) {\n if (isAdminSecretEnvKey(key)) {\n secrets[key] = { configured: Boolean(value) };\n continue;\n }\n sanitized[key] = value;\n }\n\n return { env: sanitized, secrets };\n}\n\nexport function createAllowedAdminConfigPatch(input: EnvConfig): EnvConfig {\n const patch: EnvConfig = {};\n for (const [key, value] of Object.entries(input)) {\n if (!ALLOWED_ADMIN_CONFIG_KEY_SET.has(key)) {\n continue;\n }\n if (isAdminSecretEnvKey(key) && !value) {\n continue;\n }\n patch[key] = value;\n }\n return patch;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function sanitizeLogMessage(message: string, env: EnvConfig): string {\n let sanitized = message;\n const secretEntries = Object.entries(env)\n .filter(([key, value]) => isAdminSecretEnvKey(key) && value.length >= 6)\n .sort((a, b) => b[1].length - a[1].length);\n\n for (const [key, value] of secretEntries) {\n sanitized = sanitized.replace(new RegExp(escapeRegExp(value), 'g'), `[redacted:${key}]`);\n }\n return sanitized;\n}\n\nfunction sanitizeLogEntry(entry: LogEntry, env: EnvConfig): LogEntry {\n return {\n ...entry,\n message: sanitizeLogMessage(entry.message, env),\n };\n}\n\nfunction isLocalAdminHost(req: AuthenticatedRequest): boolean {\n const configuredToken = process.env.XPOD_ADMIN_TOKEN;\n const providedToken = req.headers['x-xpod-admin-token'] ??\n req.headers.authorization?.replace(/^Bearer\\s+/i, '');\n if (configuredToken && providedToken === configuredToken) {\n return true;\n }\n\n const host = String(req.headers.host ?? '').split(':')[0].toLowerCase();\n return host === 'localhost' || host === '127.0.0.1' || host === '[::1]' || host === '::1';\n}\n\nfunction assertAdminMutationAllowed(req: AuthenticatedRequest, res: ServerResponse): boolean {\n if (isLocalAdminHost(req)) {\n return true;\n }\n sendJson(res, 403, {\n error: 'Forbidden',\n detail: 'Runtime config writes and restart are allowed only from loopback or with XPOD_ADMIN_TOKEN.',\n });\n return false;\n}\n\n/**\n * Read .env.local file and parse it\n */\nfunction readEnvFile(filePath: string): EnvConfig {\n const config: EnvConfig = {};\n if (!fs.existsSync(filePath)) {\n return config;\n }\n const content = fs.readFileSync(filePath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n // Remove quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n config[key] = value;\n }\n return config;\n}\n\n/**\n * Write .env.local file\n */\nfunction writeEnvFile(filePath: string, config: EnvConfig): void {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(config)) {\n // Quote values that contain spaces or special characters\n const needsQuotes = /[\\s\"'=]/.test(value);\n const quotedValue = needsQuotes ? `\"${value}\"` : value;\n lines.push(`${key}=${quotedValue}`);\n }\n fs.writeFileSync(filePath, lines.join('\\n') + '\\n');\n}\n\n/**\n * List available config files\n */\nfunction listConfigFiles(): ConfigFile[] {\n const files: ConfigFile[] = [];\n const configFiles = ['local.json', 'cloud.json', 'main.json', 'xpod.base.json'];\n\n for (const name of configFiles) {\n const filePath = path.join(CONFIG_DIR, name);\n files.push({\n name,\n path: filePath,\n exists: fs.existsSync(filePath),\n });\n }\n return files;\n}\n\n/**\n * Send JSON response helper\n */\n\nfunction isPrivateIp(host: string): boolean {\n if (host === 'localhost' || host === '::1') return true;\n if (host.startsWith('127.')) return true;\n if (host.startsWith('10.')) return true;\n if (host.startsWith('192.168.')) return true;\n const m = host.match(/^172\\.(\\d+)\\./);\n if (m) {\n const second = Number(m[1]);\n if (second >= 16 && second <= 31) return true;\n }\n return false;\n}\n\nasync function fetchPublicIp(): Promise<string | null> {\n const endpoints = [\n 'https://api.ipify.org?format=json',\n 'https://ifconfig.me/ip',\n ];\n\n for (const url of endpoints) {\n try {\n const res = await fetch(url, { signal: AbortSignal.timeout(3000) });\n if (!res.ok) {\n continue;\n }\n const contentType = res.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n const json = await res.json() as { ip?: string };\n const ip = json.ip?.trim();\n if (ip) {\n return ip;\n }\n } else {\n const ip = (await res.text()).trim();\n if (ip) {\n return ip;\n }\n }\n } catch {\n // ignore and try next endpoint\n }\n }\n\n return null;\n}\n\nfunction sendJson(res: ServerResponse, status: number, data: unknown): void {\n res.statusCode = status;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(data));\n}\n\n/**\n * Parse JSON body from request\n */\nfunction parseJsonBody(req: AuthenticatedRequest): Promise<{ env?: EnvConfig }> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk: Buffer) => {\n body += chunk.toString();\n });\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch (err) {\n reject(err);\n }\n });\n req.on('error', reject);\n });\n}\n\nexport function registerAdminRoutes(server: ApiServer): void {\n const logger = console;\n\n // GET /api/admin/status - Get xpod status\n const statusHandler: RouteHandler = async (\n _req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const envFilePath = getEnvFilePath();\n const env = readEnvFile(envFilePath);\n const configs = listConfigFiles();\n\n sendJson(res, 200, {\n status: 'running',\n pid: process.pid,\n ppid: process.ppid,\n uptime: process.uptime(),\n env: {\n CSS_BASE_URL: env.CSS_BASE_URL || process.env.CSS_BASE_URL,\n XPOD_EDITION: env.XPOD_EDITION || process.env.XPOD_EDITION,\n CSS_PORT: env.CSS_PORT || process.env.CSS_PORT,\n },\n configs,\n });\n } catch (error) {\n logger.error('[Admin] Status error:', error);\n sendJson(res, 500, { error: 'Failed to get status' });\n }\n };\n\n // GET /api/admin/config - Get current configuration\n const getConfigHandler: RouteHandler = async (\n _req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const envFilePath = getEnvFilePath();\n const env = readEnvFile(envFilePath);\n sendJson(res, 200, {\n ...sanitizeEnvForRead(env),\n configFiles: listConfigFiles(),\n });\n } catch (error) {\n logger.error('[Admin] Get config error:', error);\n sendJson(res, 500, { error: 'Failed to read configuration' });\n }\n };\n\n // PUT /api/admin/config - Update configuration\n const updateConfigHandler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n if (!assertAdminMutationAllowed(req, res)) {\n return;\n }\n // Parse body from raw request\n const body = await parseJsonBody(req);\n\n if (body.env) {\n // Merge with existing config\n const envFilePath = getEnvFilePath();\n const currentEnv = readEnvFile(envFilePath);\n const patch = createAllowedAdminConfigPatch(body.env);\n const newEnv = { ...currentEnv, ...patch };\n\n // Remove keys set to null or empty string\n for (const [key, value] of Object.entries(newEnv)) {\n if (value === null || value === '') {\n delete newEnv[key];\n }\n }\n\n writeEnvFile(envFilePath, newEnv);\n logger.log('[Admin] Configuration updated');\n }\n\n sendJson(res, 200, {\n success: true,\n message: 'Configuration updated. Restart required for changes to take effect.',\n });\n } catch (error) {\n logger.error('[Admin] Update config error:', error);\n sendJson(res, 500, { error: 'Failed to update configuration' });\n }\n };\n\n // POST /api/admin/restart - Trigger xpod restart\n const restartHandler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n if (!assertAdminMutationAllowed(req, res)) {\n return;\n }\n const ppid = process.ppid;\n\n if (!ppid) {\n sendJson(res, 500, { error: 'Cannot determine parent process' });\n return;\n }\n\n logger.log(`[Admin] Sending SIGUSR1 to parent process (pid: ${ppid})`);\n\n // Send response before triggering restart\n sendJson(res, 200, {\n success: true,\n message: 'Restart signal sent. Server will restart shortly.',\n });\n\n // Give time for response to be sent, then signal parent\n setTimeout(() => {\n try {\n process.kill(ppid, 'SIGUSR1');\n } catch (err) {\n logger.error('[Admin] Failed to send restart signal:', err);\n }\n }, 100);\n } catch (error) {\n logger.error('[Admin] Restart error:', error);\n sendJson(res, 500, { error: 'Failed to trigger restart' });\n }\n };\n\n // Log buffer for recent logs (in-memory)\n const logBuffer: LogEntry[] = [];\n const MAX_LOG_BUFFER = 1000;\n\n // Capture stdout/stderr logs\n const originalStdoutWrite = process.stdout.write.bind(process.stdout);\n const originalStderrWrite = process.stderr.write.bind(process.stderr);\n\n function addLog(level: string, source: string, message: string): void {\n const entry = {\n timestamp: new Date().toISOString(),\n level,\n source,\n message: message.trim(),\n };\n logBuffer.push(entry);\n if (logBuffer.length > MAX_LOG_BUFFER) {\n logBuffer.shift();\n }\n }\n\n // Intercept stdout\n process.stdout.write = (chunk: any, ...args: any[]): boolean => {\n const message = chunk.toString();\n addLog('info', 'xpod', message);\n return originalStdoutWrite(chunk, ...args);\n };\n\n // Intercept stderr\n process.stderr.write = (chunk: any, ...args: any[]): boolean => {\n const message = chunk.toString();\n addLog('error', 'xpod', message);\n return originalStderrWrite(chunk, ...args);\n };\n\n // GET /api/admin/logs - Get recent logs\n const getLogsHandler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const url = new URL(req.url || '', `http://${req.headers.host}`);\n const limit = parseInt(url.searchParams.get('limit') || '100', 10);\n const level = url.searchParams.get('level');\n const source = url.searchParams.get('source');\n const env = readEnvFile(getEnvFilePath());\n\n let logs = [...logBuffer];\n\n // Apply filters\n if (level && level !== 'all') {\n logs = logs.filter(log => log.level === level);\n }\n if (source && source !== 'all') {\n logs = logs.filter(log => log.source === source);\n }\n\n // Return last N logs\n logs = logs.slice(-limit).map((log) => sanitizeLogEntry(log, env));\n\n sendJson(res, 200, { logs });\n } catch (error) {\n logger.error('[Admin] Get logs error:', error);\n sendJson(res, 500, { error: 'Failed to get logs' });\n }\n };\n\n // GET /api/admin/logs/stream - Stream logs via SSE\n const streamLogsHandler: RouteHandler = async (\n _req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n });\n\n // Send initial logs\n const lastIndex = logBuffer.length;\n let env = readEnvFile(getEnvFilePath());\n res.write(`data: ${JSON.stringify({ type: 'init', logs: logBuffer.slice(-100).map((log) => sanitizeLogEntry(log, env)) })}\\n\\n`);\n\n // Send new logs every second\n let currentIndex = lastIndex;\n const interval = setInterval(() => {\n if (logBuffer.length > currentIndex) {\n env = readEnvFile(getEnvFilePath());\n const newLogs = logBuffer.slice(currentIndex).map((log) => sanitizeLogEntry(log, env));\n res.write(`data: ${JSON.stringify({ type: 'update', logs: newLogs })}\\n\\n`);\n currentIndex = logBuffer.length;\n }\n }, 1000);\n\n // Clean up on close\n res.on('close', () => {\n clearInterval(interval);\n });\n };\n\n // GET /api/admin/logs/file - Read log file from disk\n const getLogFileHandler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const url = new URL(req.url || '', `http://${req.headers.host}`);\n const lines = parseInt(url.searchParams.get('lines') || '100', 10);\n const env = readEnvFile(getEnvFilePath());\n\n // Try common log file locations\n const logPaths = [\n path.resolve(process.cwd(), 'logs', 'combined.log'),\n path.resolve(process.cwd(), 'logs', 'error.log'),\n path.resolve(process.cwd(), 'xpod.log'),\n path.resolve(process.cwd(), 'combined.log'),\n ];\n\n let logPath: string | null = null;\n for (const p of logPaths) {\n if (fs.existsSync(p)) {\n logPath = p;\n break;\n }\n }\n\n if (!logPath) {\n sendJson(res, 404, { error: 'No log file found' });\n return;\n }\n\n // Read last N lines\n const fileLogs: string[] = [];\n const stats = statSync(logPath);\n const stream = createReadStream(logPath, {\n start: Math.max(0, stats.size - 1024 * 100), // Last 100KB\n end: stats.size,\n });\n\n const rl = createInterface({ input: stream });\n for await (const line of rl) {\n fileLogs.push(line);\n }\n\n const lastLines = fileLogs.slice(-lines);\n sendJson(res, 200, {\n file: logPath,\n lines: lastLines.map((line) => sanitizeLogMessage(line, env)),\n });\n } catch (error) {\n logger.error('[Admin] Get log file error:', error);\n sendJson(res, 500, { error: 'Failed to read log file' });\n }\n };\n\n\n // GET /api/admin/public-ip - Detect outbound public IP and compare with CSS_BASE_URL\n const ipv4Handler: RouteHandler = async (\n req: AuthenticatedRequest,\n res: ServerResponse,\n ) => {\n try {\n const envFilePath = getEnvFilePath();\n const env = readEnvFile(envFilePath);\n const parsedUrl = new URL(req.url ?? '/', 'http://localhost');\n const baseUrl = parsedUrl.searchParams.get('baseUrl') || env.CSS_BASE_URL || process.env.CSS_BASE_URL || '';\n\n const ip = await fetchPublicIp();\n\n if (!baseUrl) {\n sendJson(res, 200, {\n status: 'unknown',\n ipv4: ip,\n baseUrl,\n detail: ip ? '未配置 Base URL,无法判断是否可直连。' : '未配置 Base URL,且无法获取公网 IP。',\n });\n return;\n }\n\n let hostname = '';\n try {\n hostname = new URL(baseUrl).hostname;\n } catch {\n sendJson(res, 200, {\n status: 'unknown',\n ipv4: ip,\n baseUrl,\n detail: 'Base URL 格式不合法,无法判断。',\n });\n return;\n }\n\n if (isPrivateIp(hostname)) {\n sendJson(res, 200, {\n status: 'fail',\n ipv4: ip,\n baseUrl,\n detail: 'Base URL 为本地/内网地址,默认不可直连。',\n });\n return;\n }\n\n // If hostname is an IP, compare directly.\n const isIpLiteral = /^\\d{1,3}(\\.\\d{1,3}){3}$/.test(hostname);\n if (isIpLiteral) {\n if (!ip) {\n sendJson(res, 200, {\n status: 'unknown',\n ipv4: null,\n baseUrl,\n detail: '无法获取公网出口 IP,无法比对。',\n });\n return;\n }\n const ok = hostname === ip;\n sendJson(res, 200, {\n status: ok ? 'pass' : 'fail',\n ipv4: ip,\n baseUrl,\n detail: ok\n ? 'Base URL IP 与公网出口 IP 一致,默认可直连。'\n : 'Base URL IP 与公网出口 IP 不一致,默认不可直连。',\n });\n return;\n }\n\n // Domain name: we can only do best-effort.\n if (!ip) {\n sendJson(res, 200, {\n status: 'unknown',\n ipv4: null,\n baseUrl,\n detail: '已配置域名,但无法获取公网出口 IP,无法进一步判断。',\n });\n return;\n }\n\n sendJson(res, 200, {\n status: 'pass',\n ipv4: ip,\n baseUrl,\n detail: '已配置域名,默认可直连(仍需确保端口映射/防火墙放行)。',\n });\n } catch (error) {\n logger.error('[Admin] Public IP check error:', error);\n sendJson(res, 500, { error: 'Failed to detect public ip' });\n }\n };\n\n // Register routes - public for now (TODO: add auth for production)\n server.get('/api/admin/status', statusHandler, { public: true });\n server.get('/api/admin/config', getConfigHandler, { public: true });\n server.get('/api/admin/public-ip', ipv4Handler, { public: true });\n server.put('/api/admin/config', updateConfigHandler, { public: true });\n server.post('/api/admin/restart', restartHandler, { public: true });\n server.get('/api/admin/logs', getLogsHandler, { public: true });\n server.get('/api/admin/logs/stream', streamLogsHandler, { public: true });\n server.get('/api/admin/logs/file', getLogFileHandler, { public: true });\n\n logger.log('[Admin] Admin API routes registered');\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CommandModule } from 'yargs';
|
|
2
2
|
import { type PodModelDescriptor } from '@undefineds.co/models';
|
|
3
|
+
import { type CliAuthContext } from '../lib/auth-context';
|
|
3
4
|
interface ObjArgs {
|
|
4
5
|
url?: string;
|
|
5
6
|
json: boolean;
|
|
@@ -28,7 +29,36 @@ interface ResolvedObjSelector {
|
|
|
28
29
|
limit: number;
|
|
29
30
|
includeMetadata: boolean;
|
|
30
31
|
}
|
|
32
|
+
interface DescriptorObject {
|
|
33
|
+
schema: string;
|
|
34
|
+
subject: string;
|
|
35
|
+
resourceUrl: string;
|
|
36
|
+
etag?: string | null;
|
|
37
|
+
revision?: string | null;
|
|
38
|
+
object: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
type ItemResult = {
|
|
41
|
+
index: number;
|
|
42
|
+
ok: boolean;
|
|
43
|
+
code: string;
|
|
44
|
+
message?: string;
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
};
|
|
47
|
+
type ObjMutationContext = CliAuthContext & {
|
|
48
|
+
planningOnly?: boolean;
|
|
49
|
+
planningWarning?: string;
|
|
50
|
+
pendingOnly?: boolean;
|
|
51
|
+
pendingWarning?: string;
|
|
52
|
+
outboxPath?: string;
|
|
53
|
+
};
|
|
54
|
+
export declare function resolveObjMutationContext(argv: ObjArgs, commit: boolean): Promise<ObjMutationContext>;
|
|
55
|
+
export declare function getObjLocalOutboxPath(): string;
|
|
31
56
|
export declare function redactDescriptorObject(descriptor: PodModelDescriptor, value: Record<string, unknown>): Record<string, unknown>;
|
|
57
|
+
export declare function serializeSchemaDescriptor(descriptor: PodModelDescriptor): Record<string, unknown>;
|
|
58
|
+
export declare function listSchemaDescriptors(input?: {
|
|
59
|
+
domain?: string;
|
|
60
|
+
}, descriptors?: readonly PodModelDescriptor[]): Record<string, unknown>[];
|
|
61
|
+
export declare function describeSchemaDescriptor(schemaOrAlias: string, descriptors?: readonly PodModelDescriptor[]): Record<string, unknown> | null;
|
|
32
62
|
export declare function buildDescriptorUpsertSparql(descriptor: PodModelDescriptor, subject: string, row: ObjMutationRow): string;
|
|
33
63
|
export declare function buildDescriptorPatchSparql(descriptor: PodModelDescriptor, subject: string, set: Record<string, unknown>): string;
|
|
34
64
|
export declare function buildDescriptorLinkSparql(subject: string, predicate: string, object: string): string;
|
|
@@ -40,5 +70,20 @@ export declare function extractReservedWhereSelectors(where: Record<string, unkn
|
|
|
40
70
|
path?: string;
|
|
41
71
|
};
|
|
42
72
|
export declare function buildDescriptorObjectQuery(selector: ResolvedObjSelector): string;
|
|
73
|
+
export declare function descriptorObjectFromTurtle(descriptor: PodModelDescriptor, subject: string, resourceUrl: string, turtle: string): DescriptorObject | null;
|
|
74
|
+
export declare function descriptorUpsertPlanItem(input: {
|
|
75
|
+
descriptor: PodModelDescriptor;
|
|
76
|
+
index: number;
|
|
77
|
+
commit: boolean;
|
|
78
|
+
podRoot: string;
|
|
79
|
+
row: ObjMutationRow;
|
|
80
|
+
}): ItemResult;
|
|
81
|
+
export declare function executeRows(input: {
|
|
82
|
+
argv: ObjArgs;
|
|
83
|
+
rows: ObjMutationRow[];
|
|
84
|
+
defaultSchema?: string;
|
|
85
|
+
commit: boolean;
|
|
86
|
+
}): Promise<ItemResult[]>;
|
|
87
|
+
export declare function mutationItemsResultCode(items: ItemResult[], commit: boolean): 'plan_ready' | 'committed' | 'pending_local' | 'partial_failure';
|
|
43
88
|
export declare const objCommand: CommandModule<object, ObjArgs>;
|
|
44
89
|
export {};
|