@botonic/nx-plugin 2.23.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/CHANGELOG.md +420 -0
- package/README.md +279 -0
- package/executors.json +55 -0
- package/generators.json +61 -0
- package/migrations.json +40 -0
- package/package.json +54 -0
- package/src/cursor-commands/update-bot.md +114 -0
- package/src/cursor-commands/update-botonic.md +63 -0
- package/src/executors/build-node-app/executor.d.ts +5 -0
- package/src/executors/build-node-app/executor.js +65 -0
- package/src/executors/build-node-app/schema.d.js +16 -0
- package/src/executors/build-node-app/schema.json +25 -0
- package/src/executors/delete-bot/executor.d.ts +5 -0
- package/src/executors/delete-bot/executor.js +112 -0
- package/src/executors/delete-bot/schema.d.js +16 -0
- package/src/executors/delete-bot/schema.json +35 -0
- package/src/executors/deploy-local-runtime/executor.d.ts +5 -0
- package/src/executors/deploy-local-runtime/executor.js +144 -0
- package/src/executors/deploy-local-runtime/schema.d.js +16 -0
- package/src/executors/deploy-local-runtime/schema.json +34 -0
- package/src/executors/deploy-netlify-snapshot/executor.d.ts +8 -0
- package/src/executors/deploy-netlify-snapshot/executor.js +79 -0
- package/src/executors/deploy-netlify-snapshot/schema.d.js +16 -0
- package/src/executors/deploy-netlify-snapshot/schema.json +31 -0
- package/src/executors/deploy-to-hubtype/executor.d.ts +5 -0
- package/src/executors/deploy-to-hubtype/executor.js +308 -0
- package/src/executors/deploy-to-hubtype/schema.d.js +16 -0
- package/src/executors/deploy-to-hubtype/schema.json +31 -0
- package/src/executors/e2e-webchat/botonic-package-publish.spec.ts +84 -0
- package/src/executors/e2e-webchat/executor.d.ts +5 -0
- package/src/executors/e2e-webchat/executor.js +134 -0
- package/src/executors/e2e-webchat/schema.d.js +16 -0
- package/src/executors/e2e-webchat/schema.json +35 -0
- package/src/executors/integrate-provider/executor.d.ts +5 -0
- package/src/executors/integrate-provider/executor.js +155 -0
- package/src/executors/integrate-provider/schema.d.js +16 -0
- package/src/executors/integrate-provider/schema.json +30 -0
- package/src/executors/login-to-hubtype/executor.d.ts +5 -0
- package/src/executors/login-to-hubtype/executor.js +79 -0
- package/src/executors/login-to-hubtype/schema.d.js +16 -0
- package/src/executors/login-to-hubtype/schema.json +25 -0
- package/src/executors/logout-from-hubtype/executor.d.ts +3 -0
- package/src/executors/logout-from-hubtype/executor.js +54 -0
- package/src/executors/logout-from-hubtype/schema.d.js +16 -0
- package/src/executors/logout-from-hubtype/schema.json +9 -0
- package/src/executors/run-lambda/executor.d.ts +5 -0
- package/src/executors/run-lambda/executor.js +65 -0
- package/src/executors/run-lambda/schema.d.js +16 -0
- package/src/executors/run-lambda/schema.json +20 -0
- package/src/executors/serve-bot/executor.d.ts +5 -0
- package/src/executors/serve-bot/executor.js +330 -0
- package/src/executors/serve-bot/schema.d.js +16 -0
- package/src/executors/serve-bot/schema.json +40 -0
- package/src/generators/action/files/__name__.spec.ts.template +15 -0
- package/src/generators/action/files/__name__.ts.template +15 -0
- package/src/generators/action/generator.d.ts +4 -0
- package/src/generators/action/generator.js +112 -0
- package/src/generators/action/schema.d.ts +7 -0
- package/src/generators/action/schema.js +16 -0
- package/src/generators/action/schema.json +43 -0
- package/src/generators/bot-app/files/.eslintrc.json.template +18 -0
- package/src/generators/bot-app/files/README.md.template +148 -0
- package/src/generators/bot-app/files/src/client/custom-messages/index.ts.template +2 -0
- package/src/generators/bot-app/files/src/client/webchat/index.html.template +35 -0
- package/src/generators/bot-app/files/src/client/webchat/index.tsx.template +107 -0
- package/src/generators/bot-app/files/src/client/webchat/styles.css.template +17 -0
- package/src/generators/bot-app/files/src/client/webchat/webchat-tokens-overrides.css.template +2 -0
- package/src/generators/bot-app/files/src/client/webviews/app.tsx.template +8 -0
- package/src/generators/bot-app/files/src/client/webviews/index.html.template +32 -0
- package/src/generators/bot-app/files/src/client/webviews/index.tsx.template +18 -0
- package/src/generators/bot-app/files/src/server/bot/actions/index.ts.template +2 -0
- package/src/generators/bot-app/files/src/server/bot/actions/not-found.ts.template +13 -0
- package/src/generators/bot-app/files/src/server/bot/actions/welcome.ts.template +13 -0
- package/src/generators/bot-app/files/src/server/bot/index.ts.template +43 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/ai-agents/index.ts.template +30 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/flow-builder/index.ts.template +28 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/index.ts.template +11 -0
- package/src/generators/bot-app/files/src/server/bot/routes.ts.template +23 -0
- package/src/generators/bot-app/files/src/server/bot/tools/index.ts.template +5 -0
- package/src/generators/bot-app/files/src/server/bot/tracking.ts.template +35 -0
- package/src/generators/bot-app/files/src/server/bot/types.ts.template +4 -0
- package/src/generators/bot-app/files/src/server/bot/utils.ts.template +9 -0
- package/src/generators/bot-app/files/src/server/lambda/handler.js.template +24 -0
- package/src/generators/bot-app/files/src/server/lambda/package.json +20 -0
- package/src/generators/bot-app/files/src/server/lambda/template.yaml.template +20 -0
- package/src/generators/bot-app/files/src/shared/constants.ts.template +12 -0
- package/src/generators/bot-app/files/vite/base-client.config.ts.template +14 -0
- package/src/generators/bot-app/files/vite/base.config.ts.template +20 -0
- package/src/generators/bot-app/files/vite/build.config.ts.template +65 -0
- package/src/generators/bot-app/files/vite/node.config.ts.template +41 -0
- package/src/generators/bot-app/files/vite/plugins/move-html.plugin.ts.template +36 -0
- package/src/generators/bot-app/files/vite/webchat.config.ts.template +58 -0
- package/src/generators/bot-app/files/vite/webviews.config.ts.template +57 -0
- package/src/generators/bot-app/files/vite.config.ts.template +36 -0
- package/src/generators/bot-app/generator.d.ts +4 -0
- package/src/generators/bot-app/generator.js +294 -0
- package/src/generators/bot-app/schema.d.ts +6 -0
- package/src/generators/bot-app/schema.js +16 -0
- package/src/generators/bot-app/schema.json +36 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/generator.js +92 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/schema.json +15 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/generator.js +97 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/schema.json +15 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/generator.js +165 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/schema.json +15 -0
- package/src/generators/custom-message/files/__name__-output.ts.template +21 -0
- package/src/generators/custom-message/files/__name__.spec.tsx.template +27 -0
- package/src/generators/custom-message/files/__name__.tsx.template +18 -0
- package/src/generators/custom-message/generator.d.ts +4 -0
- package/src/generators/custom-message/generator.js +235 -0
- package/src/generators/custom-message/schema.d.ts +7 -0
- package/src/generators/custom-message/schema.js +16 -0
- package/src/generators/custom-message/schema.json +44 -0
- package/src/generators/preset/files/.cursor/commands/update-bot.md +5 -0
- package/src/generators/preset/files/.cursor/commands/update-botonic.md +5 -0
- package/src/generators/preset/files/.cursor/scripts/update-bot/discover-bots.sh +67 -0
- package/src/generators/preset/files/.cursor/scripts/update-bot/find-migration-guides.sh +70 -0
- package/src/generators/preset/files/.cursor/skills/botonic-action/SKILL.md +167 -0
- package/src/generators/preset/files/.cursor/skills/botonic-custom-message/SKILL.md +231 -0
- package/src/generators/preset/files/.cursor/skills/botonic-webview/SKILL.md +179 -0
- package/src/generators/preset/files/.env.prod.template +2 -0
- package/src/generators/preset/files/.env.template +2 -0
- package/src/generators/preset/files/.npmrc.template +1 -0
- package/src/generators/preset/files/README.md.template +174 -0
- package/src/generators/preset/files/nx.json +66 -0
- package/src/generators/preset/files/package.json +26 -0
- package/src/generators/preset/files/tsconfig.base.json +27 -0
- package/src/generators/preset/files/tsconfig.base.json.template +27 -0
- package/src/generators/preset/files/tsconfig.json +9 -0
- package/src/generators/preset/generator.d.ts +4 -0
- package/src/generators/preset/generator.js +127 -0
- package/src/generators/preset/schema.d.ts +6 -0
- package/src/generators/preset/schema.js +16 -0
- package/src/generators/preset/schema.json +50 -0
- package/src/generators/remove-custom-message/generator.d.ts +4 -0
- package/src/generators/remove-custom-message/generator.js +259 -0
- package/src/generators/remove-custom-message/schema.d.ts +6 -0
- package/src/generators/remove-custom-message/schema.js +16 -0
- package/src/generators/remove-custom-message/schema.json +39 -0
- package/src/generators/shared/bot-app-utils.d.ts +25 -0
- package/src/generators/shared/bot-app-utils.js +209 -0
- package/src/generators/webview/files/__name__.spec.tsx.template +20 -0
- package/src/generators/webview/files/__name__.tsx.template +19 -0
- package/src/generators/webview/generator.d.ts +4 -0
- package/src/generators/webview/generator.js +179 -0
- package/src/generators/webview/schema.d.ts +5 -0
- package/src/generators/webview/schema.js +16 -0
- package/src/generators/webview/schema.json +34 -0
- package/src/index.d.ts +7 -0
- package/src/index.js +56 -0
- package/src/lib/api-service.d.ts +110 -0
- package/src/lib/api-service.js +591 -0
- package/src/lib/bot-config.d.ts +30 -0
- package/src/lib/bot-config.js +203 -0
- package/src/lib/cloudflared-tunnel.d.ts +29 -0
- package/src/lib/cloudflared-tunnel.js +95 -0
- package/src/lib/constants.d.ts +13 -0
- package/src/lib/constants.js +60 -0
- package/src/lib/credentials-handler.d.ts +40 -0
- package/src/lib/credentials-handler.js +115 -0
- package/src/lib/index.d.ts +10 -0
- package/src/lib/index.js +47 -0
- package/src/lib/interfaces.d.ts +49 -0
- package/src/lib/interfaces.js +16 -0
- package/src/lib/util/executor-helpers.d.ts +97 -0
- package/src/lib/util/executor-helpers.js +574 -0
- package/src/lib/util/file-system.d.ts +8 -0
- package/src/lib/util/file-system.js +65 -0
- package/src/lib/util/sam-container-cleanup.d.ts +11 -0
- package/src/lib/util/sam-container-cleanup.js +55 -0
- package/src/lib/util/sam-template.d.ts +9 -0
- package/src/lib/util/sam-template.js +71 -0
- package/src/lib/util/system.d.ts +1 -0
- package/src/lib/util/system.js +30 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.d.ts +2 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.js +52 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.md +23 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/commands/update-bot.md +5 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/commands/update-botonic.md +5 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/scripts/update-bot/discover-bots.sh +67 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/scripts/update-bot/find-migration-guides.sh +70 -0
- package/src/migrations/add-botonic-update-bots-skill/schema.json +5 -0
- package/src/migrations/add-lilara-registry/add-lilara-registry.migration.d.ts +2 -0
- package/src/migrations/add-lilara-registry/add-lilara-registry.migration.js +49 -0
- package/src/migrations/add-lilara-registry/schema.json +5 -0
- package/src/migrations/fix-css-code-split/fix-css-code-split.migration.md +45 -0
- package/src/migrations/remove-codeartifact-registry/remove-codeartifact-registry.migration.d.ts +2 -0
- package/src/migrations/remove-codeartifact-registry/remove-codeartifact-registry.migration.js +59 -0
- package/src/migrations/remove-codeartifact-registry/schema.json +5 -0
- package/src/migrations/sync-pending-bot-migrations/schema.json +5 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.d.ts +2 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.js +137 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.md +19 -0
- package/src/migrations/update-cursor-commands-to-stubs/schema.json +5 -0
- package/src/migrations/update-cursor-commands-to-stubs/update-cursor-commands-to-stubs.migration.d.ts +2 -0
- package/src/migrations/update-cursor-commands-to-stubs/update-cursor-commands-to-stubs.migration.js +61 -0
- package/src/migrations/update-pnpm-workspace-scripts/schema.json +4 -0
- package/src/migrations/update-pnpm-workspace-scripts/update-pnpm-workspace-scripts.migration.d.ts +2 -0
- package/src/migrations/update-pnpm-workspace-scripts/update-pnpm-workspace-scripts.migration.js +47 -0
- package/src/migrations/utils/migration-utils.d.ts +109 -0
- package/src/migrations/utils/migration-utils.js +448 -0
- package/src/plugin.d.ts +15 -0
- package/src/plugin.js +246 -0
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
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
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var api_service_exports = {};
|
|
30
|
+
__export(api_service_exports, {
|
|
31
|
+
BotonicAPIService: () => BotonicAPIService
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(api_service_exports);
|
|
34
|
+
var import_axios = __toESM(require("axios"));
|
|
35
|
+
var import_child_process = require("child_process");
|
|
36
|
+
var import_fs = require("fs");
|
|
37
|
+
var import_fs_extra = require("fs-extra");
|
|
38
|
+
var import_path = require("path");
|
|
39
|
+
var import_qs = require("qs");
|
|
40
|
+
var import_constants = require("./constants");
|
|
41
|
+
var import_credentials_handler = require("./credentials-handler");
|
|
42
|
+
var import_file_system = require("./util/file-system");
|
|
43
|
+
const FormData = require("form-data");
|
|
44
|
+
const BOTONIC_CLIENT_ID = process.env["VITE_HUBTYPE_CLIENT_ID"] || "";
|
|
45
|
+
const BOTONIC_URL = process.env["VITE_HUBTYPE_API_URL"] || "";
|
|
46
|
+
const resolveEnvironment = (environmentVariables) => {
|
|
47
|
+
return {
|
|
48
|
+
hubtypeClientId: environmentVariables["VITE_HUBTYPE_CLIENT_ID"],
|
|
49
|
+
hubtypeApiUrl: environmentVariables["VITE_HUBTYPE_API_URL"]
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
class BotonicAPIService {
|
|
53
|
+
constructor(config = {
|
|
54
|
+
isLocalRuntimeDeployment: false,
|
|
55
|
+
projectRoot: void 0,
|
|
56
|
+
environmentVariables: {},
|
|
57
|
+
targetEnvironment: "local"
|
|
58
|
+
}) {
|
|
59
|
+
this.clientId = BOTONIC_CLIENT_ID;
|
|
60
|
+
this.baseUrl = BOTONIC_URL;
|
|
61
|
+
this.loginUrl = BOTONIC_URL + "/o/token/";
|
|
62
|
+
this.bot = null;
|
|
63
|
+
this.localRuntimeBot = null;
|
|
64
|
+
this.headers = new import_axios.AxiosHeaders();
|
|
65
|
+
const { hubtypeClientId, hubtypeApiUrl } = resolveEnvironment(
|
|
66
|
+
config.environmentVariables || {}
|
|
67
|
+
);
|
|
68
|
+
this.clientId = hubtypeClientId;
|
|
69
|
+
this.baseUrl = hubtypeApiUrl;
|
|
70
|
+
this.loginUrl = hubtypeApiUrl + "/o/token/";
|
|
71
|
+
this.globalCredentialsHandler = config.workspaceRoot != null ? new import_credentials_handler.GlobalCredentialsHandler(
|
|
72
|
+
(0, import_path.join)(config.workspaceRoot, import_constants.BOTONIC_HOME_DIRNAME)
|
|
73
|
+
) : new import_credentials_handler.GlobalCredentialsHandler();
|
|
74
|
+
this.botCredentialsHandler = new import_credentials_handler.BotCredentialsHandler(config.projectRoot);
|
|
75
|
+
this.isLocalRuntimeDeployment = config.isLocalRuntimeDeployment;
|
|
76
|
+
this.projectRoot = config.projectRoot;
|
|
77
|
+
this.targetEnvironment = config.targetEnvironment;
|
|
78
|
+
this.loadGlobalCredentials();
|
|
79
|
+
this.loadBotCredentials();
|
|
80
|
+
this.setHeaders(this.oauth?.access_token);
|
|
81
|
+
if (this.isLocalRuntimeDeployment && this.projectRoot) {
|
|
82
|
+
try {
|
|
83
|
+
const appBotPath = (0, import_path.join)(this.projectRoot, import_constants.BOT_CREDENTIALS_FILENAME);
|
|
84
|
+
if ((0, import_fs.existsSync)(appBotPath)) {
|
|
85
|
+
const appCreds = (0, import_file_system.readJSON)(appBotPath);
|
|
86
|
+
if (appCreds?.bot) {
|
|
87
|
+
this.localRuntimeBot = appCreds.bot;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
this.apiClient = import_axios.default.create({
|
|
94
|
+
baseURL: this.baseUrl
|
|
95
|
+
// Remove headers from here - we'll pass them explicitly in each request
|
|
96
|
+
});
|
|
97
|
+
const onFullfilled = (response) => {
|
|
98
|
+
return response;
|
|
99
|
+
};
|
|
100
|
+
const onRejected = async (error) => {
|
|
101
|
+
const originalRequest = error.config;
|
|
102
|
+
const retry = originalRequest?._retry;
|
|
103
|
+
if (error.response?.status === 401 && !retry) {
|
|
104
|
+
console.log("Token expired. Refreshing token...");
|
|
105
|
+
originalRequest._retry = true;
|
|
106
|
+
try {
|
|
107
|
+
await this.refreshToken();
|
|
108
|
+
const nextRequest = {
|
|
109
|
+
...originalRequest,
|
|
110
|
+
headers: {
|
|
111
|
+
...originalRequest.headers,
|
|
112
|
+
...this.headers
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
console.log("Token refreshed, retrying request...");
|
|
116
|
+
return this.apiClient.request(nextRequest);
|
|
117
|
+
} catch (refreshError) {
|
|
118
|
+
console.error("Token refresh failed:", refreshError);
|
|
119
|
+
await this.logout();
|
|
120
|
+
return Promise.reject(
|
|
121
|
+
new Error("Authentication failed. Please login again.")
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return Promise.reject(error);
|
|
126
|
+
};
|
|
127
|
+
this.apiClient.interceptors.response.use(onFullfilled, onRejected);
|
|
128
|
+
}
|
|
129
|
+
saveAllCredentials() {
|
|
130
|
+
this.saveGlobalCredentials();
|
|
131
|
+
if (!this.isLocalRuntimeDeployment) {
|
|
132
|
+
this.saveBotCredentials();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
botInfo() {
|
|
136
|
+
if (this.isLocalRuntimeDeployment) {
|
|
137
|
+
if (!this.localRuntimeBot) {
|
|
138
|
+
throw new Error("Not local runtime bot info available");
|
|
139
|
+
}
|
|
140
|
+
return this.localRuntimeBot;
|
|
141
|
+
} else {
|
|
142
|
+
if (!this.bot) {
|
|
143
|
+
throw new Error("Not bot info available");
|
|
144
|
+
}
|
|
145
|
+
return this.bot;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
getOauth() {
|
|
149
|
+
if (!this.oauth) {
|
|
150
|
+
throw new Error("Not authenticated");
|
|
151
|
+
}
|
|
152
|
+
return this.oauth;
|
|
153
|
+
}
|
|
154
|
+
isAuthenticated() {
|
|
155
|
+
return !!this.oauth?.access_token;
|
|
156
|
+
}
|
|
157
|
+
/** True when in local runtime mode and a bot was loaded (e.g. from app .botonic.json). */
|
|
158
|
+
hasLocalRuntimeBot() {
|
|
159
|
+
return Boolean(this.isLocalRuntimeDeployment && this.localRuntimeBot);
|
|
160
|
+
}
|
|
161
|
+
async ensureAuthenticated() {
|
|
162
|
+
if (!this.isAuthenticated()) {
|
|
163
|
+
throw new Error("Not authenticated. Please login first.");
|
|
164
|
+
}
|
|
165
|
+
const isValid = await this.validateToken();
|
|
166
|
+
if (!isValid) {
|
|
167
|
+
try {
|
|
168
|
+
await this.refreshToken();
|
|
169
|
+
} catch (error) {
|
|
170
|
+
throw new Error("Authentication expired. Please login again.");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
setCurrentBot(bot) {
|
|
175
|
+
this.bot = bot;
|
|
176
|
+
}
|
|
177
|
+
setLocalRuntimeBot(bot) {
|
|
178
|
+
this.localRuntimeBot = bot;
|
|
179
|
+
}
|
|
180
|
+
loadGlobalCredentials() {
|
|
181
|
+
const store = this.normalizeCredentialsStore(
|
|
182
|
+
this.globalCredentialsHandler.load()
|
|
183
|
+
);
|
|
184
|
+
if (!store) return;
|
|
185
|
+
const env = this.targetEnvironment ?? "local";
|
|
186
|
+
const creds = store[env];
|
|
187
|
+
if (creds) {
|
|
188
|
+
this.oauth = creds.oauth;
|
|
189
|
+
this.me = creds.me;
|
|
190
|
+
this.loggedUserName = creds.loggedUserName;
|
|
191
|
+
this.loggedEnvironmentUrl = creds.loggedEnvironmentUrl;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Returns store as env -> credentials. Migrates old single-credential format to { local: creds }.
|
|
196
|
+
*/
|
|
197
|
+
normalizeCredentialsStore(store) {
|
|
198
|
+
if (!store) return void 0;
|
|
199
|
+
const raw = store;
|
|
200
|
+
if (raw.oauth != null && typeof raw.oauth === "object") {
|
|
201
|
+
return { local: raw };
|
|
202
|
+
}
|
|
203
|
+
return store;
|
|
204
|
+
}
|
|
205
|
+
loadBotCredentials() {
|
|
206
|
+
const credentials = this.botCredentialsHandler.load();
|
|
207
|
+
if (credentials?.bot) {
|
|
208
|
+
this.bot = credentials.bot;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
setHeaders(accessToken) {
|
|
212
|
+
if (accessToken) {
|
|
213
|
+
this.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
214
|
+
} else {
|
|
215
|
+
this.headers.delete("Authorization");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
saveGlobalCredentials() {
|
|
219
|
+
const env = this.targetEnvironment ?? "local";
|
|
220
|
+
const loggedUserName = this.me?.email ?? this.loggedUserName;
|
|
221
|
+
const store = this.normalizeCredentialsStore(this.globalCredentialsHandler.load()) ?? {};
|
|
222
|
+
store[env] = {
|
|
223
|
+
oauth: this.oauth,
|
|
224
|
+
me: this.me,
|
|
225
|
+
loggedUserName: loggedUserName ?? void 0,
|
|
226
|
+
loggedEnvironmentUrl: this.baseUrl ? this.baseUrl : void 0
|
|
227
|
+
};
|
|
228
|
+
this.globalCredentialsHandler.dump(store);
|
|
229
|
+
}
|
|
230
|
+
saveBotCredentials() {
|
|
231
|
+
this.botCredentialsHandler.dump({
|
|
232
|
+
bot: this.bot
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
async refreshToken() {
|
|
236
|
+
if (!this.oauth?.refresh_token) {
|
|
237
|
+
throw new Error("No refresh token available");
|
|
238
|
+
}
|
|
239
|
+
const data = (0, import_qs.stringify)({
|
|
240
|
+
callback: "none",
|
|
241
|
+
grant_type: "refresh_token",
|
|
242
|
+
refresh_token: this.oauth.refresh_token,
|
|
243
|
+
client_id: this.clientId
|
|
244
|
+
});
|
|
245
|
+
try {
|
|
246
|
+
const oauthResponse = await import_axios.default.post(this.loginUrl, data, {
|
|
247
|
+
headers: {
|
|
248
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
if (oauthResponse.status !== 200) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
`Token refresh failed with status: ${oauthResponse.status}`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
if (!oauthResponse.data?.access_token) {
|
|
257
|
+
throw new Error("Invalid token refresh response: missing access_token");
|
|
258
|
+
}
|
|
259
|
+
this.oauth = oauthResponse.data;
|
|
260
|
+
const accessToken = this.getOauth().access_token;
|
|
261
|
+
this.setHeaders(accessToken);
|
|
262
|
+
this.saveGlobalCredentials();
|
|
263
|
+
console.log("Token refreshed successfully");
|
|
264
|
+
} catch (error) {
|
|
265
|
+
console.error("Token refresh error:", error.message);
|
|
266
|
+
throw new Error(`Failed to refresh token: ${error.message}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async login(email, password) {
|
|
270
|
+
const data = (0, import_qs.stringify)({
|
|
271
|
+
username: email,
|
|
272
|
+
password,
|
|
273
|
+
grant_type: "password",
|
|
274
|
+
client_id: this.clientId
|
|
275
|
+
});
|
|
276
|
+
const loginResponse = await import_axios.default.post(this.loginUrl, data, {
|
|
277
|
+
headers: {
|
|
278
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
this.oauth = loginResponse.data;
|
|
282
|
+
const accessToken = this.getOauth().access_token;
|
|
283
|
+
this.setHeaders(accessToken);
|
|
284
|
+
try {
|
|
285
|
+
const meRes = await this.getMe();
|
|
286
|
+
this.me = meRes.data;
|
|
287
|
+
} catch {
|
|
288
|
+
}
|
|
289
|
+
this.saveGlobalCredentials();
|
|
290
|
+
}
|
|
291
|
+
async logout() {
|
|
292
|
+
const pathToCredentials = this.globalCredentialsHandler.pathToCredentials;
|
|
293
|
+
if (await (0, import_fs_extra.pathExists)(pathToCredentials)) {
|
|
294
|
+
(0, import_fs.rmSync)(pathToCredentials, { force: true });
|
|
295
|
+
} else {
|
|
296
|
+
console.log("Already logged out...\n");
|
|
297
|
+
}
|
|
298
|
+
this.oauth = void 0;
|
|
299
|
+
this.me = void 0;
|
|
300
|
+
this.loggedUserName = void 0;
|
|
301
|
+
this.loggedEnvironmentUrl = void 0;
|
|
302
|
+
this.bot = null;
|
|
303
|
+
this.localRuntimeBot = null;
|
|
304
|
+
this.headers.delete("Authorization");
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Ensures me is loaded (for display). Call before showing "Working as ...".
|
|
308
|
+
*/
|
|
309
|
+
async ensureMeLoaded() {
|
|
310
|
+
if (this.oauth && !this.me) {
|
|
311
|
+
try {
|
|
312
|
+
const meRes = await this.getMe();
|
|
313
|
+
this.me = meRes.data;
|
|
314
|
+
this.saveGlobalCredentials();
|
|
315
|
+
} catch {
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Display name for the logged-in user (for "Working as X in environment ...").
|
|
321
|
+
*/
|
|
322
|
+
getDisplayName() {
|
|
323
|
+
if (this.me?.email) return this.me.email;
|
|
324
|
+
return this.loggedUserName ?? "Unknown";
|
|
325
|
+
}
|
|
326
|
+
async createWebchatIntegration(botId, integrationName) {
|
|
327
|
+
return this.apiPost({
|
|
328
|
+
apiVersion: "v1",
|
|
329
|
+
path: `provider_accounts/connect_webchat_channel/`,
|
|
330
|
+
body: { botId, name: integrationName, settings: {} }
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
async signup(email, password, orgName, campaign) {
|
|
334
|
+
const signupData = { email, password, org_name: orgName, campaign };
|
|
335
|
+
return this.apiPost({ path: "sign-up/", body: signupData });
|
|
336
|
+
}
|
|
337
|
+
async createBot(botName) {
|
|
338
|
+
const resp = await this.apiPost({
|
|
339
|
+
apiVersion: "v2",
|
|
340
|
+
path: "bots/",
|
|
341
|
+
body: { name: botName }
|
|
342
|
+
});
|
|
343
|
+
if (this.isLocalRuntimeDeployment) {
|
|
344
|
+
this.setLocalRuntimeBot(resp.data);
|
|
345
|
+
} else {
|
|
346
|
+
this.setCurrentBot(resp.data);
|
|
347
|
+
}
|
|
348
|
+
return resp;
|
|
349
|
+
}
|
|
350
|
+
async getBots() {
|
|
351
|
+
return this.apiGet({
|
|
352
|
+
apiVersion: "v2",
|
|
353
|
+
path: "bots/?page_size=100"
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
async deleteBot(botId) {
|
|
357
|
+
return this.apiDelete({
|
|
358
|
+
apiVersion: "v2",
|
|
359
|
+
path: `bots/${botId}/`
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
async getProviders(botId) {
|
|
363
|
+
return this.apiGet({
|
|
364
|
+
path: "provider_accounts/",
|
|
365
|
+
params: {
|
|
366
|
+
bot_id: botId || this.botInfo().id
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
async deployBot(bundlePath, botConfigJson) {
|
|
371
|
+
try {
|
|
372
|
+
await this.getMe();
|
|
373
|
+
} catch (e) {
|
|
374
|
+
console.log(`Error authenticating: ${String(e)}`);
|
|
375
|
+
}
|
|
376
|
+
const form = new FormData();
|
|
377
|
+
const data = (0, import_fs.createReadStream)(bundlePath);
|
|
378
|
+
form.append("bundle", data, "botonic_bundle.zip");
|
|
379
|
+
form.append("bot_config", JSON.stringify(botConfigJson));
|
|
380
|
+
form.append("deployment_strategy", "botonic_v2");
|
|
381
|
+
const headers = await this.getHeaders(form);
|
|
382
|
+
return await this.apiPost({
|
|
383
|
+
apiVersion: "v2",
|
|
384
|
+
path: `bots/${this.botInfo().id}/deploy/`,
|
|
385
|
+
body: form,
|
|
386
|
+
headers: {
|
|
387
|
+
...this.headers,
|
|
388
|
+
...headers
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
async deployStatus(deployId) {
|
|
393
|
+
return this.apiGet({
|
|
394
|
+
apiVersion: "v2",
|
|
395
|
+
path: `bots/${this.botInfo().id}/deploy_status/`,
|
|
396
|
+
params: { deploy_id: deployId }
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
async deployLocalRuntime({
|
|
400
|
+
botConfigJson,
|
|
401
|
+
lambdaFunctionName,
|
|
402
|
+
lambdaEndpoint
|
|
403
|
+
}) {
|
|
404
|
+
try {
|
|
405
|
+
await this.getMe();
|
|
406
|
+
} catch (e) {
|
|
407
|
+
console.log(`Error authenticating: ${String(e)}`);
|
|
408
|
+
}
|
|
409
|
+
const form = new FormData();
|
|
410
|
+
form.append("bot_config", JSON.stringify(botConfigJson));
|
|
411
|
+
form.append("lambda_function_name", lambdaFunctionName);
|
|
412
|
+
form.append("lambda_endpoint", lambdaEndpoint);
|
|
413
|
+
const headers = await this.getHeaders(form);
|
|
414
|
+
return await this.apiPost({
|
|
415
|
+
apiVersion: "v2",
|
|
416
|
+
path: `bots/${this.botInfo().id}/deploy_local_runtime/`,
|
|
417
|
+
body: form,
|
|
418
|
+
headers: {
|
|
419
|
+
...this.headers,
|
|
420
|
+
...headers
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
async build({
|
|
425
|
+
projectRoot,
|
|
426
|
+
projectName
|
|
427
|
+
}) {
|
|
428
|
+
try {
|
|
429
|
+
console.log("Building...");
|
|
430
|
+
(0, import_fs.rm)((0, import_path.join)(projectRoot, "dist"), { recursive: true, force: true }, (err) => {
|
|
431
|
+
if (err) {
|
|
432
|
+
console.error("Error removing dist directory", err);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
const commands = [
|
|
436
|
+
[
|
|
437
|
+
"run",
|
|
438
|
+
`${projectName}:build-webchat-app`,
|
|
439
|
+
`--configuration=${this.targetEnvironment}`
|
|
440
|
+
],
|
|
441
|
+
[
|
|
442
|
+
"run",
|
|
443
|
+
`${projectName}:build-webviews-app`,
|
|
444
|
+
`--configuration=${this.targetEnvironment}`
|
|
445
|
+
],
|
|
446
|
+
[
|
|
447
|
+
"run",
|
|
448
|
+
`${projectName}:build-node-app`,
|
|
449
|
+
`--configuration=${this.targetEnvironment}`
|
|
450
|
+
]
|
|
451
|
+
];
|
|
452
|
+
const processes = commands.map(
|
|
453
|
+
(cmd) => new Promise((resolve, reject) => {
|
|
454
|
+
const childProcess = (0, import_child_process.spawn)("nx", cmd, {
|
|
455
|
+
cwd: process.cwd(),
|
|
456
|
+
stdio: "inherit"
|
|
457
|
+
});
|
|
458
|
+
childProcess.on("close", (code) => {
|
|
459
|
+
resolve(code === 0);
|
|
460
|
+
});
|
|
461
|
+
childProcess.on("error", (error) => {
|
|
462
|
+
reject(error);
|
|
463
|
+
});
|
|
464
|
+
})
|
|
465
|
+
);
|
|
466
|
+
const results = await Promise.all(processes);
|
|
467
|
+
await this.prepareLambda(projectRoot);
|
|
468
|
+
return results.every((result) => result === true);
|
|
469
|
+
} catch (error) {
|
|
470
|
+
console.log("\n\nBuild error:\n", error);
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
async prepareLambda(projectRoot) {
|
|
475
|
+
try {
|
|
476
|
+
(0, import_child_process.execSync)(
|
|
477
|
+
`mkdir -p ${projectRoot}/dist/lambda && cp -r ${projectRoot}/src/server/lambda/* ${projectRoot}/dist/lambda/ && cd ${projectRoot}/dist/lambda && npm install`
|
|
478
|
+
);
|
|
479
|
+
return true;
|
|
480
|
+
} catch (error) {
|
|
481
|
+
console.log("\n\nPrepare Lambda error:\n", error);
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
async apiPost({
|
|
486
|
+
apiVersion = "v1",
|
|
487
|
+
path,
|
|
488
|
+
body,
|
|
489
|
+
headers,
|
|
490
|
+
params
|
|
491
|
+
}) {
|
|
492
|
+
if (this.oauth?.access_token && this.isTokenExpired()) {
|
|
493
|
+
try {
|
|
494
|
+
await this.refreshToken();
|
|
495
|
+
} catch (error) {
|
|
496
|
+
console.warn(
|
|
497
|
+
"Proactive token refresh failed, proceeding with request:",
|
|
498
|
+
error
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return this.apiClient.post(
|
|
503
|
+
`${this.baseUrl}/${apiVersion}/${path}`,
|
|
504
|
+
body,
|
|
505
|
+
{
|
|
506
|
+
headers: headers || this.headers,
|
|
507
|
+
params
|
|
508
|
+
}
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
async apiGet({
|
|
512
|
+
apiVersion = "v1",
|
|
513
|
+
path,
|
|
514
|
+
headers,
|
|
515
|
+
params
|
|
516
|
+
}) {
|
|
517
|
+
if (this.oauth?.access_token && this.isTokenExpired()) {
|
|
518
|
+
try {
|
|
519
|
+
await this.refreshToken();
|
|
520
|
+
} catch (error) {
|
|
521
|
+
console.warn(
|
|
522
|
+
"Proactive token refresh failed, proceeding with request:",
|
|
523
|
+
error
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
return this.apiClient.get(`${this.baseUrl}/${apiVersion}/${path}`, {
|
|
528
|
+
headers: headers || this.headers,
|
|
529
|
+
params
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
async apiDelete({
|
|
533
|
+
apiVersion = "v1",
|
|
534
|
+
path,
|
|
535
|
+
headers,
|
|
536
|
+
params
|
|
537
|
+
}) {
|
|
538
|
+
if (this.oauth?.access_token && this.isTokenExpired()) {
|
|
539
|
+
try {
|
|
540
|
+
await this.refreshToken();
|
|
541
|
+
} catch (error) {
|
|
542
|
+
console.warn(
|
|
543
|
+
"Proactive token refresh failed, proceeding with request:",
|
|
544
|
+
error
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return this.apiClient.delete(`${this.baseUrl}/${apiVersion}/${path}`, {
|
|
549
|
+
headers: headers || this.headers,
|
|
550
|
+
params
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
async getMe() {
|
|
554
|
+
return this.apiClient.get("/v3/users/me/");
|
|
555
|
+
}
|
|
556
|
+
async validateToken() {
|
|
557
|
+
try {
|
|
558
|
+
await this.getMe();
|
|
559
|
+
return true;
|
|
560
|
+
} catch (error) {
|
|
561
|
+
if (error.response?.status === 401) {
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
throw error;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
isTokenExpired() {
|
|
568
|
+
if (!this.oauth?.access_token) {
|
|
569
|
+
return true;
|
|
570
|
+
}
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
async getHeaders(form) {
|
|
574
|
+
return new Promise((resolve, reject) => {
|
|
575
|
+
form.getLength((err, length) => {
|
|
576
|
+
if (err) {
|
|
577
|
+
reject(err);
|
|
578
|
+
}
|
|
579
|
+
const headers = Object.assign(
|
|
580
|
+
{ "Content-Length": length },
|
|
581
|
+
form.getHeaders()
|
|
582
|
+
);
|
|
583
|
+
resolve(headers);
|
|
584
|
+
});
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
589
|
+
0 && (module.exports = {
|
|
590
|
+
BotonicAPIService
|
|
591
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface BotConfigJSON {
|
|
2
|
+
build_info: {
|
|
3
|
+
node_version: string;
|
|
4
|
+
npm_version: string;
|
|
5
|
+
botonic_cli_version: string;
|
|
6
|
+
};
|
|
7
|
+
packages: Record<string, {
|
|
8
|
+
version: string;
|
|
9
|
+
}>;
|
|
10
|
+
tools: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
}>;
|
|
14
|
+
payloads: string[];
|
|
15
|
+
webviews: Array<{
|
|
16
|
+
name: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
export declare class BotConfig {
|
|
20
|
+
static get(projectRoot: string): Promise<BotConfigJSON>;
|
|
21
|
+
private static displayBotConfig;
|
|
22
|
+
private static loadBotConfig;
|
|
23
|
+
private static getTools;
|
|
24
|
+
private static loadModuleConstant;
|
|
25
|
+
private static getPayloads;
|
|
26
|
+
private static getWebviews;
|
|
27
|
+
private static getBuildInfo;
|
|
28
|
+
private static getBotonicPackages;
|
|
29
|
+
private static getOutputByCommand;
|
|
30
|
+
}
|