{"version":3,"file":"one-click.cjs","names":["path","os","fs","analyzeProject","renderHtmlReport","startAutomatorInspector","explainAutomatorFailure","startWebPanel"],"sources":["../src/one-click.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { explainAutomatorFailure, startAutomatorInspector } from './automator-inspector';\nimport { analyzeProject, type ProjectAnalysis } from './core';\nimport { renderHtmlReport } from './html-report';\nimport { startWebPanel } from './web-panel';\n\nconst OUTPUT_DIR = path.join(os.tmpdir(), 'uniapp-miniprogram-devtool');\nconst PROJECT_OPTIONS = ['--project', '--proj', '-p'];\nconst WECHAT_DEVTOOLS_OPTIONS = ['--wechat-devtools', '--wd', '-w'];\nconst CLI_PATH_OPTIONS = ['--cli-path'];\nconst PORT_OPTIONS = ['--port'];\nconst AUTOMATOR_PORT_OPTIONS = ['--automator-port'];\nconst VALUE_OPTIONS = new Set([\n  ...PROJECT_OPTIONS,\n  ...WECHAT_DEVTOOLS_OPTIONS,\n  ...CLI_PATH_OPTIONS,\n  ...PORT_OPTIONS,\n  ...AUTOMATOR_PORT_OPTIONS,\n]);\n\nfunction isMpWeixinRoot(dir: string): boolean {\n  return fs.existsSync(path.join(dir, 'app.json')) && fs.existsSync(path.join(dir, 'app.js'));\n}\n\nfunction safeStat(file: string): fs.Stats | null {\n  try {\n    return fs.statSync(file);\n  } catch (_error) {\n    return null;\n  }\n}\n\nfunction normalizeCliPath(value: string): string {\n  const resolved = path.resolve(value);\n  if (resolved.endsWith('.app')) return path.join(resolved, 'Contents', 'MacOS', 'cli');\n  return resolved;\n}\n\nfunction getOptionValue(argv: string[], name: string): string | undefined {\n  for (let index = 0; index < argv.length; index += 1) {\n    const arg = argv[index];\n    if (arg === name) return argv[index + 1];\n    if (arg.startsWith(`${name}=`)) return arg.slice(name.length + 1);\n  }\n  return undefined;\n}\n\nfunction getAnyOptionValue(argv: string[], names: string[]): string | undefined {\n  for (const name of names) {\n    const value = getOptionValue(argv, name);\n    if (value) return value;\n  }\n  return undefined;\n}\n\nfunction firstPositionalArg(argv: string[]): string | undefined {\n  for (let index = 0; index < argv.length; index += 1) {\n    const arg = argv[index];\n    const optionName = arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg;\n    if (VALUE_OPTIONS.has(optionName)) {\n      if (!arg.includes('=')) index += 1;\n      continue;\n    }\n    if (!arg.startsWith('-')) return arg;\n  }\n  return undefined;\n}\n\nfunction getRequiredTarget(argv: string[]): string {\n  const explicitTarget = getAnyOptionValue(argv, PROJECT_OPTIONS) || firstPositionalArg(argv);\n  if (!explicitTarget) {\n    throw new Error(\n      '请显式传入 uni-app / uni-app x 微信小程序编译产物目录，例如：umpd -p ./unpackage/dist/dev/mp-weixin',\n    );\n  }\n\n  const resolved = path.resolve(explicitTarget);\n  if (!isMpWeixinRoot(resolved)) {\n    throw new Error(`不是有效的 mp-weixin 产物目录：${resolved}。请确认该目录包含 app.json 和 app.js。`);\n  }\n  return resolved;\n}\n\nfunction getRequiredCliPath(argv: string[]): string {\n  const rawCliPath = getAnyOptionValue(argv, CLI_PATH_OPTIONS) || getAnyOptionValue(argv, WECHAT_DEVTOOLS_OPTIONS);\n  if (!rawCliPath) {\n    throw new Error('请显式传入微信开发者工具路径，例如：umpd -w /Volumes/Elements/Applications/wechatwebdevtools.app');\n  }\n\n  const cliPath = normalizeCliPath(rawCliPath);\n  if (!fs.existsSync(cliPath)) {\n    throw new Error(`不是有效的微信开发者工具路径：${rawCliPath}。可以通过 -w 直接传 .app 路径。`);\n  }\n\n  return cliPath;\n}\n\nfunction writeText(file: string, content: string): void {\n  fs.mkdirSync(path.dirname(file), { recursive: true });\n  fs.writeFileSync(file, content);\n}\n\nfunction latestTreeMtime(root: string): number {\n  let latest = 0;\n  function walk(dir: string): void {\n    let entries: fs.Dirent[];\n    try {\n      entries = fs.readdirSync(dir, { withFileTypes: true });\n    } catch (_error) {\n      return;\n    }\n    for (const entry of entries) {\n      const full = path.join(dir, entry.name);\n      if (entry.isDirectory()) {\n        if (entry.name === 'common') continue;\n        walk(full);\n      } else if (/\\.(js|wxml|map)$/.test(entry.name)) {\n        latest = Math.max(latest, safeStat(full)?.mtimeMs || 0);\n      }\n    }\n  }\n  walk(root);\n  return latest;\n}\n\nfunction generate(targetRoot: string): ProjectAnalysis {\n  const result = analyzeProject(targetRoot);\n  const keymapPath = path.join(OUTPUT_DIR, 'uniapp-miniprogram-devtool.json');\n  const htmlPath = path.join(OUTPUT_DIR, 'uniapp-miniprogram-devtool.html');\n\n  writeText(keymapPath, JSON.stringify(result, null, 2));\n  writeText(htmlPath, renderHtmlReport(result));\n\n  return result;\n}\n\nfunction printStartup(targetRoot: string, result: ProjectAnalysis): void {\n  const htmlPath = path.join(OUTPUT_DIR, 'uniapp-miniprogram-devtool.html');\n  const pageCount = Object.keys(result.pages).length;\n  const keyCount = Object.values(result.pages).reduce((sum, page) => sum + page.keys.length, 0);\n\n  console.clear();\n  console.log('uniapp-miniprogram-devtool');\n  console.log('目标目录:', targetRoot);\n  console.log('页面数:', pageCount, '键数量:', keyCount);\n  console.log('报告文件:', htmlPath);\n  console.log('');\n  console.log('正在启动并连接微信开发者工具自动化...');\n}\n\nexport async function main(argv: string[]): Promise<void> {\n  const cliPath = getRequiredCliPath(argv);\n  const panelPort = Number(\n    getOptionValue(argv, '--port') ||\n      process.env.UNIAPP_MINIPROGRAM_DEVTOOL_PORT ||\n      process.env.UNIAPPX_KEYMAP_PORT ||\n      17890,\n  );\n  const rawAutomatorPort =\n    getAnyOptionValue(argv, AUTOMATOR_PORT_OPTIONS) || process.env.UNIAPP_MINIPROGRAM_DEVTOOL_AUTOMATOR_PORT;\n  const automatorPort = rawAutomatorPort ? Number(rawAutomatorPort) : undefined;\n  const targetRoot = getRequiredTarget(argv);\n  let lastMtime = 0;\n  let currentAnalysis = generate(targetRoot);\n  printStartup(targetRoot, currentAnalysis);\n\n  let pollTimer: NodeJS.Timeout | undefined;\n  let stopInspector: (() => void) | undefined;\n  let reconnectPromise: Promise<void> | null = null;\n  let shuttingDown = false;\n\n  function updatePanelStatus(status: string): void {\n    webPanel.update({ connected: false, status, route: '', rows: [], updatedAt: new Date().toISOString() });\n  }\n\n  function disposeInspector(): void {\n    stopInspector?.();\n    stopInspector = undefined;\n  }\n\n  async function reconnectInspector(status = '正在启动微信开发者工具自动化...'): Promise<void> {\n    if (shuttingDown) return;\n    if (reconnectPromise) return reconnectPromise;\n\n    updatePanelStatus(status);\n    reconnectPromise = (async () => {\n      disposeInspector();\n      regenerateIfNeeded(true);\n      try {\n        stopInspector = await startAutomatorInspector({\n          projectPath: targetRoot,\n          getAnalysis: () => currentAnalysis,\n          intervalMs: 500,\n          cliPath,\n          port: automatorPort,\n          suppressTerminal: true,\n          onSnapshot: (snapshot) => webPanel.update(snapshot),\n        });\n        process.exitCode = 0;\n      } catch (error) {\n        const message = explainAutomatorFailure(error);\n        webPanel.update({\n          connected: false,\n          status: message,\n          route: '',\n          rows: [],\n          updatedAt: new Date().toISOString(),\n        });\n        console.error(message);\n        process.exitCode = 1;\n      } finally {\n        reconnectPromise = null;\n      }\n    })();\n\n    return reconnectPromise;\n  }\n\n  async function shutdown(exitCode?: number): Promise<void> {\n    if (shuttingDown) return;\n    shuttingDown = true;\n    pollTimer && clearInterval(pollTimer);\n    disposeInspector();\n    webPanel.close();\n    if (typeof exitCode === 'number') process.exit(exitCode);\n  }\n\n  const webPanel = await startWebPanel({\n    port: panelPort,\n    onReconnect: () => reconnectInspector('正在重新连接微信开发者工具自动化...'),\n  });\n  console.log('Web 面板:', webPanel.url);\n  console.log('运行时变量值会显示在 Web 面板中，按 Ctrl+C 停止。');\n  updatePanelStatus('正在启动微信开发者工具自动化...');\n\n  function regenerateIfNeeded(force = false): void {\n    const mtime = latestTreeMtime(targetRoot);\n    if (force || mtime !== lastMtime) {\n      lastMtime = mtime;\n      currentAnalysis = generate(targetRoot);\n    }\n  }\n\n  regenerateIfNeeded(true);\n\n  pollTimer = setInterval(() => regenerateIfNeeded(), 1200);\n\n  process.once('SIGINT', () => void shutdown(130));\n  process.once('SIGTERM', () => void shutdown(143));\n\n  await reconnectInspector();\n}\n\nif (require.main === module) {\n  main(process.argv.slice(2)).catch((error) => {\n    console.error(error?.stack ? error.stack : String(error));\n    process.exitCode = 1;\n  });\n}\n"],"mappings":"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"}