@lead-routing/cli 0.7.0 → 0.8.0
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/index.js
CHANGED
|
@@ -111,7 +111,7 @@ function bail2(value) {
|
|
|
111
111
|
}
|
|
112
112
|
throw new Error("Unexpected cancel");
|
|
113
113
|
}
|
|
114
|
-
async function collectConfig(opts = {}) {
|
|
114
|
+
async function collectConfig(opts = {}, authEmail) {
|
|
115
115
|
const crmType = opts.crmType ?? "salesforce";
|
|
116
116
|
note2(
|
|
117
117
|
"You will need:\n \u2022 Public HTTPS URLs for the web app and routing engine",
|
|
@@ -152,16 +152,22 @@ async function collectConfig(opts = {}) {
|
|
|
152
152
|
const redisPassword = generateSecret(16);
|
|
153
153
|
const managedRedis = !opts.externalRedis;
|
|
154
154
|
const redisUrl = opts.externalRedis ?? `redis://:${redisPassword}@redis:6379`;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
155
|
+
let adminEmail;
|
|
156
|
+
if (authEmail) {
|
|
157
|
+
note2(`Using ${authEmail} as admin email`, "Admin Account");
|
|
158
|
+
adminEmail = authEmail;
|
|
159
|
+
} else {
|
|
160
|
+
note2("This creates the first admin user for the web app.", "Admin Account");
|
|
161
|
+
adminEmail = await text2({
|
|
162
|
+
message: "Admin email address",
|
|
163
|
+
placeholder: "admin@acme.com",
|
|
164
|
+
validate: (v) => {
|
|
165
|
+
if (!v) return "Required";
|
|
166
|
+
if (!v.includes("@")) return "Must be a valid email";
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
if (isCancel2(adminEmail)) bail2(adminEmail);
|
|
170
|
+
}
|
|
165
171
|
const adminPassword = await password2({
|
|
166
172
|
message: "Admin password (min 8 characters)",
|
|
167
173
|
validate: (v) => {
|
|
@@ -173,35 +179,9 @@ async function collectConfig(opts = {}) {
|
|
|
173
179
|
const sessionSecret = generateSecret(32);
|
|
174
180
|
const engineWebhookSecret = generateSecret(32);
|
|
175
181
|
const internalApiKey = generateSecret(32);
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (crmType === "hubspot") {
|
|
180
|
-
note2(
|
|
181
|
-
"Create a HubSpot app at https://developers.hubspot.com/\nYou will need the App ID, Client ID, and Client Secret.",
|
|
182
|
-
"HubSpot Credentials"
|
|
183
|
-
);
|
|
184
|
-
const rawAppId = await text2({
|
|
185
|
-
message: "HubSpot App ID",
|
|
186
|
-
placeholder: "123456",
|
|
187
|
-
validate: (v) => !v?.trim() ? "Required" : void 0
|
|
188
|
-
});
|
|
189
|
-
if (isCancel2(rawAppId)) bail2(rawAppId);
|
|
190
|
-
hubspotAppId = rawAppId.trim();
|
|
191
|
-
const rawClientId = await text2({
|
|
192
|
-
message: "HubSpot Client ID",
|
|
193
|
-
placeholder: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
194
|
-
validate: (v) => !v?.trim() ? "Required" : void 0
|
|
195
|
-
});
|
|
196
|
-
if (isCancel2(rawClientId)) bail2(rawClientId);
|
|
197
|
-
hubspotClientId = rawClientId.trim();
|
|
198
|
-
const rawClientSecret = await password2({
|
|
199
|
-
message: "HubSpot Client Secret",
|
|
200
|
-
validate: (v) => !v?.trim() ? "Required" : void 0
|
|
201
|
-
});
|
|
202
|
-
if (isCancel2(rawClientSecret)) bail2(rawClientSecret);
|
|
203
|
-
hubspotClientSecret = rawClientSecret.trim();
|
|
204
|
-
}
|
|
182
|
+
const hubspotAppId = void 0;
|
|
183
|
+
const hubspotClientId = void 0;
|
|
184
|
+
const hubspotClientSecret = void 0;
|
|
205
185
|
return {
|
|
206
186
|
appUrl: appUrl.trim().replace(/\/+$/, ""),
|
|
207
187
|
engineUrl: engineUrl.trim().replace(/\/+$/, ""),
|
|
@@ -389,9 +369,9 @@ function renderEnvWeb(c) {
|
|
|
389
369
|
...c.crmType === "hubspot" ? [
|
|
390
370
|
``,
|
|
391
371
|
`# HubSpot`,
|
|
392
|
-
`HUBSPOT_CLIENT_ID=${c.hubspotClientId ?? ""}`,
|
|
393
|
-
`HUBSPOT_CLIENT_SECRET=${c.hubspotClientSecret ?? ""}`,
|
|
394
|
-
`HUBSPOT_APP_ID=${c.hubspotAppId ?? ""}`,
|
|
372
|
+
`HUBSPOT_CLIENT_ID=${c.hubspotClientId ?? "c53f3d1c-ff03-4db7-875a-1ebe7b0f98cc"}`,
|
|
373
|
+
`HUBSPOT_CLIENT_SECRET=${c.hubspotClientSecret ?? "f95949ac-6464-40d3-bdaa-893c48749951"}`,
|
|
374
|
+
`HUBSPOT_APP_ID=${c.hubspotAppId ?? "35016223"}`,
|
|
395
375
|
`HUBSPOT_REDIRECT_URI=${c.appUrl}/api/auth/hubspot/callback`
|
|
396
376
|
] : []
|
|
397
377
|
].join("\n");
|
|
@@ -427,6 +407,7 @@ function renderEnvEngine(c) {
|
|
|
427
407
|
...c.crmType === "hubspot" ? [
|
|
428
408
|
``,
|
|
429
409
|
`# HubSpot`,
|
|
410
|
+
`HUBSPOT_CLIENT_ID=${c.hubspotClientId ?? ""}`,
|
|
430
411
|
`HUBSPOT_CLIENT_SECRET=${c.hubspotClientSecret ?? ""}`
|
|
431
412
|
] : []
|
|
432
413
|
].join("\n");
|
|
@@ -1451,7 +1432,7 @@ Install URL: ${chalk2.cyan(MANAGED_PACKAGE_INSTALL_URL)}`,
|
|
|
1451
1432
|
externalDb: options.externalDb,
|
|
1452
1433
|
externalRedis: options.externalRedis,
|
|
1453
1434
|
crmType
|
|
1454
|
-
});
|
|
1435
|
+
}, auth.customer.email);
|
|
1455
1436
|
await checkDnsResolvable(cfg.appUrl, cfg.engineUrl);
|
|
1456
1437
|
log7.step("Step 6/9 Generating config files");
|
|
1457
1438
|
const { dir } = generateFiles(cfg, sshCfg, {
|
|
@@ -1540,6 +1521,12 @@ Files created: docker-compose.yml, Caddyfile, .env.web, .env.engine, lead-routin
|
|
|
1540
1521
|
log7.step("Retrying health check...");
|
|
1541
1522
|
}
|
|
1542
1523
|
}
|
|
1524
|
+
note3(
|
|
1525
|
+
`You can log in to the web app at ${chalk2.cyan(cfg.appUrl)} with:
|
|
1526
|
+
Email: ${cfg.adminEmail}
|
|
1527
|
+
Password: (the password you set during setup)`,
|
|
1528
|
+
"Admin Login"
|
|
1529
|
+
);
|
|
1543
1530
|
try {
|
|
1544
1531
|
const envWebPath = join5(dir, ".env.web");
|
|
1545
1532
|
const envContent = readFileSync4(envWebPath, "utf-8");
|
|
@@ -140,7 +140,7 @@ model Organization {
|
|
|
140
140
|
fieldsSyncedAt DateTime?
|
|
141
141
|
plan Plan @default(FREE)
|
|
142
142
|
isActive Boolean @default(true)
|
|
143
|
-
seatsPurchased Int @default(
|
|
143
|
+
seatsPurchased Int @default(10)
|
|
144
144
|
seatsUsed Int @default(0)
|
|
145
145
|
routingQuotaUsed Int @default(0)
|
|
146
146
|
quotaResetAt DateTime @default(now())
|
package/package.json
CHANGED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
-- CreateEnum
|
|
2
|
-
CREATE TYPE "FlowStatus" AS ENUM ('DRAFT', 'ACTIVE', 'INACTIVE');
|
|
3
|
-
|
|
4
|
-
-- CreateEnum
|
|
5
|
-
CREATE TYPE "FlowNodeType" AS ENUM ('ENTRY', 'DECISION', 'BRANCH_DECISION', 'MATCH', 'ASSIGNMENT', 'UPDATE_FIELD', 'CREATE_TASK', 'FILTER', 'DEFAULT');
|
|
6
|
-
|
|
7
|
-
-- AlterTable
|
|
8
|
-
ALTER TABLE "organizations" ADD COLUMN "routingMode" JSONB;
|
|
9
|
-
|
|
10
|
-
-- AlterTable
|
|
11
|
-
ALTER TABLE "routing_logs" ADD COLUMN "flowId" TEXT,
|
|
12
|
-
ADD COLUMN "flowNodePath" JSONB;
|
|
13
|
-
|
|
14
|
-
-- CreateTable
|
|
15
|
-
CREATE TABLE "routing_flows" (
|
|
16
|
-
"id" TEXT NOT NULL,
|
|
17
|
-
"orgId" TEXT NOT NULL,
|
|
18
|
-
"objectType" "SfdcObjectType" NOT NULL,
|
|
19
|
-
"name" TEXT NOT NULL DEFAULT 'Untitled Flow',
|
|
20
|
-
"status" "FlowStatus" NOT NULL DEFAULT 'DRAFT',
|
|
21
|
-
"triggerEvent" "TriggerEvent" NOT NULL DEFAULT 'BOTH',
|
|
22
|
-
"isDryRun" BOOLEAN NOT NULL DEFAULT false,
|
|
23
|
-
"version" INTEGER NOT NULL DEFAULT 1,
|
|
24
|
-
"publishedAt" TIMESTAMP(3),
|
|
25
|
-
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
26
|
-
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
27
|
-
|
|
28
|
-
CONSTRAINT "routing_flows_pkey" PRIMARY KEY ("id")
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
-- CreateTable
|
|
32
|
-
CREATE TABLE "flow_nodes" (
|
|
33
|
-
"id" TEXT NOT NULL,
|
|
34
|
-
"flowId" TEXT NOT NULL,
|
|
35
|
-
"type" "FlowNodeType" NOT NULL,
|
|
36
|
-
"label" TEXT,
|
|
37
|
-
"positionX" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
|
38
|
-
"positionY" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
|
39
|
-
"config" JSONB,
|
|
40
|
-
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
|
41
|
-
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
42
|
-
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
43
|
-
|
|
44
|
-
CONSTRAINT "flow_nodes_pkey" PRIMARY KEY ("id")
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
-- CreateTable
|
|
48
|
-
CREATE TABLE "flow_edges" (
|
|
49
|
-
"id" TEXT NOT NULL,
|
|
50
|
-
"flowId" TEXT NOT NULL,
|
|
51
|
-
"fromId" TEXT NOT NULL,
|
|
52
|
-
"toId" TEXT NOT NULL,
|
|
53
|
-
"label" TEXT,
|
|
54
|
-
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
|
55
|
-
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
56
|
-
|
|
57
|
-
CONSTRAINT "flow_edges_pkey" PRIMARY KEY ("id")
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
-- CreateIndex
|
|
61
|
-
CREATE UNIQUE INDEX "routing_flows_orgId_objectType_key" ON "routing_flows"("orgId", "objectType");
|
|
62
|
-
|
|
63
|
-
-- AddForeignKey
|
|
64
|
-
ALTER TABLE "routing_flows" ADD CONSTRAINT "routing_flows_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
65
|
-
|
|
66
|
-
-- AddForeignKey
|
|
67
|
-
ALTER TABLE "flow_nodes" ADD CONSTRAINT "flow_nodes_flowId_fkey" FOREIGN KEY ("flowId") REFERENCES "routing_flows"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
68
|
-
|
|
69
|
-
-- AddForeignKey
|
|
70
|
-
ALTER TABLE "flow_edges" ADD CONSTRAINT "flow_edges_flowId_fkey" FOREIGN KEY ("flowId") REFERENCES "routing_flows"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
71
|
-
|
|
72
|
-
-- AddForeignKey
|
|
73
|
-
ALTER TABLE "flow_edges" ADD CONSTRAINT "flow_edges_fromId_fkey" FOREIGN KEY ("fromId") REFERENCES "flow_nodes"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
74
|
-
|
|
75
|
-
-- AddForeignKey
|
|
76
|
-
ALTER TABLE "flow_edges" ADD CONSTRAINT "flow_edges_toId_fkey" FOREIGN KEY ("toId") REFERENCES "flow_nodes"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|