@lead-routing/cli 0.6.2 → 0.6.3

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 +117 -25
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "
9
9
  import { exec } from "child_process";
10
10
  import { platform } from "os";
11
11
  import { join as join5 } from "path";
12
- import { intro, outro, note as note3, log as log7, confirm, cancel as cancel3, isCancel as isCancel3, password as promptPassword } from "@clack/prompts";
12
+ import { intro, outro, note as note3, log as log7, confirm, cancel as cancel3, isCancel as isCancel3, password as promptPassword, select, text as text3 } from "@clack/prompts";
13
13
  import chalk2 from "chalk";
14
14
 
15
15
  // src/steps/prerequisites.ts
@@ -1208,16 +1208,108 @@ async function runInit(options = {}) {
1208
1208
  let auth;
1209
1209
  try {
1210
1210
  auth = await requireAuth();
1211
- } catch (err) {
1212
- log7.error(err instanceof Error ? err.message : "Authentication required");
1213
- note3(
1214
- `Run one of the following:
1215
-
1216
- ${chalk2.cyan("lead-routing signup")} Create a new account
1217
- ${chalk2.cyan("lead-routing login")} Log in to existing account`,
1218
- "Account Required"
1219
- );
1220
- process.exit(1);
1211
+ } catch {
1212
+ const action = await select({
1213
+ message: "You need an account to continue. What would you like to do?",
1214
+ options: [
1215
+ { value: "signup", label: "Create a new account" },
1216
+ { value: "login", label: "Log in to existing account" }
1217
+ ]
1218
+ });
1219
+ if (isCancel3(action)) {
1220
+ cancel3("Setup cancelled.");
1221
+ process.exit(0);
1222
+ }
1223
+ if (action === "signup") {
1224
+ const firstName = await text3({ message: "First name", placeholder: "John", validate: (v) => v.trim() ? void 0 : "Required" });
1225
+ if (isCancel3(firstName)) {
1226
+ cancel3("Setup cancelled.");
1227
+ process.exit(0);
1228
+ }
1229
+ const lastName = await text3({ message: "Last name", placeholder: "Smith", validate: (v) => v.trim() ? void 0 : "Required" });
1230
+ if (isCancel3(lastName)) {
1231
+ cancel3("Setup cancelled.");
1232
+ process.exit(0);
1233
+ }
1234
+ const signupEmail = await text3({ message: "Email", placeholder: "john@acme.com", validate: (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.trim()) ? void 0 : "Invalid email" });
1235
+ if (isCancel3(signupEmail)) {
1236
+ cancel3("Setup cancelled.");
1237
+ process.exit(0);
1238
+ }
1239
+ const signupPw = await promptPassword({ message: "Password (min 8 characters)", validate: (v) => v.length >= 8 ? void 0 : "Must be at least 8 characters" });
1240
+ if (isCancel3(signupPw)) {
1241
+ cancel3("Setup cancelled.");
1242
+ process.exit(0);
1243
+ }
1244
+ const confirmPw = await promptPassword({ message: "Confirm password", validate: (v) => v === signupPw ? void 0 : "Passwords do not match" });
1245
+ if (isCancel3(confirmPw)) {
1246
+ cancel3("Setup cancelled.");
1247
+ process.exit(0);
1248
+ }
1249
+ log7.step("Creating account...");
1250
+ try {
1251
+ await apiSignup({ firstName: firstName.trim(), lastName: lastName.trim(), email: signupEmail.trim(), password: signupPw });
1252
+ log7.success("Account created!");
1253
+ } catch (err) {
1254
+ log7.error(err instanceof Error ? err.message : "Signup failed");
1255
+ process.exit(1);
1256
+ }
1257
+ note3(
1258
+ `Check your email (${signupEmail.trim()}) for a verification link.
1259
+ After verifying, press Enter to continue.`,
1260
+ "Verify Email"
1261
+ );
1262
+ await text3({ message: "Press Enter once you've verified your email...", defaultValue: "" });
1263
+ log7.step("Logging in...");
1264
+ try {
1265
+ const { token, customer } = await apiLogin(signupEmail.trim(), signupPw);
1266
+ if (!customer.emailVerified) {
1267
+ log7.warn("Email not verified yet.");
1268
+ const resend = await confirm({ message: "Resend verification email?" });
1269
+ if (resend && !isCancel3(resend)) {
1270
+ await apiResendVerification(token).catch(() => {
1271
+ });
1272
+ log7.info("Verification email sent. Verify and re-run `lead-routing init`.");
1273
+ }
1274
+ process.exit(1);
1275
+ }
1276
+ saveCredentials({ token, customer, storedAt: (/* @__PURE__ */ new Date()).toISOString() });
1277
+ auth = { token, customer, storedAt: (/* @__PURE__ */ new Date()).toISOString() };
1278
+ } catch (err) {
1279
+ log7.error(err instanceof Error ? err.message : "Login failed");
1280
+ process.exit(1);
1281
+ }
1282
+ } else {
1283
+ const loginEmail = await text3({ message: "Email", placeholder: "john@acme.com" });
1284
+ if (isCancel3(loginEmail)) {
1285
+ cancel3("Setup cancelled.");
1286
+ process.exit(0);
1287
+ }
1288
+ const loginPw = await promptPassword({ message: "Password" });
1289
+ if (isCancel3(loginPw)) {
1290
+ cancel3("Setup cancelled.");
1291
+ process.exit(0);
1292
+ }
1293
+ log7.step("Authenticating...");
1294
+ try {
1295
+ const { token, customer } = await apiLogin(loginEmail.trim(), loginPw);
1296
+ if (!customer.emailVerified) {
1297
+ log7.warn("Email not verified yet.");
1298
+ const resend = await confirm({ message: "Resend verification email?" });
1299
+ if (resend && !isCancel3(resend)) {
1300
+ await apiResendVerification(token).catch(() => {
1301
+ });
1302
+ log7.info("Verification email sent. Verify and re-run `lead-routing init`.");
1303
+ }
1304
+ process.exit(1);
1305
+ }
1306
+ saveCredentials({ token, customer, storedAt: (/* @__PURE__ */ new Date()).toISOString() });
1307
+ auth = { token, customer, storedAt: (/* @__PURE__ */ new Date()).toISOString() };
1308
+ } catch (err) {
1309
+ log7.error(err instanceof Error ? err.message : "Login failed");
1310
+ process.exit(1);
1311
+ }
1312
+ }
1221
1313
  }
1222
1314
  log7.success(`Logged in as ${auth.customer.firstName} ${auth.customer.lastName} \u2014 ${formatTierBadge(auth.customer.tier)}`);
1223
1315
  try {
@@ -1591,7 +1683,7 @@ function runConfigShow() {
1591
1683
  }
1592
1684
 
1593
1685
  // src/commands/sfdc.ts
1594
- import { intro as intro5, outro as outro5, text as text3, note as note4, confirm as confirm2, log as log14, isCancel as isCancel4, cancel as cancel4 } from "@clack/prompts";
1686
+ import { intro as intro5, outro as outro5, text as text4, note as note4, confirm as confirm2, log as log14, isCancel as isCancel4, cancel as cancel4 } from "@clack/prompts";
1595
1687
  import chalk6 from "chalk";
1596
1688
  import { exec as exec2 } from "child_process";
1597
1689
  import { platform as platform2 } from "os";
@@ -1723,9 +1815,9 @@ Content-Type: application/zip\r
1723
1815
  body
1724
1816
  });
