{"version":3,"sources":["../src/cli/esiurBin.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\r\nimport { existsSync } from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport { join } from \"node:path\";\r\n\r\n/**\r\n * `bin/esiur`'s implementation: a thin launcher for `Esiur.CLI` (the .NET\r\n * global tool that generates TypeScript/JS resource stubs from C# resource\r\n * definitions). This package has no CLI logic of its own — it locates the\r\n * installed dotnet tool and forwards straight through to it, or explains how\r\n * to install it.\r\n */\r\n\r\nexport const TOOL_PACKAGE_ID = \"Esiur.CLI\";\r\nconst TOOL_COMMAND = \"esiur\";\r\n\r\nexport interface ProcessRunResult {\r\n  status: number | null;\r\n  stdout?: string;\r\n  error?: Error;\r\n}\r\n\r\n/** Injected in tests so the detection/forwarding logic never needs a real dotnet install to exercise. */\r\nexport interface ProcessRunner {\r\n  run(command: string, args: string[], stdio: \"inherit\" | \"ignore\" | \"pipe\"): ProcessRunResult;\r\n  fileExists(path: string): boolean;\r\n}\r\n\r\nexport const defaultRunner: ProcessRunner = {\r\n  run(command, args, stdio) {\r\n    const result = spawnSync(command, args, {\r\n      stdio: stdio === \"pipe\" ? [\"ignore\", \"pipe\", \"ignore\"] : stdio,\r\n      encoding: \"utf8\",\r\n    });\r\n    return {\r\n      status: result.status,\r\n      stdout: typeof result.stdout === \"string\" ? result.stdout : undefined,\r\n      error: result.error,\r\n    };\r\n  },\r\n  fileExists: existsSync,\r\n};\r\n\r\n/** Default install location of a `dotnet tool install -g` global tool's launcher shim. */\r\nexport function defaultDotnetToolShimPath(platform: NodeJS.Platform = process.platform): string {\r\n  const exe = platform === \"win32\" ? `${TOOL_COMMAND}.exe` : TOOL_COMMAND;\r\n  return join(homedir(), \".dotnet\", \"tools\", exe);\r\n}\r\n\r\nexport function isDotnetInstalled(runner: ProcessRunner = defaultRunner): boolean {\r\n  const result = runner.run(\"dotnet\", [\"--version\"], \"ignore\");\r\n  return result.error == null && result.status === 0;\r\n}\r\n\r\nexport type EsiurCliLocation = { path: string } | { installedElsewhere: true } | undefined;\r\n\r\n/**\r\n * Locate the installed `Esiur.CLI` global tool. Checks the default global-tool\r\n * shim path first (covers the overwhelming majority of installs); if that's\r\n * absent but `dotnet tool list -g` still reports the package, it's installed\r\n * at a non-default location (e.g. via `--tool-path`) this wrapper can't\r\n * reliably resolve — reported distinctly so `main` can explain rather than\r\n * silently fail, and so a bare `esiur` PATH lookup (which could resolve back\r\n * to *this* wrapper if it's ever installed under the same name) is never needed.\r\n */\r\nexport function findEsiurCli(runner: ProcessRunner = defaultRunner): EsiurCliLocation {\r\n  const shimPath = defaultDotnetToolShimPath();\r\n  if (runner.fileExists(shimPath)) return { path: shimPath };\r\n\r\n  const listing = runner.run(\"dotnet\", [\"tool\", \"list\", \"-g\"], \"pipe\");\r\n  if (listing.stdout?.toLowerCase().includes(TOOL_PACKAGE_ID.toLowerCase())) {\r\n    return { installedElsewhere: true };\r\n  }\r\n  return undefined;\r\n}\r\n\r\nexport function installGuidance(runner: ProcessRunner = defaultRunner): string {\r\n  const lines = [\"The Esiur CLI is a .NET tool and isn't installed yet.\", \"\"];\r\n  if (!isDotnetInstalled(runner)) {\r\n    lines.push(\"You'll need the .NET SDK first: https://dotnet.microsoft.com/download\", \"\");\r\n  }\r\n  lines.push(\r\n    \"Install it with:\",\r\n    \"\",\r\n    `  dotnet tool install -g ${TOOL_PACKAGE_ID}`,\r\n    \"\",\r\n    \"Then re-run this command.\",\r\n  );\r\n  return lines.join(\"\\n\");\r\n}\r\n\r\nexport function customPathGuidance(): string {\r\n  return [\r\n    `${TOOL_PACKAGE_ID} is installed, but not at the default global-tool location this wrapper`,\r\n    \"checks (~/.dotnet/tools) — probably installed with a custom --tool-path.\",\r\n    \"\",\r\n    \"Run it directly instead (make sure its install directory is on your PATH), or reinstall it as\",\r\n    \"a normal global tool for this wrapper to find it automatically:\",\r\n    \"\",\r\n    `  dotnet tool uninstall -g ${TOOL_PACKAGE_ID}`,\r\n    `  dotnet tool install -g ${TOOL_PACKAGE_ID}`,\r\n  ].join(\"\\n\");\r\n}\r\n\r\n/** Runs the wrapper end to end; returns the process exit code. */\r\nexport function main(argv: string[], runner: ProcessRunner = defaultRunner): number {\r\n  const found = findEsiurCli(runner);\r\n\r\n  if (!found) {\r\n    console.error(installGuidance(runner));\r\n    return 1;\r\n  }\r\n  if (\"installedElsewhere\" in found) {\r\n    console.error(customPathGuidance());\r\n    return 1;\r\n  }\r\n\r\n  const result = runner.run(found.path, argv, \"inherit\");\r\n  if (result.error) {\r\n    console.error(`Failed to run the Esiur CLI: ${result.error.message}`);\r\n    return 1;\r\n  }\r\n  return result.status ?? 1;\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAA0B;AAC1B,qBAA2B;AAC3B,qBAAwB;AACxB,uBAAqB;AAUd,IAAM,kBAAkB;AAC/B,IAAM,eAAe;AAcd,IAAM,gBAA+B;AAAA,EAC1C,IAAI,SAAS,MAAM,OAAO;AACxB,UAAM,aAAS,qCAAU,SAAS,MAAM;AAAA,MACtC,OAAO,UAAU,SAAS,CAAC,UAAU,QAAQ,QAAQ,IAAI;AAAA,MACzD,UAAU;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,MACL,QAAQ,OAAO;AAAA,MACf,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AAAA,MAC5D,OAAO,OAAO;AAAA,IAChB;AAAA,EACF;AAAA,EACA,YAAY;AACd;AAGO,SAAS,0BAA0B,WAA4B,QAAQ,UAAkB;AAC9F,QAAM,MAAM,aAAa,UAAU,GAAG,YAAY,SAAS;AAC3D,aAAO,2BAAK,wBAAQ,GAAG,WAAW,SAAS,GAAG;AAChD;AAEO,SAAS,kBAAkB,SAAwB,eAAwB;AAChF,QAAM,SAAS,OAAO,IAAI,UAAU,CAAC,WAAW,GAAG,QAAQ;AAC3D,SAAO,OAAO,SAAS,QAAQ,OAAO,WAAW;AACnD;AAaO,SAAS,aAAa,SAAwB,eAAiC;AACpF,QAAM,WAAW,0BAA0B;AAC3C,MAAI,OAAO,WAAW,QAAQ,EAAG,QAAO,EAAE,MAAM,SAAS;AAEzD,QAAM,UAAU,OAAO,IAAI,UAAU,CAAC,QAAQ,QAAQ,IAAI,GAAG,MAAM;AACnE,MAAI,QAAQ,QAAQ,YAAY,EAAE,SAAS,gBAAgB,YAAY,CAAC,GAAG;AACzE,WAAO,EAAE,oBAAoB,KAAK;AAAA,EACpC;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,SAAwB,eAAuB;AAC7E,QAAM,QAAQ,CAAC,yDAAyD,EAAE;AAC1E,MAAI,CAAC,kBAAkB,MAAM,GAAG;AAC9B,UAAM,KAAK,yEAAyE,EAAE;AAAA,EACxF;AACA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,4BAA4B,eAAe;AAAA,IAC3C;AAAA,IACA;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,qBAA6B;AAC3C,SAAO;AAAA,IACL,GAAG,eAAe;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,8BAA8B,eAAe;AAAA,IAC7C,4BAA4B,eAAe;AAAA,EAC7C,EAAE,KAAK,IAAI;AACb;AAGO,SAAS,KAAK,MAAgB,SAAwB,eAAuB;AAClF,QAAM,QAAQ,aAAa,MAAM;AAEjC,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,gBAAgB,MAAM,CAAC;AACrC,WAAO;AAAA,EACT;AACA,MAAI,wBAAwB,OAAO;AACjC,YAAQ,MAAM,mBAAmB,CAAC;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,OAAO,IAAI,MAAM,MAAM,MAAM,SAAS;AACrD,MAAI,OAAO,OAAO;AAChB,YAAQ,MAAM,gCAAgC,OAAO,MAAM,OAAO,EAAE;AACpE,WAAO;AAAA,EACT;AACA,SAAO,OAAO,UAAU;AAC1B;","names":[]}