@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.
Files changed (206) hide show
  1. package/CHANGELOG.md +420 -0
  2. package/README.md +279 -0
  3. package/executors.json +55 -0
  4. package/generators.json +61 -0
  5. package/migrations.json +40 -0
  6. package/package.json +54 -0
  7. package/src/cursor-commands/update-bot.md +114 -0
  8. package/src/cursor-commands/update-botonic.md +63 -0
  9. package/src/executors/build-node-app/executor.d.ts +5 -0
  10. package/src/executors/build-node-app/executor.js +65 -0
  11. package/src/executors/build-node-app/schema.d.js +16 -0
  12. package/src/executors/build-node-app/schema.json +25 -0
  13. package/src/executors/delete-bot/executor.d.ts +5 -0
  14. package/src/executors/delete-bot/executor.js +112 -0
  15. package/src/executors/delete-bot/schema.d.js +16 -0
  16. package/src/executors/delete-bot/schema.json +35 -0
  17. package/src/executors/deploy-local-runtime/executor.d.ts +5 -0
  18. package/src/executors/deploy-local-runtime/executor.js +144 -0
  19. package/src/executors/deploy-local-runtime/schema.d.js +16 -0
  20. package/src/executors/deploy-local-runtime/schema.json +34 -0
  21. package/src/executors/deploy-netlify-snapshot/executor.d.ts +8 -0
  22. package/src/executors/deploy-netlify-snapshot/executor.js +79 -0
  23. package/src/executors/deploy-netlify-snapshot/schema.d.js +16 -0
  24. package/src/executors/deploy-netlify-snapshot/schema.json +31 -0
  25. package/src/executors/deploy-to-hubtype/executor.d.ts +5 -0
  26. package/src/executors/deploy-to-hubtype/executor.js +308 -0
  27. package/src/executors/deploy-to-hubtype/schema.d.js +16 -0
  28. package/src/executors/deploy-to-hubtype/schema.json +31 -0
  29. package/src/executors/e2e-webchat/botonic-package-publish.spec.ts +84 -0
  30. package/src/executors/e2e-webchat/executor.d.ts +5 -0
  31. package/src/executors/e2e-webchat/executor.js +134 -0
  32. package/src/executors/e2e-webchat/schema.d.js +16 -0
  33. package/src/executors/e2e-webchat/schema.json +35 -0
  34. package/src/executors/integrate-provider/executor.d.ts +5 -0
  35. package/src/executors/integrate-provider/executor.js +155 -0
  36. package/src/executors/integrate-provider/schema.d.js +16 -0
  37. package/src/executors/integrate-provider/schema.json +30 -0
  38. package/src/executors/login-to-hubtype/executor.d.ts +5 -0
  39. package/src/executors/login-to-hubtype/executor.js +79 -0
  40. package/src/executors/login-to-hubtype/schema.d.js +16 -0
  41. package/src/executors/login-to-hubtype/schema.json +25 -0
  42. package/src/executors/logout-from-hubtype/executor.d.ts +3 -0
  43. package/src/executors/logout-from-hubtype/executor.js +54 -0
  44. package/src/executors/logout-from-hubtype/schema.d.js +16 -0
  45. package/src/executors/logout-from-hubtype/schema.json +9 -0
  46. package/src/executors/run-lambda/executor.d.ts +5 -0
  47. package/src/executors/run-lambda/executor.js +65 -0
  48. package/src/executors/run-lambda/schema.d.js +16 -0
  49. package/src/executors/run-lambda/schema.json +20 -0
  50. package/src/executors/serve-bot/executor.d.ts +5 -0
  51. package/src/executors/serve-bot/executor.js +330 -0
  52. package/src/executors/serve-bot/schema.d.js +16 -0
  53. package/src/executors/serve-bot/schema.json +40 -0
  54. package/src/generators/action/files/__name__.spec.ts.template +15 -0
  55. package/src/generators/action/files/__name__.ts.template +15 -0
  56. package/src/generators/action/generator.d.ts +4 -0
  57. package/src/generators/action/generator.js +112 -0
  58. package/src/generators/action/schema.d.ts +7 -0
  59. package/src/generators/action/schema.js +16 -0
  60. package/src/generators/action/schema.json +43 -0
  61. package/src/generators/bot-app/files/.eslintrc.json.template +18 -0
  62. package/src/generators/bot-app/files/README.md.template +148 -0
  63. package/src/generators/bot-app/files/src/client/custom-messages/index.ts.template +2 -0
  64. package/src/generators/bot-app/files/src/client/webchat/index.html.template +35 -0
  65. package/src/generators/bot-app/files/src/client/webchat/index.tsx.template +107 -0
  66. package/src/generators/bot-app/files/src/client/webchat/styles.css.template +17 -0
  67. package/src/generators/bot-app/files/src/client/webchat/webchat-tokens-overrides.css.template +2 -0
  68. package/src/generators/bot-app/files/src/client/webviews/app.tsx.template +8 -0
  69. package/src/generators/bot-app/files/src/client/webviews/index.html.template +32 -0
  70. package/src/generators/bot-app/files/src/client/webviews/index.tsx.template +18 -0
  71. package/src/generators/bot-app/files/src/server/bot/actions/index.ts.template +2 -0
  72. package/src/generators/bot-app/files/src/server/bot/actions/not-found.ts.template +13 -0
  73. package/src/generators/bot-app/files/src/server/bot/actions/welcome.ts.template +13 -0
  74. package/src/generators/bot-app/files/src/server/bot/index.ts.template +43 -0
  75. package/src/generators/bot-app/files/src/server/bot/plugins/ai-agents/index.ts.template +30 -0
  76. package/src/generators/bot-app/files/src/server/bot/plugins/flow-builder/index.ts.template +28 -0
  77. package/src/generators/bot-app/files/src/server/bot/plugins/index.ts.template +11 -0
  78. package/src/generators/bot-app/files/src/server/bot/routes.ts.template +23 -0
  79. package/src/generators/bot-app/files/src/server/bot/tools/index.ts.template +5 -0
  80. package/src/generators/bot-app/files/src/server/bot/tracking.ts.template +35 -0
  81. package/src/generators/bot-app/files/src/server/bot/types.ts.template +4 -0
  82. package/src/generators/bot-app/files/src/server/bot/utils.ts.template +9 -0
  83. package/src/generators/bot-app/files/src/server/lambda/handler.js.template +24 -0
  84. package/src/generators/bot-app/files/src/server/lambda/package.json +20 -0
  85. package/src/generators/bot-app/files/src/server/lambda/template.yaml.template +20 -0
  86. package/src/generators/bot-app/files/src/shared/constants.ts.template +12 -0
  87. package/src/generators/bot-app/files/vite/base-client.config.ts.template +14 -0
  88. package/src/generators/bot-app/files/vite/base.config.ts.template +20 -0
  89. package/src/generators/bot-app/files/vite/build.config.ts.template +65 -0
  90. package/src/generators/bot-app/files/vite/node.config.ts.template +41 -0
  91. package/src/generators/bot-app/files/vite/plugins/move-html.plugin.ts.template +36 -0
  92. package/src/generators/bot-app/files/vite/webchat.config.ts.template +58 -0
  93. package/src/generators/bot-app/files/vite/webviews.config.ts.template +57 -0
  94. package/src/generators/bot-app/files/vite.config.ts.template +36 -0
  95. package/src/generators/bot-app/generator.d.ts +4 -0
  96. package/src/generators/bot-app/generator.js +294 -0
  97. package/src/generators/bot-app/schema.d.ts +6 -0
  98. package/src/generators/bot-app/schema.js +16 -0
  99. package/src/generators/bot-app/schema.json +36 -0
  100. package/src/generators/bot-app-migrations/migrate-fix-css-code-split/generator.d.ts +5 -0
  101. package/src/generators/bot-app-migrations/migrate-fix-css-code-split/generator.js +92 -0
  102. package/src/generators/bot-app-migrations/migrate-fix-css-code-split/schema.json +15 -0
  103. package/src/generators/bot-app-migrations/migrate-pnpm-compat/generator.d.ts +5 -0
  104. package/src/generators/bot-app-migrations/migrate-pnpm-compat/generator.js +97 -0
  105. package/src/generators/bot-app-migrations/migrate-pnpm-compat/schema.json +15 -0
  106. package/src/generators/bot-app-migrations/migrate-webchat-trigger/generator.d.ts +5 -0
  107. package/src/generators/bot-app-migrations/migrate-webchat-trigger/generator.js +165 -0
  108. package/src/generators/bot-app-migrations/migrate-webchat-trigger/schema.json +15 -0
  109. package/src/generators/custom-message/files/__name__-output.ts.template +21 -0
  110. package/src/generators/custom-message/files/__name__.spec.tsx.template +27 -0
  111. package/src/generators/custom-message/files/__name__.tsx.template +18 -0
  112. package/src/generators/custom-message/generator.d.ts +4 -0
  113. package/src/generators/custom-message/generator.js +235 -0
  114. package/src/generators/custom-message/schema.d.ts +7 -0
  115. package/src/generators/custom-message/schema.js +16 -0
  116. package/src/generators/custom-message/schema.json +44 -0
  117. package/src/generators/preset/files/.cursor/commands/update-bot.md +5 -0
  118. package/src/generators/preset/files/.cursor/commands/update-botonic.md +5 -0
  119. package/src/generators/preset/files/.cursor/scripts/update-bot/discover-bots.sh +67 -0
  120. package/src/generators/preset/files/.cursor/scripts/update-bot/find-migration-guides.sh +70 -0
  121. package/src/generators/preset/files/.cursor/skills/botonic-action/SKILL.md +167 -0
  122. package/src/generators/preset/files/.cursor/skills/botonic-custom-message/SKILL.md +231 -0
  123. package/src/generators/preset/files/.cursor/skills/botonic-webview/SKILL.md +179 -0
  124. package/src/generators/preset/files/.env.prod.template +2 -0
  125. package/src/generators/preset/files/.env.template +2 -0
  126. package/src/generators/preset/files/.npmrc.template +1 -0
  127. package/src/generators/preset/files/README.md.template +174 -0
  128. package/src/generators/preset/files/nx.json +66 -0
  129. package/src/generators/preset/files/package.json +26 -0
  130. package/src/generators/preset/files/tsconfig.base.json +27 -0
  131. package/src/generators/preset/files/tsconfig.base.json.template +27 -0
  132. package/src/generators/preset/files/tsconfig.json +9 -0
  133. package/src/generators/preset/generator.d.ts +4 -0
  134. package/src/generators/preset/generator.js +127 -0
  135. package/src/generators/preset/schema.d.ts +6 -0
  136. package/src/generators/preset/schema.js +16 -0
  137. package/src/generators/preset/schema.json +50 -0
  138. package/src/generators/remove-custom-message/generator.d.ts +4 -0
  139. package/src/generators/remove-custom-message/generator.js +259 -0
  140. package/src/generators/remove-custom-message/schema.d.ts +6 -0
  141. package/src/generators/remove-custom-message/schema.js +16 -0
  142. package/src/generators/remove-custom-message/schema.json +39 -0
  143. package/src/generators/shared/bot-app-utils.d.ts +25 -0
  144. package/src/generators/shared/bot-app-utils.js +209 -0
  145. package/src/generators/webview/files/__name__.spec.tsx.template +20 -0
  146. package/src/generators/webview/files/__name__.tsx.template +19 -0
  147. package/src/generators/webview/generator.d.ts +4 -0
  148. package/src/generators/webview/generator.js +179 -0
  149. package/src/generators/webview/schema.d.ts +5 -0
  150. package/src/generators/webview/schema.js +16 -0
  151. package/src/generators/webview/schema.json +34 -0
  152. package/src/index.d.ts +7 -0
  153. package/src/index.js +56 -0
  154. package/src/lib/api-service.d.ts +110 -0
  155. package/src/lib/api-service.js +591 -0
  156. package/src/lib/bot-config.d.ts +30 -0
  157. package/src/lib/bot-config.js +203 -0
  158. package/src/lib/cloudflared-tunnel.d.ts +29 -0
  159. package/src/lib/cloudflared-tunnel.js +95 -0
  160. package/src/lib/constants.d.ts +13 -0
  161. package/src/lib/constants.js +60 -0
  162. package/src/lib/credentials-handler.d.ts +40 -0
  163. package/src/lib/credentials-handler.js +115 -0
  164. package/src/lib/index.d.ts +10 -0
  165. package/src/lib/index.js +47 -0
  166. package/src/lib/interfaces.d.ts +49 -0
  167. package/src/lib/interfaces.js +16 -0
  168. package/src/lib/util/executor-helpers.d.ts +97 -0
  169. package/src/lib/util/executor-helpers.js +574 -0
  170. package/src/lib/util/file-system.d.ts +8 -0
  171. package/src/lib/util/file-system.js +65 -0
  172. package/src/lib/util/sam-container-cleanup.d.ts +11 -0
  173. package/src/lib/util/sam-container-cleanup.js +55 -0
  174. package/src/lib/util/sam-template.d.ts +9 -0
  175. package/src/lib/util/sam-template.js +71 -0
  176. package/src/lib/util/system.d.ts +1 -0
  177. package/src/lib/util/system.js +30 -0
  178. package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.d.ts +2 -0
  179. package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.js +52 -0
  180. package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.md +23 -0
  181. package/src/migrations/add-botonic-update-bots-skill/files/.cursor/commands/update-bot.md +5 -0
  182. package/src/migrations/add-botonic-update-bots-skill/files/.cursor/commands/update-botonic.md +5 -0
  183. package/src/migrations/add-botonic-update-bots-skill/files/.cursor/scripts/update-bot/discover-bots.sh +67 -0
  184. package/src/migrations/add-botonic-update-bots-skill/files/.cursor/scripts/update-bot/find-migration-guides.sh +70 -0
  185. package/src/migrations/add-botonic-update-bots-skill/schema.json +5 -0
  186. package/src/migrations/add-lilara-registry/add-lilara-registry.migration.d.ts +2 -0
  187. package/src/migrations/add-lilara-registry/add-lilara-registry.migration.js +49 -0
  188. package/src/migrations/add-lilara-registry/schema.json +5 -0
  189. package/src/migrations/fix-css-code-split/fix-css-code-split.migration.md +45 -0
  190. package/src/migrations/remove-codeartifact-registry/remove-codeartifact-registry.migration.d.ts +2 -0
  191. package/src/migrations/remove-codeartifact-registry/remove-codeartifact-registry.migration.js +59 -0
  192. package/src/migrations/remove-codeartifact-registry/schema.json +5 -0
  193. package/src/migrations/sync-pending-bot-migrations/schema.json +5 -0
  194. package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.d.ts +2 -0
  195. package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.js +137 -0
  196. package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.md +19 -0
  197. package/src/migrations/update-cursor-commands-to-stubs/schema.json +5 -0
  198. package/src/migrations/update-cursor-commands-to-stubs/update-cursor-commands-to-stubs.migration.d.ts +2 -0
  199. package/src/migrations/update-cursor-commands-to-stubs/update-cursor-commands-to-stubs.migration.js +61 -0
  200. package/src/migrations/update-pnpm-workspace-scripts/schema.json +4 -0
  201. package/src/migrations/update-pnpm-workspace-scripts/update-pnpm-workspace-scripts.migration.d.ts +2 -0
  202. package/src/migrations/update-pnpm-workspace-scripts/update-pnpm-workspace-scripts.migration.js +47 -0
  203. package/src/migrations/utils/migration-utils.d.ts +109 -0
  204. package/src/migrations/utils/migration-utils.js +448 -0
  205. package/src/plugin.d.ts +15 -0
  206. 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
+ }