1725
1817
  if (!res.ok) {
1726
- const text7 = await res.text();
1818
+ const text8 = await res.text();
1727
1819
  throw new Error(
1728
- `Metadata deploy request failed (${res.status}): ${text7}`
1820
+ `Metadata deploy request failed (${res.status}): ${text8}`
1729
1821
  );
1730
1822
  }
1731
1823
  const result = await res.json();
@@ -1742,9 +1834,9 @@ Content-Type: application/zip\r
1742
1834
  const url = `${this.baseUrl}/metadata/deployRequest/${deployId}?includeDetails=true`;
1743
1835
  const res = await fetch(url, { headers: this.headers() });
1744
1836
  if (!res.ok) {
1745
- const text7 = await res.text();
1837
+ const text8 = await res.text();
1746
1838
  throw new Error(
1747
- `Deploy status check failed (${res.status}): ${text7}`
1839
+ `Deploy status check failed (${res.status}): ${text8}`
1748
1840
  );
1749
1841
  }
1750
1842
  const data = await res.json();
@@ -2112,13 +2204,13 @@ async function runSfdcDeploy() {
2112
2204
  log14.info(`Using config from ${dir}/lead-routing.json`);
2113
2205
  } else {
2114
2206
  log14.warn("No lead-routing.json found \u2014 enter the URLs from your installation.");
2115
- const rawApp = await text3({
2207
+ const rawApp = await text4({
2116
2208
  message: "App URL (e.g. https://leads.acme.com)",
2117
2209
  validate: (v) => !v ? "Required" : void 0
2118
2210
  });
2119
2211
  if (typeof rawApp === "symbol") process.exit(0);
2120
2212
  appUrl = rawApp.trim();
2121
- const rawEngine = await text3({
2213
+ const rawEngine = await text4({
2122
2214
  message: "Engine URL (e.g. https://engine.acme.com or https://acme.com:3001)",
2123
2215
  validate: (v) => !v ? "Required" : void 0
2124
2216
  });
@@ -2148,7 +2240,7 @@ Install URL: ${chalk6.cyan(MANAGED_PACKAGE_INSTALL_URL2)}`,
2148
2240
  } else {
2149
2241
  log14.success("Salesforce package installed");
2150
2242
  }
2151
- const alias = await text3({
2243
+ const alias = await text4({
2152
2244
  message: "Salesforce org alias (used to log in)",
2153
2245
  placeholder: "lead-routing",
2154
2246
  initialValue: "lead-routing",
@@ -2351,7 +2443,7 @@ import {
2351
2443
  intro as intro9,
2352
2444
  outro as outro9,
2353
2445
  spinner as spinner8,
2354
- text as text6,
2446
+ text as text7,
2355
2447
  password as promptPassword4,
2356
2448
  note as note7,
2357
2449
  log as log18,
@@ -2470,7 +2562,7 @@ async function runDev(opts = {}) {
2470
2562
  "You need a Salesforce Connected App with callback URL:\n http://localhost:3000/api/auth/sfdc/callback",
2471
2563
  "Before you begin"
2472
2564
  );
2473
- const clientId = await text6({
2565
+ const clientId = await text7({
2474
2566
  message: "Consumer Key (Client ID)",
2475
2567
  validate: (v) => !v ? "Required" : void 0
2476
2568
  });
@@ -2483,7 +2575,7 @@ async function runDev(opts = {}) {
2483
2575
  cancel5("Cancelled.");
2484
2576
  process.exit(0);
2485
2577
  }
2486
- const loginUrl = await text6({
2578
+ const loginUrl = await text7({
2487
2579
  message: "Login URL",
2488
2580
  initialValue: "https://login.salesforce.com",
2489
2581
  validate: (v) => !v ? "Required" : void 0
@@ -2582,7 +2674,7 @@ async function runDev(opts = {}) {
2582
2674
  "Sets up a full Lead Routing stack locally using Docker.\nNo SSH, no VPS, no manual steps.",
2583
2675
  "First-time setup"
2584
2676
  );
2585
- const adminEmail = await text6({
2677
+ const adminEmail = await text7({
2586
2678
  message: "Admin email",
2587
2679
  placeholder: "you@company.com",
2588
2680
  validate: (v) => {
@@ -2604,7 +2696,7 @@ async function runDev(opts = {}) {
2604
2696
  "Optional \u2014 needed to connect Salesforce.\nPress Enter to skip; add credentials later via `lead-routing config sfdc`.",
2605
2697
  "Salesforce Connected App"
2606
2698
  );
2607
- const sfdcClientId = await text6({
2699
+ const sfdcClientId = await text7({
2608
2700
  message: "Consumer Key (Client ID)",
2609
2701
  placeholder: "Leave blank to skip"
2610
2702
  });
@@ -2615,7 +2707,7 @@ async function runDev(opts = {}) {
2615
2707
  if (isCancel8(s)) bail3(s);
2616
2708
  sfdcClientSecret = s.trim();
2617
2709
  }
2618
- const tunnelUrl = await text6({
2710
+ const tunnelUrl = await text7({
2619
2711
  message: "Engine tunnel URL (for Salesforce webhooks)",
2620
2712
  placeholder: "Leave blank \u2014 use `ssh -R 80:localhost:3001 localhost.run` to get one"
2621
2713
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lead-routing/cli",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Self-hosted deployment CLI for Lead Routing",
5
5
  "homepage": "https://github.com/lead-routing/lead-routing",
6
6
  "keywords": [