@lead-routing/cli 0.1.12 → 0.1.13

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.
Files changed (2) hide show
  1. package/dist/index.js +91 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1038,7 +1038,7 @@ function patchXml(content, tag, value) {
1038
1038
  async function sfdcDeployInline(params) {
1039
1039
  const { appUrl, engineUrl, orgAlias, installDir } = params;
1040
1040
  const s = spinner7();
1041
- const { code: authCheck } = await execa3(
1041
+ const { exitCode: authCheck } = await execa3(
1042
1042
  "sf",
1043
1043
  ["org", "display", "--target-org", orgAlias, "--json"],
1044
1044
  { reject: false }
@@ -2005,9 +2005,97 @@ async function runSfdcDeploy() {
2005
2005
  );
2006
2006
  }
2007
2007
 
2008
+ // src/commands/uninstall.ts
2009
+ import { rmSync as rmSync2, existsSync as existsSync6 } from "fs";
2010
+ import { intro as intro6, outro as outro6, log as log16, confirm as confirm3, password as promptPassword3, isCancel as isCancel5 } from "@clack/prompts";
2011
+ import chalk7 from "chalk";
2012
+ async function runUninstall() {
2013
+ console.log();
2014
+ intro6(chalk7.bold.red("Lead Routing \u2014 Uninstall"));
2015
+ const dir = findInstallDir();
2016
+ if (!dir) {
2017
+ log16.error(
2018
+ "No lead-routing.json found. Run this command from your install directory."
2019
+ );
2020
+ process.exit(1);
2021
+ }
2022
+ const cfg = readConfig(dir);
2023
+ if (!cfg.ssh) {
2024
+ log16.error(
2025
+ "This lead-routing.json was created with an older CLI version and has no SSH config. Please manually SSH into your server and run:\n\n cd ~/lead-routing && docker compose down -v && cd ~ && rm -rf ~/lead-routing"
2026
+ );
2027
+ process.exit(1);
2028
+ }
2029
+ log16.warn(chalk7.red("This will permanently destroy:"));
2030
+ log16.warn(` \u2022 Remote: ${cfg.ssh.username}@${cfg.ssh.host}:${cfg.remoteDir}`);
2031
+ log16.warn(" \u2514\u2500 All containers, Postgres data, Redis data, config files");
2032
+ log16.warn(` \u2022 Local: ${dir}/`);
2033
+ log16.warn(" \u2514\u2500 docker-compose.yml, .env.web, .env.engine, Caddyfile, lead-routing.json");
2034
+ const confirmed = await confirm3({
2035
+ message: chalk7.bold("Are you sure you want to uninstall? This cannot be undone."),
2036
+ initialValue: false
2037
+ });
2038
+ if (isCancel5(confirmed) || !confirmed) {
2039
+ log16.info("Uninstall cancelled.");
2040
+ process.exit(0);
2041
+ }
2042
+ const ssh = new SshConnection();
2043
+ let sshPassword;
2044
+ if (!cfg.ssh.privateKeyPath) {
2045
+ const pw = await promptPassword3({
2046
+ message: `SSH password for ${cfg.ssh.username}@${cfg.ssh.host}`
2047
+ });
2048
+ if (isCancel5(pw)) process.exit(0);
2049
+ sshPassword = pw;
2050
+ }
2051
+ try {
2052
+ await ssh.connect({
2053
+ host: cfg.ssh.host,
2054
+ port: cfg.ssh.port,
2055
+ username: cfg.ssh.username,
2056
+ privateKeyPath: cfg.ssh.privateKeyPath,
2057
+ password: sshPassword,
2058
+ remoteDir: cfg.remoteDir
2059
+ });
2060
+ log16.success(`Connected to ${cfg.ssh.host}`);
2061
+ } catch (err) {
2062
+ log16.error(`SSH connection failed: ${String(err)}`);
2063
+ process.exit(1);
2064
+ }
2065
+ try {
2066
+ const remoteDir = await ssh.resolveHome(cfg.remoteDir);
2067
+ log16.step("Stopping containers and removing volumes");
2068
+ const { code } = await ssh.execSilent("docker compose down -v", remoteDir);
2069
+ if (code !== 0) {
2070
+ log16.warn("docker compose down reported an error \u2014 directory may already be partially removed");
2071
+ } else {
2072
+ log16.success("Containers and volumes removed");
2073
+ }
2074
+ log16.step(`Removing remote directory ${remoteDir}`);
2075
+ await ssh.exec(`rm -rf ${remoteDir}`);
2076
+ log16.success("Remote directory removed");
2077
+ } catch (err) {
2078
+ const message = err instanceof Error ? err.message : String(err);
2079
+ log16.error(`Remote cleanup failed: ${message}`);
2080
+ process.exit(1);
2081
+ } finally {
2082
+ await ssh.disconnect();
2083
+ }
2084
+ log16.step("Removing local config directory");
2085
+ if (existsSync6(dir)) {
2086
+ rmSync2(dir, { recursive: true, force: true });
2087
+ log16.success(`Removed ${dir}`);
2088
+ }
2089
+ outro6(
2090
+ chalk7.green("\u2714 Uninstall complete.") + `
2091
+
2092
+ Run ${chalk7.cyan("npx @lead-routing/cli init")} to start fresh.`
2093
+ );
2094
+ }
2095
+
2008
2096
  // src/index.ts
2009
2097
  var program = new Command();
2010
- program.name("lead-routing").description("Self-hosted Lead Routing \u2014 scaffold, deploy, and manage your installation").version("0.1.12");
2098
+ program.name("lead-routing").description("Self-hosted Lead Routing \u2014 scaffold, deploy, and manage your installation").version("0.1.13");
2011
2099
  program.command("init").description("Interactive setup wizard \u2014 configure and deploy the full Lead Routing stack").option("--dry-run", "Generate config files without connecting or deploying").option("--resume", "Skip to health check using existing lead-routing.json (post-timeout recovery)").option("--sandbox", "Use Salesforce sandbox (test.salesforce.com) instead of production").option("--ssh-port <port>", "SSH port (default: 22)", parseInt).option("--ssh-user <user>", "SSH username (default: root)").option("--ssh-key <path>", "Path to SSH private key (overrides auto-detection)").option("--remote-dir <path>", "Remote install directory (default: ~/lead-routing)").option("--external-db <url>", "Use external PostgreSQL URL instead of managed Docker container").option("--external-redis <url>", "Use external Redis URL instead of managed Docker container").action((opts) => runInit({
2012
2100
  dryRun: opts.dryRun,
2013
2101
  resume: opts.resume,
@@ -2028,6 +2116,7 @@ config.command("show").description("Print key config values for this installatio
2028
2116
  config.command("sfdc").description("Update Salesforce Connected App credentials (Consumer Key + Secret)").action(runConfigSfdc);
2029
2117
  var sfdc = program.command("sfdc").description("Manage the Salesforce package for this installation");
2030
2118
  sfdc.command("deploy").description("Deploy (or redeploy) the Lead Router Salesforce package to your Salesforce org").action(runSfdcDeploy);
2119
+ program.command("uninstall").description("Stop all containers, remove all data, and delete the remote installation").action(runUninstall);
2031
2120
  program.parseAsync(process.argv).catch((err) => {
2032
2121
  console.error(err instanceof Error ? err.message : String(err));
2033
2122
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lead-routing/cli",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Self-hosted deployment CLI for Lead Routing",
5
5
  "homepage": "https://github.com/lead-routing/lead-routing",
6
6
  "keywords": ["salesforce", "lead-routing", "self-hosted", "deployment", "cli"],