@botonic/nx-plugin 2.31.0 → 2.32.0-alpha.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/migrations.json +1 -8
- package/package.json +7 -4
- package/src/executors/build-node-app/executor-impl.d.ts +5 -0
- package/src/executors/build-node-app/executor-impl.js +65 -0
- package/src/executors/build-node-app/executor.d.ts +4 -2
- package/src/executors/build-node-app/executor.js +3 -41
- package/src/executors/delete-bot/executor-impl.d.ts +5 -0
- package/src/executors/delete-bot/executor-impl.js +110 -0
- package/src/executors/delete-bot/executor.d.ts +4 -2
- package/src/executors/delete-bot/executor.js +3 -86
- package/src/executors/deploy-netlify-snapshot/executor-impl.d.ts +8 -0
- package/src/executors/deploy-netlify-snapshot/executor-impl.js +79 -0
- package/src/executors/deploy-netlify-snapshot/executor.d.ts +4 -5
- package/src/executors/deploy-netlify-snapshot/executor.js +3 -55
- package/src/executors/deploy-to-hubtype/executor-impl.d.ts +5 -0
- package/src/executors/deploy-to-hubtype/executor-impl.js +172 -0
- package/src/executors/deploy-to-hubtype/executor.d.ts +4 -2
- package/src/executors/deploy-to-hubtype/executor.js +3 -148
- package/src/executors/e2e-webchat/executor-impl.d.ts +5 -0
- package/src/executors/e2e-webchat/executor-impl.js +134 -0
- package/src/executors/e2e-webchat/executor.d.ts +4 -2
- package/src/executors/e2e-webchat/executor.js +4 -111
- package/src/executors/integrate-provider/executor-impl.d.ts +5 -0
- package/src/executors/integrate-provider/executor-impl.js +153 -0
- package/src/executors/integrate-provider/executor.d.ts +4 -2
- package/src/executors/integrate-provider/executor.js +3 -129
- package/src/executors/login-to-hubtype/executor-impl.d.ts +5 -0
- package/src/executors/login-to-hubtype/executor-impl.js +77 -0
- package/src/executors/login-to-hubtype/executor.d.ts +4 -2
- package/src/executors/login-to-hubtype/executor.js +3 -53
- package/src/executors/logout-from-hubtype/executor-impl.d.ts +3 -0
- package/src/executors/logout-from-hubtype/executor-impl.js +54 -0
- package/src/executors/logout-from-hubtype/executor.d.ts +5 -1
- package/src/executors/logout-from-hubtype/executor.js +3 -30
- package/src/executors/run-lambda/executor-impl.d.ts +5 -0
- package/src/executors/run-lambda/executor-impl.js +65 -0
- package/src/executors/run-lambda/executor.d.ts +4 -2
- package/src/executors/run-lambda/executor.js +3 -41
- package/src/executors/serve-bot/executor-impl.d.ts +5 -0
- package/src/executors/serve-bot/executor-impl.js +530 -0
- package/src/executors/serve-bot/executor.d.ts +4 -2
- package/src/executors/serve-bot/executor.js +3 -506
- package/src/generators/action/generator-impl.d.ts +4 -0
- package/src/generators/action/generator-impl.js +112 -0
- package/src/generators/action/generator.d.ts +2 -3
- package/src/generators/action/generator.js +2 -87
- package/src/generators/bot-app/files/vite/webchat.config.ts.template +10 -2
- package/src/generators/bot-app/generator-impl.d.ts +4 -0
- package/src/generators/bot-app/generator-impl.js +328 -0
- package/src/generators/bot-app/generator.d.ts +2 -4
- package/src/generators/bot-app/generator.js +2 -295
- package/src/generators/custom-message/generator-impl.d.ts +4 -0
- package/src/generators/custom-message/generator-impl.js +235 -0
- package/src/generators/custom-message/generator.d.ts +2 -3
- package/src/generators/custom-message/generator.js +2 -210
- package/src/generators/preset/generator-impl.d.ts +4 -0
- package/src/generators/preset/generator-impl.js +127 -0
- package/src/generators/preset/generator.d.ts +2 -4
- package/src/generators/preset/generator.js +2 -95
- package/src/generators/remove-custom-message/generator-impl.d.ts +4 -0
- package/src/generators/remove-custom-message/generator-impl.js +259 -0
- package/src/generators/remove-custom-message/generator.d.ts +2 -3
- package/src/generators/remove-custom-message/generator.js +2 -234
- package/src/generators/webview/generator-impl.d.ts +4 -0
- package/src/generators/webview/generator-impl.js +179 -0
- package/src/generators/webview/generator.d.ts +2 -3
- package/src/generators/webview/generator.js +2 -154
- package/src/index.d.ts +1 -0
- package/src/index.js +3 -1
- package/src/lib/delegate/delegate-executor.d.ts +6 -0
- package/src/lib/delegate/delegate-executor.js +119 -0
- package/src/lib/delegate/delegate-generator.d.ts +2 -0
- package/src/lib/delegate/delegate-generator.js +128 -0
- package/src/lib/serve-mode/index.d.ts +25 -0
- package/src/lib/serve-mode/index.js +183 -0
- package/src/generators/bot-app/files/vite/plugins/dev-log-viewer-html.plugin.ts.template +0 -65
- package/src/migrations/install-claude-update-skills/install-claude-update-skills.migration.d.ts +0 -2
- package/src/migrations/install-claude-update-skills/install-claude-update-skills.migration.js +0 -290
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,514 +15,13 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
var executor_exports = {};
|
|
30
20
|
__export(executor_exports, {
|
|
31
21
|
default: () => serveBotExecutor
|
|
32
22
|
});
|
|
33
23
|
module.exports = __toCommonJS(executor_exports);
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
var readline = __toESM(require("readline"));
|
|
38
|
-
var import_cloudflared_tunnel = require("../../lib/cloudflared-tunnel");
|
|
39
|
-
var import_executor_helpers = require("../../lib/util/executor-helpers");
|
|
40
|
-
var import_sam_container_cleanup = require("../../lib/util/sam-container-cleanup");
|
|
41
|
-
const colors = {
|
|
42
|
-
bot: "\x1B[36m",
|
|
43
|
-
// Cyan
|
|
44
|
-
lambda: "\x1B[33m",
|
|
45
|
-
// Yellow
|
|
46
|
-
webchat: "\x1B[32m",
|
|
47
|
-
// Green
|
|
48
|
-
webviews: "\x1B[35m",
|
|
49
|
-
// Magenta
|
|
50
|
-
reset: "\x1B[0m",
|
|
51
|
-
dim: "\x1B[2m",
|
|
52
|
-
bold: "\x1B[1m"
|
|
53
|
-
};
|
|
54
|
-
let logFilePath = null;
|
|
55
|
-
function initLogFile(projectRoot) {
|
|
56
|
-
const logsDir = (0, import_path.join)(projectRoot, ".botonic", "logs");
|
|
57
|
-
(0, import_fs.mkdirSync)(logsDir, { recursive: true });
|
|
58
|
-
const logPath = (0, import_path.join)(logsDir, "serve-bot.log");
|
|
59
|
-
(0, import_fs.writeFileSync)(logPath, "");
|
|
60
|
-
return logPath;
|
|
61
|
-
}
|
|
62
|
-
function writeToLogFile(line) {
|
|
63
|
-
if (logFilePath) {
|
|
64
|
-
try {
|
|
65
|
-
(0, import_fs.appendFileSync)(logFilePath, `${line}
|
|
66
|
-
`);
|
|
67
|
-
} catch {
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function checkFrontailInstalled(cwd) {
|
|
72
|
-
try {
|
|
73
|
-
(0, import_child_process.execSync)(`${cwd}/node_modules/.bin/frontail --help`, {
|
|
74
|
-
stdio: "pipe",
|
|
75
|
-
cwd
|
|
76
|
-
});
|
|
77
|
-
return true;
|
|
78
|
-
} catch {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
function startFrontail(logPath, port, cwd) {
|
|
83
|
-
if (!checkFrontailInstalled(cwd)) {
|
|
84
|
-
console.warn(`${colors.bold}\u26A0\uFE0F frontail is not installed.${colors.reset}`);
|
|
85
|
-
console.warn(
|
|
86
|
-
` Run: ${colors.dim}pnpm install${colors.reset} to install dependencies
|
|
87
|
-
`
|
|
88
|
-
);
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
const frontailProcess = (0, import_child_process.spawn)(
|
|
92
|
-
`${cwd}/node_modules/.bin/frontail`,
|
|
93
|
-
[
|
|
94
|
-
"--port",
|
|
95
|
-
port.toString(),
|
|
96
|
-
"--theme",
|
|
97
|
-
"dark",
|
|
98
|
-
"--lines",
|
|
99
|
-
"500",
|
|
100
|
-
"--ui-hide-topbar",
|
|
101
|
-
logPath
|
|
102
|
-
],
|
|
103
|
-
{
|
|
104
|
-
cwd,
|
|
105
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
106
|
-
detached: false
|
|
107
|
-
}
|
|
108
|
-
);
|
|
109
|
-
frontailProcess.on("error", (error) => {
|
|
110
|
-
console.error(
|
|
111
|
-
`${colors.dim}[log-viewer]${colors.reset} Error: ${error.message}`
|
|
112
|
-
);
|
|
113
|
-
});
|
|
114
|
-
return frontailProcess;
|
|
115
|
-
}
|
|
116
|
-
function tryReadWebchatDevPort(projectRoot) {
|
|
117
|
-
try {
|
|
118
|
-
const configPath = (0, import_path.join)(projectRoot, "vite", "build.config.ts");
|
|
119
|
-
const content = (0, import_fs.readFileSync)(configPath, "utf8");
|
|
120
|
-
const match = content.match(/webchat:\s*\{\s*port:\s*(\d+)/);
|
|
121
|
-
if (match) return parseInt(match[1], 10);
|
|
122
|
-
} catch {
|
|
123
|
-
}
|
|
124
|
-
return 4201;
|
|
125
|
-
}
|
|
126
|
-
function getAppIdFromEnvFile(projectRoot) {
|
|
127
|
-
const envFilePath = (0, import_path.join)(projectRoot, ".env.local");
|
|
128
|
-
if (!(0, import_fs.existsSync)(envFilePath)) {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
try {
|
|
132
|
-
const envContent = (0, import_fs.readFileSync)(envFilePath, "utf8");
|
|
133
|
-
const lines = envContent.split("\n");
|
|
134
|
-
const appIdKey = "VITE_HUBTYPE_APP_ID";
|
|
135
|
-
for (const line of lines) {
|
|
136
|
-
if (line.startsWith(`${appIdKey}=`)) {
|
|
137
|
-
return line.split("=")[1]?.trim();
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return null;
|
|
141
|
-
} catch (error) {
|
|
142
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
143
|
-
console.warn(`\u26A0\uFE0F Could not read .env.local file: ${errorMessage}`);
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
function prefixOutput(stream, prefix, color) {
|
|
148
|
-
if (!stream) return;
|
|
149
|
-
const rl = readline.createInterface({ input: stream });
|
|
150
|
-
rl.on("line", (line) => {
|
|
151
|
-
const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false });
|
|
152
|
-
const formattedLine = `${colors.dim}${timestamp}${colors.reset} ${color}[${prefix}]${colors.reset} ${line}`;
|
|
153
|
-
console.log(formattedLine);
|
|
154
|
-
writeToLogFile(`${timestamp} [${prefix}] ${line}`);
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
function spawnProcess(command, name, color, cwd) {
|
|
158
|
-
const child = (0, import_child_process.spawn)("sh", ["-c", command], {
|
|
159
|
-
cwd,
|
|
160
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
161
|
-
env: { ...process.env, FORCE_COLOR: "1" }
|
|
162
|
-
});
|
|
163
|
-
prefixOutput(child.stdout, name, color);
|
|
164
|
-
prefixOutput(child.stderr, name, color);
|
|
165
|
-
return { name, color, process: child };
|
|
166
|
-
}
|
|
167
|
-
async function serveBotExecutor(options, context) {
|
|
168
|
-
if (!context.projectName) {
|
|
169
|
-
throw new Error("Project name is required");
|
|
170
|
-
}
|
|
171
|
-
const projectRoot = context.projectsConfigurations?.projects?.[context.projectName]?.root;
|
|
172
|
-
if (!projectRoot) {
|
|
173
|
-
throw new Error(`Could not find project root for ${context.projectName}`);
|
|
174
|
-
}
|
|
175
|
-
const configuration = options.configuration || "prod";
|
|
176
|
-
const fullProjectRoot = (0, import_path.join)(context.root, projectRoot);
|
|
177
|
-
const configPath = (0, import_path.join)(context.root, projectRoot, "vite.config.ts");
|
|
178
|
-
const appId = getAppIdFromEnvFile(fullProjectRoot);
|
|
179
|
-
if (!appId) {
|
|
180
|
-
console.warn(
|
|
181
|
-
`\u26A0\uFE0F VITE_HUBTYPE_APP_ID not found in .env.local \u2014 will be set automatically after deploy`
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
console.log(`${colors.dim}Clearing Vite cache...${colors.reset}`);
|
|
185
|
-
const viteCacheDirs = [
|
|
186
|
-
(0, import_path.join)(context.root, "node_modules", ".vite"),
|
|
187
|
-
(0, import_path.join)(fullProjectRoot, "node_modules", ".vite"),
|
|
188
|
-
(0, import_path.join)(fullProjectRoot, ".vite")
|
|
189
|
-
];
|
|
190
|
-
for (const dir of viteCacheDirs) {
|
|
191
|
-
try {
|
|
192
|
-
if ((0, import_fs.existsSync)(dir)) {
|
|
193
|
-
(0, import_child_process.execSync)(`rm -rf "${dir}"`, { stdio: "pipe" });
|
|
194
|
-
}
|
|
195
|
-
} catch {
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
console.log(`${colors.dim}Vite cache cleared.${colors.reset}`);
|
|
199
|
-
const cleanupResult = (0, import_sam_container_cleanup.cleanupPreviousSamContainersByLabel)(fullProjectRoot);
|
|
200
|
-
if (cleanupResult === "removed") {
|
|
201
|
-
console.log(
|
|
202
|
-
`${colors.dim}[lambda] Removed previous run's container (reused slot).${colors.reset}`
|
|
203
|
-
);
|
|
204
|
-
} else if (cleanupResult === "none") {
|
|
205
|
-
console.log(
|
|
206
|
-
`${colors.dim}[lambda] No previous Lambda container to clean up.${colors.reset}`
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
logFilePath = null;
|
|
210
|
-
const logViewerPort = options.logViewerPort ?? 9001;
|
|
211
|
-
const webchatDevPort = tryReadWebchatDevPort(fullProjectRoot);
|
|
212
|
-
logFilePath = initLogFile(fullProjectRoot);
|
|
213
|
-
const frontailProcess = startFrontail(
|
|
214
|
-
logFilePath,
|
|
215
|
-
logViewerPort,
|
|
216
|
-
context.root
|
|
217
|
-
);
|
|
218
|
-
const logViewerInfo = `${colors.dim}Webchat:${colors.reset} ${colors.bold}http://localhost:${webchatDevPort}/?logs=${logViewerPort}${colors.reset} (with logs panel)
|
|
219
|
-
${colors.dim}Log viewer:${colors.reset} http://localhost:${logViewerPort}`;
|
|
220
|
-
const useTunnel = true;
|
|
221
|
-
const tunnelPort = options.tunnelPort ?? 3001;
|
|
222
|
-
let effectiveLambdaEndpoint = options.lambdaEndpoint;
|
|
223
|
-
let startLambda = !options.skipLambda && !effectiveLambdaEndpoint;
|
|
224
|
-
let tunnelDeployResult;
|
|
225
|
-
let devSessionLambdaFunctionName;
|
|
226
|
-
let registeredTunnelUrl;
|
|
227
|
-
let deployedBotId;
|
|
228
|
-
let selectedBotId;
|
|
229
|
-
let deployedApiUrl;
|
|
230
|
-
let deployedAccessToken;
|
|
231
|
-
let deployedRefreshToken;
|
|
232
|
-
let deployedClientId;
|
|
233
|
-
if (useTunnel) {
|
|
234
|
-
await (0, import_executor_helpers.ensureHubtypeLoginBeforeTunnel)(context, fullProjectRoot, {
|
|
235
|
-
env: options.env,
|
|
236
|
-
configuration
|
|
237
|
-
});
|
|
238
|
-
try {
|
|
239
|
-
selectedBotId = await (0, import_executor_helpers.selectBotForServe)(context, fullProjectRoot, {
|
|
240
|
-
env: options.env,
|
|
241
|
-
configuration,
|
|
242
|
-
botName: options.botName
|
|
243
|
-
});
|
|
244
|
-
} catch (botDeployErr) {
|
|
245
|
-
if ((0, import_executor_helpers.isBotDeployedRestartRequired)(botDeployErr)) {
|
|
246
|
-
if (frontailProcess) {
|
|
247
|
-
frontailProcess.kill("SIGTERM");
|
|
248
|
-
}
|
|
249
|
-
if (process.stdin.isTTY) {
|
|
250
|
-
try {
|
|
251
|
-
process.stdin.setRawMode(false);
|
|
252
|
-
} catch {
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
process.stdin.pause();
|
|
256
|
-
process.stdin.unref();
|
|
257
|
-
return { success: true };
|
|
258
|
-
}
|
|
259
|
-
throw botDeployErr;
|
|
260
|
-
}
|
|
261
|
-
console.log(
|
|
262
|
-
`${colors.dim}Starting tunnel flow (Lambda + cloudflared + dev session registration)...${colors.reset}
|
|
263
|
-
`
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
const processes = [];
|
|
267
|
-
try {
|
|
268
|
-
if (useTunnel) {
|
|
269
|
-
const lambdaPath = (0, import_path.join)(fullProjectRoot, "src/server/lambda");
|
|
270
|
-
const lambdaCommand = "sam local start-lambda --warm-containers EAGER --skip-pull-image";
|
|
271
|
-
processes.push(
|
|
272
|
-
spawnProcess(lambdaCommand, "lambda", colors.lambda, lambdaPath)
|
|
273
|
-
);
|
|
274
|
-
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
275
|
-
console.log(
|
|
276
|
-
`${colors.dim}Starting Cloudflare tunnel (cloudflared)...${colors.reset}`
|
|
277
|
-
);
|
|
278
|
-
const { url: tunnelUrl, process: cloudflaredProcess } = await (0, import_cloudflared_tunnel.startCloudflaredTunnel)(tunnelPort);
|
|
279
|
-
processes.push({
|
|
280
|
-
name: "tunnel",
|
|
281
|
-
color: colors.lambda,
|
|
282
|
-
process: cloudflaredProcess
|
|
283
|
-
});
|
|
284
|
-
console.log(`${colors.dim}Tunnel URL: ${tunnelUrl}${colors.reset}
|
|
285
|
-
`);
|
|
286
|
-
console.log(
|
|
287
|
-
`${colors.dim}Setting up dev bot and writing dev session env vars...${colors.reset}`
|
|
288
|
-
);
|
|
289
|
-
const deployResult = await (0, import_executor_helpers.performDeployLocalRuntimeWithEndpoint)(
|
|
290
|
-
context,
|
|
291
|
-
fullProjectRoot,
|
|
292
|
-
tunnelUrl,
|
|
293
|
-
{
|
|
294
|
-
env: options.env,
|
|
295
|
-
configuration,
|
|
296
|
-
whatsappPhone: options.phone,
|
|
297
|
-
selectedBotId
|
|
298
|
-
}
|
|
299
|
-
);
|
|
300
|
-
tunnelDeployResult = {
|
|
301
|
-
targetEnvironment: deployResult.targetEnvironment,
|
|
302
|
-
environmentVariables: deployResult.environmentVariables,
|
|
303
|
-
teardownWebchat: deployResult.teardownWebchat
|
|
304
|
-
};
|
|
305
|
-
devSessionLambdaFunctionName = deployResult.lambdaFunctionName;
|
|
306
|
-
registeredTunnelUrl = tunnelUrl;
|
|
307
|
-
deployedBotId = deployResult.botId ?? "";
|
|
308
|
-
deployedApiUrl = deployResult.apiUrl ?? "https://api.hubtype.com";
|
|
309
|
-
deployedAccessToken = deployResult.accessToken ?? "";
|
|
310
|
-
deployedRefreshToken = deployResult.refreshToken ?? "";
|
|
311
|
-
deployedClientId = deployResult.clientId ?? "";
|
|
312
|
-
const resolvedEnv = ["local", "dev", "dev2", "qa", "prod"].includes(deployResult.targetEnvironment) ? deployResult.targetEnvironment : "local";
|
|
313
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
314
|
-
fullProjectRoot,
|
|
315
|
-
"VITE_DEV_SESSION_URL",
|
|
316
|
-
tunnelUrl,
|
|
317
|
-
resolvedEnv
|
|
318
|
-
);
|
|
319
|
-
if (devSessionLambdaFunctionName) {
|
|
320
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
321
|
-
fullProjectRoot,
|
|
322
|
-
"VITE_DEV_LAMBDA_FUNCTION_NAME",
|
|
323
|
-
devSessionLambdaFunctionName,
|
|
324
|
-
resolvedEnv
|
|
325
|
-
);
|
|
326
|
-
}
|
|
327
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
328
|
-
fullProjectRoot,
|
|
329
|
-
"VITE_DEV_BOT_ID",
|
|
330
|
-
deployResult.botId ?? "",
|
|
331
|
-
resolvedEnv
|
|
332
|
-
);
|
|
333
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
334
|
-
fullProjectRoot,
|
|
335
|
-
"VITE_DEV_API_URL",
|
|
336
|
-
deployResult.apiUrl ?? "https://api.hubtype.com",
|
|
337
|
-
resolvedEnv
|
|
338
|
-
);
|
|
339
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
340
|
-
fullProjectRoot,
|
|
341
|
-
"VITE_DEV_ACCESS_TOKEN",
|
|
342
|
-
deployResult.accessToken ?? "",
|
|
343
|
-
resolvedEnv
|
|
344
|
-
);
|
|
345
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
346
|
-
fullProjectRoot,
|
|
347
|
-
"VITE_DEV_REFRESH_TOKEN",
|
|
348
|
-
deployResult.refreshToken ?? "",
|
|
349
|
-
resolvedEnv
|
|
350
|
-
);
|
|
351
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
352
|
-
fullProjectRoot,
|
|
353
|
-
"VITE_DEV_CLIENT_ID",
|
|
354
|
-
deployResult.clientId ?? "",
|
|
355
|
-
resolvedEnv
|
|
356
|
-
);
|
|
357
|
-
console.log(
|
|
358
|
-
`${colors.dim}VITE_DEV_SESSION_URL written to .env.${resolvedEnv}${colors.reset}`
|
|
359
|
-
);
|
|
360
|
-
effectiveLambdaEndpoint = tunnelUrl;
|
|
361
|
-
startLambda = false;
|
|
362
|
-
}
|
|
363
|
-
} catch (tunnelError) {
|
|
364
|
-
const msg = tunnelError instanceof Error ? tunnelError.message : String(tunnelError);
|
|
365
|
-
console.error(`\u274C Tunnel flow failed: ${msg}`);
|
|
366
|
-
if (frontailProcess) {
|
|
367
|
-
frontailProcess.kill("SIGTERM");
|
|
368
|
-
}
|
|
369
|
-
return { success: false };
|
|
370
|
-
}
|
|
371
|
-
let effectiveAppId = appId;
|
|
372
|
-
if (useTunnel) {
|
|
373
|
-
const latestAppId = (0, import_executor_helpers.getAppIdFromEnvFileForConfig)(
|
|
374
|
-
fullProjectRoot,
|
|
375
|
-
configuration
|
|
376
|
-
);
|
|
377
|
-
if (latestAppId) effectiveAppId = latestAppId;
|
|
378
|
-
}
|
|
379
|
-
if (configuration !== "local" && effectiveAppId) {
|
|
380
|
-
await (0, import_executor_helpers.writeAppIdToEnvFile)(fullProjectRoot, effectiveAppId, configuration);
|
|
381
|
-
}
|
|
382
|
-
const useExternalLambda = Boolean(effectiveLambdaEndpoint);
|
|
383
|
-
if (!useTunnel) {
|
|
384
|
-
startLambda = !options.skipLambda && !useExternalLambda;
|
|
385
|
-
}
|
|
386
|
-
console.log(`
|
|
387
|
-
${colors.bold}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
388
|
-
\u2551 \u{1F680} Botonic Dev Server \u2551
|
|
389
|
-
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${colors.reset}
|
|
390
|
-
|
|
391
|
-
${colors.dim}Project:${colors.reset} ${context.projectName}
|
|
392
|
-
${colors.dim}Configuration:${colors.reset} ${configuration}
|
|
393
|
-
${colors.dim}App ID:${colors.reset} ${effectiveAppId}
|
|
394
|
-
${logViewerInfo}
|
|
395
|
-
${useExternalLambda ? `${colors.dim}Lambda (external):${colors.reset} ${effectiveLambdaEndpoint}
|
|
396
|
-
` : ""}
|
|
397
|
-
${colors.bot}[bot]${colors.reset} - Node/Lambda build watcher
|
|
398
|
-
${startLambda ? `${colors.lambda}[lambda]${colors.reset} - AWS SAM local lambda server` : useExternalLambda ? `${colors.lambda}[lambda]${colors.reset} - Using external endpoint (no Docker)` : ""}
|
|
399
|
-
${colors.webchat}[webchat]${colors.reset} - Webchat Vite dev server
|
|
400
|
-
${colors.webviews}[webviews]${colors.reset} - Webviews Vite dev server
|
|
401
|
-
`);
|
|
402
|
-
if (useExternalLambda && !useTunnel) {
|
|
403
|
-
console.log(
|
|
404
|
-
`${colors.dim}\u{1F4A1} Ensure you have run the serve target first to register your dev session.${colors.reset}
|
|
405
|
-
`
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
for (const dir of viteCacheDirs) {
|
|
409
|
-
try {
|
|
410
|
-
if ((0, import_fs.existsSync)(dir)) {
|
|
411
|
-
(0, import_child_process.execSync)(`rm -rf "${dir}"`, { stdio: "pipe" });
|
|
412
|
-
}
|
|
413
|
-
} catch {
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
try {
|
|
417
|
-
const buildCommand = `VITE_CJS_IGNORE_WARNING=true BUILD_TARGET=node vite build --config ${configPath} --watch`;
|
|
418
|
-
processes.push(
|
|
419
|
-
spawnProcess(buildCommand, "bot", colors.bot, fullProjectRoot)
|
|
420
|
-
);
|
|
421
|
-
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
422
|
-
if (startLambda) {
|
|
423
|
-
const lambdaPath = (0, import_path.join)(fullProjectRoot, "src/server/lambda");
|
|
424
|
-
const lambdaCommand = "sam local start-lambda --warm-containers EAGER --skip-pull-image";
|
|
425
|
-
processes.push(
|
|
426
|
-
spawnProcess(lambdaCommand, "lambda", colors.lambda, lambdaPath)
|
|
427
|
-
);
|
|
428
|
-
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
429
|
-
}
|
|
430
|
-
const noOpenEnv = options.open === false ? "VITE_SERVE_OPEN=false " : "";
|
|
431
|
-
const viteEnvAppId = `VITE_HUBTYPE_APP_ID=${effectiveAppId}`;
|
|
432
|
-
const viteDevSessionEnv = registeredTunnelUrl && devSessionLambdaFunctionName ? `VITE_DEV_SESSION_URL=${registeredTunnelUrl} VITE_DEV_LAMBDA_FUNCTION_NAME=${devSessionLambdaFunctionName} ` : "";
|
|
433
|
-
const viteDevCredentialsEnv = deployedBotId ? [
|
|
434
|
-
`VITE_DEV_BOT_ID=${deployedBotId}`,
|
|
435
|
-
`VITE_DEV_API_URL=${deployedApiUrl ?? "https://api.hubtype.com"}`,
|
|
436
|
-
`VITE_DEV_ACCESS_TOKEN=${deployedAccessToken ?? ""}`,
|
|
437
|
-
`VITE_DEV_REFRESH_TOKEN=${deployedRefreshToken ?? ""}`,
|
|
438
|
-
`VITE_DEV_CLIENT_ID=${deployedClientId ?? ""}`
|
|
439
|
-
].join(" ") + " " : "";
|
|
440
|
-
const logViewerEnv = `LOG_VIEWER_PORT=${logViewerPort} `;
|
|
441
|
-
const botHasWhatsapp = deployedBotId ? (0, import_executor_helpers.selectedBotHasActiveWhatsapp)(deployedBotId) : false;
|
|
442
|
-
const whatsappPanelEnv = botHasWhatsapp ? `BOT_HAS_WHATSAPP=1 ${options.phone ? `WHATSAPP_PANEL_PHONE=${options.phone} ` : ""}` : "";
|
|
443
|
-
const webchatCommand = `${noOpenEnv}${logViewerEnv}${viteDevSessionEnv}${viteDevCredentialsEnv}${whatsappPanelEnv}${viteEnvAppId} TARGET_APP=webchat MODE=${configuration} vite --config ${configPath}`;
|
|
444
|
-
processes.push(
|
|
445
|
-
spawnProcess(webchatCommand, "webchat", colors.webchat, fullProjectRoot)
|
|
446
|
-
);
|
|
447
|
-
if (!options.skipWebviews) {
|
|
448
|
-
const webviewsCommand = `${noOpenEnv}${viteDevSessionEnv}${viteEnvAppId} TARGET_APP=webviews MODE=${configuration} vite --config ${configPath}`;
|
|
449
|
-
processes.push(
|
|
450
|
-
spawnProcess(
|
|
451
|
-
webviewsCommand,
|
|
452
|
-
"webviews",
|
|
453
|
-
colors.webviews,
|
|
454
|
-
fullProjectRoot
|
|
455
|
-
)
|
|
456
|
-
);
|
|
457
|
-
}
|
|
458
|
-
let cleanupCalled = false;
|
|
459
|
-
const cleanup = () => {
|
|
460
|
-
if (cleanupCalled) return;
|
|
461
|
-
cleanupCalled = true;
|
|
462
|
-
console.log(
|
|
463
|
-
`
|
|
464
|
-
${colors.bold}\u{1F6D1} Shutting down all processes...${colors.reset}`
|
|
465
|
-
);
|
|
466
|
-
try {
|
|
467
|
-
const envConfig = ["local", "dev", "dev2", "qa", "prod"].includes(tunnelDeployResult?.targetEnvironment ?? "") ? tunnelDeployResult.targetEnvironment : "local";
|
|
468
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
469
|
-
fullProjectRoot,
|
|
470
|
-
"VITE_DEV_SESSION_URL",
|
|
471
|
-
"",
|
|
472
|
-
envConfig
|
|
473
|
-
);
|
|
474
|
-
(0, import_executor_helpers.writeEnvVarToEnvFile)(
|
|
475
|
-
fullProjectRoot,
|
|
476
|
-
"VITE_DEV_LAMBDA_FUNCTION_NAME",
|
|
477
|
-
"",
|
|
478
|
-
envConfig
|
|
479
|
-
);
|
|
480
|
-
} catch {
|
|
481
|
-
}
|
|
482
|
-
processes.forEach(({ name, color, process: proc }) => {
|
|
483
|
-
console.log(`${color}[${name}]${colors.reset} Stopping...`);
|
|
484
|
-
proc.kill("SIGTERM");
|
|
485
|
-
});
|
|
486
|
-
if (frontailProcess) {
|
|
487
|
-
console.log(
|
|
488
|
-
`${colors.dim}[log-viewer]${colors.reset} Stopping log viewer...`
|
|
489
|
-
);
|
|
490
|
-
frontailProcess.kill("SIGTERM");
|
|
491
|
-
}
|
|
492
|
-
};
|
|
493
|
-
process.on("SIGINT", cleanup);
|
|
494
|
-
process.on("SIGTERM", cleanup);
|
|
495
|
-
process.on("exit", cleanup);
|
|
496
|
-
return new Promise((resolve) => {
|
|
497
|
-
let exitCount = 0;
|
|
498
|
-
const totalProcesses = processes.length;
|
|
499
|
-
processes.forEach(({ name, color, process: proc }) => {
|
|
500
|
-
proc.on("exit", (code) => {
|
|
501
|
-
console.log(
|
|
502
|
-
`${color}[${name}]${colors.reset} Process exited with code ${code}`
|
|
503
|
-
);
|
|
504
|
-
exitCount++;
|
|
505
|
-
if (code !== 0 && code !== null) {
|
|
506
|
-
cleanup();
|
|
507
|
-
resolve({ success: false });
|
|
508
|
-
}
|
|
509
|
-
if (exitCount === totalProcesses) {
|
|
510
|
-
resolve({ success: true });
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
proc.on("error", (error) => {
|
|
514
|
-
console.error(
|
|
515
|
-
`${color}[${name}]${colors.reset} Error: ${error.message}`
|
|
516
|
-
);
|
|
517
|
-
cleanup();
|
|
518
|
-
resolve({ success: false });
|
|
519
|
-
});
|
|
520
|
-
});
|
|
521
|
-
});
|
|
522
|
-
} catch (error) {
|
|
523
|
-
if ((0, import_executor_helpers.isBotDeployedRestartRequired)(error)) {
|
|
524
|
-
return { success: true };
|
|
525
|
-
}
|
|
526
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
527
|
-
console.error(`\u274C Error starting dev server:`, errorMessage);
|
|
528
|
-
return { success: false };
|
|
529
|
-
}
|
|
24
|
+
var import_delegate_executor = require("../../lib/delegate/delegate-executor");
|
|
25
|
+
async function serveBotExecutor(options, ctx) {
|
|
26
|
+
return (0, import_delegate_executor.runLocalExecutor)(__filename, "serve-bot", options, ctx);
|
|
530
27
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var generator_impl_exports = {};
|
|
20
|
+
__export(generator_impl_exports, {
|
|
21
|
+
default: () => generator_impl_default
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(generator_impl_exports);
|
|
24
|
+
var import_devkit = require("@nx/devkit");
|
|
25
|
+
var import_bot_app_utils = require("../shared/bot-app-utils");
|
|
26
|
+
const MODULE_DIR = __dirname;
|
|
27
|
+
function normalizeOptions(tree, options) {
|
|
28
|
+
const { projectRoot, sourceRoot } = (0, import_bot_app_utils.validateBotAppProject)(
|
|
29
|
+
tree,
|
|
30
|
+
options.project
|
|
31
|
+
);
|
|
32
|
+
const paths = (0, import_bot_app_utils.resolveStandardPaths)(sourceRoot);
|
|
33
|
+
const name = (0, import_devkit.names)(options.name);
|
|
34
|
+
const fileName = name.fileName;
|
|
35
|
+
const className = name.className;
|
|
36
|
+
return {
|
|
37
|
+
...options,
|
|
38
|
+
projectName: options.project,
|
|
39
|
+
projectRoot,
|
|
40
|
+
fileName,
|
|
41
|
+
className,
|
|
42
|
+
actionsPath: paths.actionsPath,
|
|
43
|
+
routesPath: paths.routesPath,
|
|
44
|
+
resolvedRouteMatcher: options.routeMatcher ?? fileName
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function addFilesToProject(tree, options) {
|
|
48
|
+
const name = (0, import_devkit.names)(options.name);
|
|
49
|
+
const templateOptions = {
|
|
50
|
+
...options,
|
|
51
|
+
...name,
|
|
52
|
+
name: name.fileName
|
|
53
|
+
// __name__ in filenames must be kebab-case
|
|
54
|
+
};
|
|
55
|
+
(0, import_devkit.generateFiles)(
|
|
56
|
+
tree,
|
|
57
|
+
(0, import_devkit.joinPathFragments)(MODULE_DIR, "files"),
|
|
58
|
+
options.actionsPath,
|
|
59
|
+
templateOptions
|
|
60
|
+
);
|
|
61
|
+
if (options.skipTests) {
|
|
62
|
+
const testFilePath = `${options.actionsPath}/${options.fileName}.spec.ts`;
|
|
63
|
+
if (tree.exists(testFilePath)) {
|
|
64
|
+
tree.delete(testFilePath);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function updateActionsIndex(tree, options) {
|
|
69
|
+
(0, import_bot_app_utils.addExportToIndex)(
|
|
70
|
+
tree,
|
|
71
|
+
`${options.actionsPath}/index.ts`,
|
|
72
|
+
`export * from './${options.fileName}'`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
function updateRoutes(tree, options) {
|
|
76
|
+
if (options.skipRoute) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
(0, import_bot_app_utils.addActionImportToRoutes)(tree, options.routesPath, options.className);
|
|
80
|
+
(0, import_bot_app_utils.insertRouteBeforeFlowBuilder)(tree, options.routesPath, [
|
|
81
|
+
` {`,
|
|
82
|
+
` text: '${options.resolvedRouteMatcher}',`,
|
|
83
|
+
` action: async () => await ${options.className}(botonicContext),`,
|
|
84
|
+
` },`
|
|
85
|
+
]);
|
|
86
|
+
}
|
|
87
|
+
async function generator_impl_default(tree, options) {
|
|
88
|
+
console.log(`Creating action: ${options.name}`);
|
|
89
|
+
const normalizedOptions = normalizeOptions(tree, options);
|
|
90
|
+
console.log(`Project: ${normalizedOptions.projectName}`);
|
|
91
|
+
console.log(`Location: ${normalizedOptions.actionsPath}`);
|
|
92
|
+
addFilesToProject(tree, normalizedOptions);
|
|
93
|
+
updateActionsIndex(tree, normalizedOptions);
|
|
94
|
+
updateRoutes(tree, normalizedOptions);
|
|
95
|
+
await (0, import_devkit.formatFiles)(tree);
|
|
96
|
+
console.log(`
|
|
97
|
+
Successfully created action: ${normalizedOptions.className}`);
|
|
98
|
+
console.log(`Next steps:`);
|
|
99
|
+
console.log(
|
|
100
|
+
` 1. Implement the logic in: ${normalizedOptions.actionsPath}/${normalizedOptions.fileName}.ts`
|
|
101
|
+
);
|
|
102
|
+
if (!options.skipRoute) {
|
|
103
|
+
console.log(
|
|
104
|
+
` 2. Test by sending '${normalizedOptions.resolvedRouteMatcher}' in the webchat`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (!options.skipTests) {
|
|
108
|
+
console.log(
|
|
109
|
+
` 3. Update the tests in: ${normalizedOptions.actionsPath}/${normalizedOptions.fileName}.spec.ts`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Tree } from '@nx/devkit';
|
|
1
|
+
import type { Tree } from '@nx/devkit';
|
|
2
2
|
import type { ActionGeneratorSchema } from './schema';
|
|
3
|
-
export default function (tree: Tree, options: ActionGeneratorSchema): Promise<void>;
|
|
4
|
-
export { ActionGeneratorSchema };
|
|
3
|
+
export default function (tree: Tree, options: ActionGeneratorSchema): Promise<void | import("@nx/devkit").GeneratorCallback>;
|