@botonic/nx-plugin 2.29.0 → 2.31.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 +32 -0
- package/executors.json +0 -5
- package/package.json +3 -2
- package/src/executors/delete-bot/executor.js +0 -2
- package/src/executors/deploy-to-hubtype/executor.js +24 -160
- package/src/executors/e2e-webchat/botonic-package-publish.spec.ts +7 -11
- package/src/executors/integrate-provider/executor.js +0 -2
- package/src/executors/login-to-hubtype/executor.js +0 -2
- package/src/executors/logout-from-hubtype/executor.js +2 -2
- package/src/executors/serve-bot/executor.js +142 -24
- package/src/executors/serve-bot/schema.json +13 -5
- package/src/generators/bot-app/files/src/client/webchat/index.tsx.template +2 -0
- package/src/generators/bot-app/files/src/client/webchat/webchat.tsx.template +111 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/flow-builder/index.ts.template +13 -4
- package/src/generators/bot-app/files/src/server/bot/plugins/index.ts.template +0 -3
- package/src/generators/bot-app/files/src/server/lambda/handler.js.template +1 -1
- package/src/generators/bot-app/files/src/server/lambda/package.json +3 -3
- package/src/generators/bot-app/files/vite/node.config.ts.template +2 -4
- package/src/generators/bot-app/files/vite/webchat.config.ts.template +20 -1
- package/src/generators/bot-app/generator.js +6 -5
- package/src/generators/bot-app/lilara-version.json +1 -1
- package/src/lib/api-service.d.ts +19 -20
- package/src/lib/api-service.js +150 -82
- package/src/lib/bot-config.d.ts +10 -7
- package/src/lib/bot-config.js +5 -1
- package/src/lib/constants.d.ts +2 -3
- package/src/lib/constants.js +6 -9
- package/src/lib/credentials-handler.d.ts +9 -18
- package/src/lib/credentials-handler.js +42 -24
- package/src/lib/interfaces.d.ts +10 -13
- package/src/lib/util/executor-helpers.d.ts +58 -18
- package/src/lib/util/executor-helpers.js +501 -102
- package/src/plugin.js +6 -15
- package/src/executors/deploy-local-runtime/executor.d.ts +0 -5
- package/src/executors/deploy-local-runtime/executor.js +0 -144
- package/src/executors/deploy-local-runtime/schema.d.js +0 -16
- package/src/executors/deploy-local-runtime/schema.json +0 -34
- package/src/generators/bot-app/files/src/server/bot/tracking.ts.template +0 -35
- package/src/generators/preset/files/package.json +0 -26
package/src/lib/api-service.js
CHANGED
|
@@ -39,7 +39,6 @@ var import_path = require("path");
|
|
|
39
39
|
var import_qs = require("qs");
|
|
40
40
|
var import_constants = require("./constants");
|
|
41
41
|
var import_credentials_handler = require("./credentials-handler");
|
|
42
|
-
var import_file_system = require("./util/file-system");
|
|
43
42
|
const FormData = require("form-data");
|
|
44
43
|
const BOTONIC_CLIENT_ID = process.env["VITE_HUBTYPE_CLIENT_ID"] || "";
|
|
45
44
|
const BOTONIC_URL = process.env["VITE_HUBTYPE_API_URL"] || "";
|
|
@@ -51,7 +50,6 @@ const resolveEnvironment = (environmentVariables) => {
|
|
|
51
50
|
};
|
|
52
51
|
class BotonicAPIService {
|
|
53
52
|
constructor(config = {
|
|
54
|
-
isLocalRuntimeDeployment: false,
|
|
55
53
|
projectRoot: void 0,
|
|
56
54
|
environmentVariables: {},
|
|
57
55
|
targetEnvironment: "local"
|
|
@@ -60,7 +58,6 @@ class BotonicAPIService {
|
|
|
60
58
|
this.baseUrl = BOTONIC_URL;
|
|
61
59
|
this.loginUrl = BOTONIC_URL + "/o/token/";
|
|
62
60
|
this.bot = null;
|
|
63
|
-
this.localRuntimeBot = null;
|
|
64
61
|
this.headers = new import_axios.AxiosHeaders();
|
|
65
62
|
const { hubtypeClientId, hubtypeApiUrl } = resolveEnvironment(
|
|
66
63
|
config.environmentVariables || {}
|
|
@@ -71,25 +68,12 @@ class BotonicAPIService {
|
|
|
71
68
|
this.globalCredentialsHandler = config.workspaceRoot != null ? new import_credentials_handler.GlobalCredentialsHandler(
|
|
72
69
|
(0, import_path.join)(config.workspaceRoot, import_constants.BOTONIC_HOME_DIRNAME)
|
|
73
70
|
) : new import_credentials_handler.GlobalCredentialsHandler();
|
|
74
|
-
this.
|
|
75
|
-
this.isLocalRuntimeDeployment = config.isLocalRuntimeDeployment;
|
|
71
|
+
this.botsRegistryHandler = new import_credentials_handler.BotsRegistryHandler();
|
|
76
72
|
this.projectRoot = config.projectRoot;
|
|
77
73
|
this.targetEnvironment = config.targetEnvironment;
|
|
78
74
|
this.loadGlobalCredentials();
|
|
79
|
-
this.
|
|
75
|
+
this.loadBotFromRegistry();
|
|
80
76
|
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
77
|
this.apiClient = import_axios.default.create({
|
|
94
78
|
baseURL: this.baseUrl
|
|
95
79
|
// Remove headers from here - we'll pass them explicitly in each request
|
|
@@ -128,22 +112,13 @@ class BotonicAPIService {
|
|
|
128
112
|
}
|
|
129
113
|
saveAllCredentials() {
|
|
130
114
|
this.saveGlobalCredentials();
|
|
131
|
-
|
|
132
|
-
this.saveBotCredentials();
|
|
133
|
-
}
|
|
115
|
+
this.saveToBotsRegistry();
|
|
134
116
|
}
|
|
135
117
|
botInfo() {
|
|
136
|
-
if (this.
|
|
137
|
-
|
|
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;
|
|
118
|
+
if (!this.bot) {
|
|
119
|
+
throw new Error("No bot selected");
|
|
146
120
|
}
|
|
121
|
+
return this.bot;
|
|
147
122
|
}
|
|
148
123
|
getOauth() {
|
|
149
124
|
if (!this.oauth) {
|
|
@@ -154,10 +129,6 @@ class BotonicAPIService {
|
|
|
154
129
|
isAuthenticated() {
|
|
155
130
|
return !!this.oauth?.access_token;
|
|
156
131
|
}
|
|
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
132
|
async ensureAuthenticated() {
|
|
162
133
|
if (!this.isAuthenticated()) {
|
|
163
134
|
throw new Error("Not authenticated. Please login first.");
|
|
@@ -173,9 +144,16 @@ class BotonicAPIService {
|
|
|
173
144
|
}
|
|
174
145
|
setCurrentBot(bot) {
|
|
175
146
|
this.bot = bot;
|
|
147
|
+
this.saveToBotsRegistry();
|
|
176
148
|
}
|
|
177
|
-
|
|
178
|
-
this.
|
|
149
|
+
async selectBot(bot) {
|
|
150
|
+
this.bot = bot;
|
|
151
|
+
try {
|
|
152
|
+
const providers = await this.fetchProviders(bot.id);
|
|
153
|
+
this.bot = { ...bot, providers };
|
|
154
|
+
} catch {
|
|
155
|
+
}
|
|
156
|
+
this.saveToBotsRegistry();
|
|
179
157
|
}
|
|
180
158
|
loadGlobalCredentials() {
|
|
181
159
|
const store = this.normalizeCredentialsStore(
|
|
@@ -202,10 +180,53 @@ class BotonicAPIService {
|
|
|
202
180
|
}
|
|
203
181
|
return store;
|
|
204
182
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
183
|
+
loadBotFromRegistry() {
|
|
184
|
+
try {
|
|
185
|
+
const entry = this.botsRegistryHandler.findLatestForEnv(
|
|
186
|
+
this.targetEnvironment ?? "local"
|
|
187
|
+
);
|
|
188
|
+
if (!entry) return;
|
|
189
|
+
this.bot = entry;
|
|
190
|
+
} catch {
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
saveToBotsRegistry() {
|
|
194
|
+
try {
|
|
195
|
+
if (!this.bot) return;
|
|
196
|
+
this.botsRegistryHandler.upsert(
|
|
197
|
+
this.targetEnvironment ?? "local",
|
|
198
|
+
this.bot
|
|
199
|
+
);
|
|
200
|
+
} catch (e) {
|
|
201
|
+
console.warn("bots.json could not be saved:", e);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
saveProviders(providers) {
|
|
205
|
+
try {
|
|
206
|
+
if (!this.bot) return;
|
|
207
|
+
this.bot = { ...this.bot, providers };
|
|
208
|
+
this.botsRegistryHandler.upsert(
|
|
209
|
+
this.targetEnvironment ?? "local",
|
|
210
|
+
this.bot
|
|
211
|
+
);
|
|
212
|
+
} catch (e) {
|
|
213
|
+
console.warn("bots.json providers could not be saved:", e);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async fetchProviders(botId) {
|
|
217
|
+
const resp = await this.getProviders(botId);
|
|
218
|
+
return (resp.data.results ?? []).map((p) => ({
|
|
219
|
+
id: p.id,
|
|
220
|
+
provider: p.provider ?? "",
|
|
221
|
+
is_test: p.is_test ?? false,
|
|
222
|
+
is_active: p.is_active ?? false
|
|
223
|
+
}));
|
|
224
|
+
}
|
|
225
|
+
saveBotEntry(bot) {
|
|
226
|
+
try {
|
|
227
|
+
this.botsRegistryHandler.upsert(this.targetEnvironment ?? "local", bot);
|
|
228
|
+
} catch (e) {
|
|
229
|
+
console.warn("bots.json could not be saved:", e);
|
|
209
230
|
}
|
|
210
231
|
}
|
|
211
232
|
setHeaders(accessToken) {
|
|
@@ -227,11 +248,6 @@ class BotonicAPIService {
|
|
|
227
248
|
};
|
|
228
249
|
this.globalCredentialsHandler.dump(store);
|
|
229
250
|
}
|
|
230
|
-
saveBotCredentials() {
|
|
231
|
-
this.botCredentialsHandler.dump({
|
|
232
|
-
bot: this.bot
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
251
|
async refreshToken() {
|
|
236
252
|
if (!this.oauth?.refresh_token) {
|
|
237
253
|
throw new Error("No refresh token available");
|
|
@@ -257,6 +273,7 @@ class BotonicAPIService {
|
|
|
257
273
|
throw new Error("Invalid token refresh response: missing access_token");
|
|
258
274
|
}
|
|
259
275
|
this.oauth = oauthResponse.data;
|
|
276
|
+
this._tokenExpiresAt = Date.now() + oauthResponse.data.expires_in * 1e3;
|
|
260
277
|
const accessToken = this.getOauth().access_token;
|
|
261
278
|
this.setHeaders(accessToken);
|
|
262
279
|
this.saveGlobalCredentials();
|
|
@@ -279,6 +296,7 @@ class BotonicAPIService {
|
|
|
279
296
|
}
|
|
280
297
|
});
|
|
281
298
|
this.oauth = loginResponse.data;
|
|
299
|
+
this._tokenExpiresAt = Date.now() + loginResponse.data.expires_in * 1e3;
|
|
282
300
|
const accessToken = this.getOauth().access_token;
|
|
283
301
|
this.setHeaders(accessToken);
|
|
284
302
|
try {
|
|
@@ -296,11 +314,11 @@ class BotonicAPIService {
|
|
|
296
314
|
console.log("Already logged out...\n");
|
|
297
315
|
}
|
|
298
316
|
this.oauth = void 0;
|
|
317
|
+
this._tokenExpiresAt = void 0;
|
|
299
318
|
this.me = void 0;
|
|
300
319
|
this.loggedUserName = void 0;
|
|
301
320
|
this.loggedEnvironmentUrl = void 0;
|
|
302
321
|
this.bot = null;
|
|
303
|
-
this.localRuntimeBot = null;
|
|
304
322
|
this.headers.delete("Authorization");
|
|
305
323
|
}
|
|
306
324
|
/**
|
|
@@ -334,17 +352,13 @@ class BotonicAPIService {
|
|
|
334
352
|
const signupData = { email, password, org_name: orgName, campaign };
|
|
335
353
|
return this.apiPost({ path: "sign-up/", body: signupData });
|
|
336
354
|
}
|
|
337
|
-
async createBot(botName) {
|
|
355
|
+
async createBot(botName, isTest = false) {
|
|
338
356
|
const resp = await this.apiPost({
|
|
339
357
|
apiVersion: "v2",
|
|
340
358
|
path: "bots/",
|
|
341
|
-
body: { name: botName }
|
|
359
|
+
body: { name: botName, is_test: isTest }
|
|
342
360
|
});
|
|
343
|
-
|
|
344
|
-
this.setLocalRuntimeBot(resp.data);
|
|
345
|
-
} else {
|
|
346
|
-
this.setCurrentBot(resp.data);
|
|
347
|
-
}
|
|
361
|
+
this.setCurrentBot(resp.data);
|
|
348
362
|
return resp;
|
|
349
363
|
}
|
|
350
364
|
async getBots() {
|
|
@@ -396,31 +410,6 @@ class BotonicAPIService {
|
|
|
396
410
|
params: { deploy_id: deployId }
|
|
397
411
|
});
|
|
398
412
|
}
|
|
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
413
|
async build({
|
|
425
414
|
projectRoot,
|
|
426
415
|
projectName
|
|
@@ -474,7 +463,7 @@ class BotonicAPIService {
|
|
|
474
463
|
async prepareLambda(projectRoot) {
|
|
475
464
|
try {
|
|
476
465
|
(0, import_child_process.execSync)(
|
|
477
|
-
`mkdir -p ${projectRoot}/dist/lambda &&
|
|
466
|
+
`mkdir -p ${projectRoot}/dist/lambda && rsync -a --exclude=node_modules/ ${projectRoot}/src/server/lambda/ ${projectRoot}/dist/lambda/`
|
|
478
467
|
);
|
|
479
468
|
return true;
|
|
480
469
|
} catch (error) {
|
|
@@ -532,6 +521,7 @@ class BotonicAPIService {
|
|
|
532
521
|
async apiDelete({
|
|
533
522
|
apiVersion = "v1",
|
|
534
523
|
path,
|
|
524
|
+
body,
|
|
535
525
|
headers,
|
|
536
526
|
params
|
|
537
527
|
}) {
|
|
@@ -547,9 +537,84 @@ class BotonicAPIService {
|
|
|
547
537
|
}
|
|
548
538
|
return this.apiClient.delete(`${this.baseUrl}/${apiVersion}/${path}`, {
|
|
549
539
|
headers: headers || this.headers,
|
|
550
|
-
params
|
|
540
|
+
params,
|
|
541
|
+
...body !== void 0 && { data: body }
|
|
551
542
|
});
|
|
552
543
|
}
|
|
544
|
+
async apiPut({
|
|
545
|
+
apiVersion = "v1",
|
|
546
|
+
path,
|
|
547
|
+
body,
|
|
548
|
+
headers,
|
|
549
|
+
params
|
|
550
|
+
}) {
|
|
551
|
+
if (this.oauth?.access_token && this.isTokenExpired()) {
|
|
552
|
+
try {
|
|
553
|
+
await this.refreshToken();
|
|
554
|
+
} catch (error) {
|
|
555
|
+
console.warn(
|
|
556
|
+
"Proactive token refresh failed, proceeding with request:",
|
|
557
|
+
error
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return this.apiClient.put(
|
|
562
|
+
`${this.baseUrl}/${apiVersion}/${path}`,
|
|
563
|
+
body,
|
|
564
|
+
{
|
|
565
|
+
headers: headers || this.headers,
|
|
566
|
+
params
|
|
567
|
+
}
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
async registerDevSessionWhatsapp(botId, chatProviderId, devSessionUrl, lambdaFunctionName, botConfig) {
|
|
571
|
+
return this.apiPost({
|
|
572
|
+
apiVersion: "v2",
|
|
573
|
+
path: `bots/${botId}/dev_session/`,
|
|
574
|
+
body: {
|
|
575
|
+
channel: "whatsapp",
|
|
576
|
+
chat_provider_id: chatProviderId,
|
|
577
|
+
lambda_endpoint: devSessionUrl,
|
|
578
|
+
lambda_function_name: lambdaFunctionName,
|
|
579
|
+
...botConfig && { bot_config: botConfig }
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
async registerDevSessionWebchat(botId, chatProviderId, devSessionUrl, lambdaFunctionName, botConfig) {
|
|
584
|
+
return this.apiPost({
|
|
585
|
+
apiVersion: "v2",
|
|
586
|
+
path: `bots/${botId}/dev_session/`,
|
|
587
|
+
body: {
|
|
588
|
+
channel: "webchat",
|
|
589
|
+
chat_provider_id: chatProviderId,
|
|
590
|
+
lambda_endpoint: devSessionUrl,
|
|
591
|
+
lambda_function_name: lambdaFunctionName,
|
|
592
|
+
...botConfig && { bot_config: botConfig }
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
async unregisterDevSessionWhatsapp(botId, chatProviderId) {
|
|
597
|
+
return this.apiDelete({
|
|
598
|
+
apiVersion: "v2",
|
|
599
|
+
path: `bots/${botId}/dev_session/`,
|
|
600
|
+
body: { channel: "whatsapp", chat_provider_id: chatProviderId }
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
async unregisterDevSessionWebchat(botId, chatProviderId) {
|
|
604
|
+
return this.apiDelete({
|
|
605
|
+
apiVersion: "v2",
|
|
606
|
+
path: `bots/${botId}/dev_session/`,
|
|
607
|
+
body: { channel: "webchat", chat_provider_id: chatProviderId }
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
async refreshTokenIfNeeded() {
|
|
611
|
+
if (this.oauth?.access_token) {
|
|
612
|
+
try {
|
|
613
|
+
await this.refreshToken();
|
|
614
|
+
} catch {
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
553
618
|
async getMe() {
|
|
554
619
|
return this.apiClient.get("/v3/users/me/");
|
|
555
620
|
}
|
|
@@ -568,7 +633,10 @@ class BotonicAPIService {
|
|
|
568
633
|
if (!this.oauth?.access_token) {
|
|
569
634
|
return true;
|
|
570
635
|
}
|
|
571
|
-
|
|
636
|
+
if (!this._tokenExpiresAt) {
|
|
637
|
+
return false;
|
|
638
|
+
}
|
|
639
|
+
return Date.now() >= this._tokenExpiresAt - 6e4;
|
|
572
640
|
}
|
|
573
641
|
async getHeaders(form) {
|
|
574
642
|
return new Promise((resolve, reject) => {
|
package/src/lib/bot-config.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export interface ToolConfigJSON {
|
|
2
|
+
name: string;
|
|
3
|
+
schema?: Record<string, unknown>;
|
|
4
|
+
description: string;
|
|
5
|
+
}
|
|
6
|
+
export interface WebviewConfigJSON {
|
|
7
|
+
name: string;
|
|
8
|
+
}
|
|
1
9
|
export interface BotConfigJSON {
|
|
2
10
|
build_info: {
|
|
3
11
|
node_version: string;
|
|
@@ -7,14 +15,9 @@ export interface BotConfigJSON {
|
|
|
7
15
|
packages: Record<string, {
|
|
8
16
|
version: string;
|
|
9
17
|
}>;
|
|
10
|
-
tools:
|
|
11
|
-
name: string;
|
|
12
|
-
description: string;
|
|
13
|
-
}>;
|
|
18
|
+
tools: ToolConfigJSON[];
|
|
14
19
|
payloads: string[];
|
|
15
|
-
webviews:
|
|
16
|
-
name: string;
|
|
17
|
-
}>;
|
|
20
|
+
webviews: WebviewConfigJSON[];
|
|
18
21
|
}
|
|
19
22
|
export declare class BotConfig {
|
|
20
23
|
static get(projectRoot: string): Promise<BotConfigJSON>;
|
package/src/lib/bot-config.js
CHANGED
|
@@ -35,6 +35,7 @@ var childProcess = __toESM(require("child_process"));
|
|
|
35
35
|
var import_fs = require("fs");
|
|
36
36
|
var import_path = require("path");
|
|
37
37
|
var util = __toESM(require("util"));
|
|
38
|
+
var import_zod = require("zod");
|
|
38
39
|
const CONSTANTS_PATH = "src/shared/constants";
|
|
39
40
|
const TOOLS_PATH = "src/server/bot/tools";
|
|
40
41
|
class BotConfig {
|
|
@@ -108,7 +109,10 @@ class BotConfig {
|
|
|
108
109
|
return toolsModule.customTools.map(
|
|
109
110
|
(tool) => ({
|
|
110
111
|
name: tool.name,
|
|
111
|
-
description: tool.description
|
|
112
|
+
description: tool.description,
|
|
113
|
+
schema: import_zod.z.toJSONSchema(tool.schema, {
|
|
114
|
+
target: "draft-07"
|
|
115
|
+
})
|
|
112
116
|
})
|
|
113
117
|
);
|
|
114
118
|
}
|
package/src/lib/constants.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export declare const BOTONIC_NPM_NAMESPACE = "@botonic";
|
|
2
2
|
export declare const BOTONIC_HOME_DIRNAME = ".botonic";
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const ENV_CREDENTIALS_FILENAME = "env-credentials.json";
|
|
4
|
+
export declare const BOTS_REGISTRY_FILENAME = "bots.json";
|
|
4
5
|
export declare const BOTONIC_PROJECT_PATH: string;
|
|
5
|
-
export declare const BOT_CREDENTIALS_FILENAME = ".botonic.json";
|
|
6
|
-
export declare const LOCAL_RUNTIME_BOT_CREDENTIALS_FILENAME = ".local-runtime-botonic.json";
|
|
7
6
|
export declare const ANALYTICS_WRITE_KEY = "YD0jpJHNGW12uhLNbgB4wbdTRQ4Cy1Zu";
|
|
8
7
|
export declare const CLOUD_PROVIDERS: Readonly<{
|
|
9
8
|
AWS: "aws";
|
package/src/lib/constants.js
CHANGED
|
@@ -23,10 +23,9 @@ __export(constants_exports, {
|
|
|
23
23
|
BOTONIC_HOME_DIRNAME: () => BOTONIC_HOME_DIRNAME,
|
|
24
24
|
BOTONIC_NPM_NAMESPACE: () => BOTONIC_NPM_NAMESPACE,
|
|
25
25
|
BOTONIC_PROJECT_PATH: () => BOTONIC_PROJECT_PATH,
|
|
26
|
-
|
|
26
|
+
BOTS_REGISTRY_FILENAME: () => BOTS_REGISTRY_FILENAME,
|
|
27
27
|
CLOUD_PROVIDERS: () => CLOUD_PROVIDERS,
|
|
28
|
-
|
|
29
|
-
LOCAL_RUNTIME_BOT_CREDENTIALS_FILENAME: () => LOCAL_RUNTIME_BOT_CREDENTIALS_FILENAME,
|
|
28
|
+
ENV_CREDENTIALS_FILENAME: () => ENV_CREDENTIALS_FILENAME,
|
|
30
29
|
PATH_TO_AWS_CONFIG: () => PATH_TO_AWS_CONFIG
|
|
31
30
|
});
|
|
32
31
|
module.exports = __toCommonJS(constants_exports);
|
|
@@ -34,10 +33,9 @@ var import_path = require("path");
|
|
|
34
33
|
var import_process = require("process");
|
|
35
34
|
const BOTONIC_NPM_NAMESPACE = "@botonic";
|
|
36
35
|
const BOTONIC_HOME_DIRNAME = ".botonic";
|
|
37
|
-
const
|
|
36
|
+
const ENV_CREDENTIALS_FILENAME = "env-credentials.json";
|
|
37
|
+
const BOTS_REGISTRY_FILENAME = "bots.json";
|
|
38
38
|
const BOTONIC_PROJECT_PATH = process.cwd();
|
|
39
|
-
const BOT_CREDENTIALS_FILENAME = ".botonic.json";
|
|
40
|
-
const LOCAL_RUNTIME_BOT_CREDENTIALS_FILENAME = ".local-runtime-botonic.json";
|
|
41
39
|
const ANALYTICS_WRITE_KEY = "YD0jpJHNGW12uhLNbgB4wbdTRQ4Cy1Zu";
|
|
42
40
|
const CLOUD_PROVIDERS = Object.freeze({
|
|
43
41
|
AWS: "aws",
|
|
@@ -52,9 +50,8 @@ const PATH_TO_AWS_CONFIG = (0, import_path.join)((0, import_process.cwd)(), AWS_
|
|
|
52
50
|
BOTONIC_HOME_DIRNAME,
|
|
53
51
|
BOTONIC_NPM_NAMESPACE,
|
|
54
52
|
BOTONIC_PROJECT_PATH,
|
|
55
|
-
|
|
53
|
+
BOTS_REGISTRY_FILENAME,
|
|
56
54
|
CLOUD_PROVIDERS,
|
|
57
|
-
|
|
58
|
-
LOCAL_RUNTIME_BOT_CREDENTIALS_FILENAME,
|
|
55
|
+
ENV_CREDENTIALS_FILENAME,
|
|
59
56
|
PATH_TO_AWS_CONFIG
|
|
60
57
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BotRegistryEntry, BotsRegistry, GlobalCredentialsStore, JSONObject } from './interfaces';
|
|
2
2
|
export declare class CredentialsHandler {
|
|
3
3
|
homeDir: string;
|
|
4
4
|
pathToCredentials: string;
|
|
@@ -9,12 +9,12 @@ export declare class CredentialsHandler {
|
|
|
9
9
|
initialize(): void;
|
|
10
10
|
createDirIfNotExists(): void;
|
|
11
11
|
loadJSON(): JSONObject | undefined;
|
|
12
|
-
dumpJSON(obj: JSONObject): void;
|
|
12
|
+
dumpJSON(obj: JSONObject | JSONObject[]): void;
|
|
13
13
|
}
|
|
14
14
|
export declare class GlobalCredentialsHandler extends CredentialsHandler {
|
|
15
15
|
/**
|
|
16
16
|
* @param baseDir - Optional directory for credentials (e.g. monorepo_root/.botonic).
|
|
17
|
-
* When provided, credentials are stored at baseDir/credentials.json
|
|
17
|
+
* When provided, credentials are stored at baseDir/env-credentials.json.
|
|
18
18
|
* When omitted, uses ~/.botonic (user home).
|
|
19
19
|
*/
|
|
20
20
|
constructor(baseDir?: string);
|
|
@@ -22,19 +22,10 @@ export declare class GlobalCredentialsHandler extends CredentialsHandler {
|
|
|
22
22
|
load(): GlobalCredentialsStore | undefined;
|
|
23
23
|
dump(obj: GlobalCredentialsStore): void;
|
|
24
24
|
}
|
|
25
|
-
declare class
|
|
26
|
-
constructor(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
dump(obj: T): void;
|
|
32
|
-
}
|
|
33
|
-
export declare class BotCredentialsHandler extends BaseBotCredentialsHandler<BotCredentials> {
|
|
34
|
-
/**
|
|
35
|
-
* @param projectRoot - Directory for app/project .botonic.json (e.g. apps/my-bot).
|
|
36
|
-
* When omitted, uses process.cwd() (may write to repo root when Nx cwd is workspace root).
|
|
37
|
-
*/
|
|
38
|
-
constructor(projectRoot?: string);
|
|
25
|
+
export declare class BotsRegistryHandler extends CredentialsHandler {
|
|
26
|
+
constructor();
|
|
27
|
+
load(): BotsRegistry;
|
|
28
|
+
dump(registry: BotsRegistry): void;
|
|
29
|
+
upsert(env: string, entry: BotRegistryEntry): void;
|
|
30
|
+
findLatestForEnv(env: string): BotRegistryEntry | undefined;
|
|
39
31
|
}
|
|
40
|
-
export {};
|
|
@@ -18,7 +18,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var credentials_handler_exports = {};
|
|
20
20
|
__export(credentials_handler_exports, {
|
|
21
|
-
|
|
21
|
+
BotsRegistryHandler: () => BotsRegistryHandler,
|
|
22
22
|
CredentialsHandler: () => CredentialsHandler,
|
|
23
23
|
GlobalCredentialsHandler: () => GlobalCredentialsHandler
|
|
24
24
|
});
|
|
@@ -58,13 +58,13 @@ class CredentialsHandler {
|
|
|
58
58
|
class GlobalCredentialsHandler extends CredentialsHandler {
|
|
59
59
|
/**
|
|
60
60
|
* @param baseDir - Optional directory for credentials (e.g. monorepo_root/.botonic).
|
|
61
|
-
* When provided, credentials are stored at baseDir/credentials.json
|
|
61
|
+
* When provided, credentials are stored at baseDir/env-credentials.json.
|
|
62
62
|
* When omitted, uses ~/.botonic (user home).
|
|
63
63
|
*/
|
|
64
64
|
constructor(baseDir) {
|
|
65
65
|
super({
|
|
66
66
|
homeDir: baseDir ? (0, import_path.resolve)(baseDir) : (0, import_path.join)((0, import_file_system.getHomeDirectory)(), import_constants.BOTONIC_HOME_DIRNAME),
|
|
67
|
-
filename: import_constants.
|
|
67
|
+
filename: import_constants.ENV_CREDENTIALS_FILENAME
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
initialize() {
|
|
@@ -79,37 +79,55 @@ class GlobalCredentialsHandler extends CredentialsHandler {
|
|
|
79
79
|
return this.dumpJSON(obj);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
class
|
|
83
|
-
constructor(
|
|
82
|
+
class BotsRegistryHandler extends CredentialsHandler {
|
|
83
|
+
constructor() {
|
|
84
84
|
super({
|
|
85
|
-
homeDir:
|
|
86
|
-
filename:
|
|
85
|
+
homeDir: (0, import_path.join)((0, import_file_system.getHomeDirectory)(), import_constants.BOTONIC_HOME_DIRNAME),
|
|
86
|
+
filename: import_constants.BOTS_REGISTRY_FILENAME
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
load() {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
try {
|
|
91
|
+
if (!(0, import_file_system.pathExists)(this.pathToCredentials)) return {};
|
|
92
|
+
const result = (0, import_file_system.readJSON)(this.pathToCredentials);
|
|
93
|
+
return result && !Array.isArray(result) ? result : {};
|
|
94
|
+
} catch {
|
|
95
|
+
console.warn("bots.json could not be loaded");
|
|
96
|
+
return {};
|
|
97
|
+
}
|
|
93
98
|
}
|
|
94
|
-
dump(
|
|
95
|
-
|
|
99
|
+
dump(registry) {
|
|
100
|
+
try {
|
|
101
|
+
(0, import_file_system.writeJSON)(this.pathToCredentials, registry);
|
|
102
|
+
} catch {
|
|
103
|
+
console.warn("bots.json could not be written");
|
|
104
|
+
}
|
|
96
105
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
upsert(env, entry) {
|
|
107
|
+
try {
|
|
108
|
+
const registry = this.load();
|
|
109
|
+
const list = registry[env] ?? [];
|
|
110
|
+
const idx = list.findIndex((e) => e.id === entry.id);
|
|
111
|
+
if (idx !== -1) {
|
|
112
|
+
list[idx] = entry;
|
|
113
|
+
} else {
|
|
114
|
+
list.push(entry);
|
|
115
|
+
}
|
|
116
|
+
registry[env] = list;
|
|
117
|
+
this.dump(registry);
|
|
118
|
+
} catch {
|
|
119
|
+
console.warn("bots.json could not be updated");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
findLatestForEnv(env) {
|
|
123
|
+
const registry = this.load();
|
|
124
|
+
const list = registry[env] ?? [];
|
|
125
|
+
return list.length > 0 ? list[list.length - 1] : void 0;
|
|
108
126
|
}
|
|
109
127
|
}
|
|
110
128
|
// Annotate the CommonJS export names for ESM import in node:
|
|
111
129
|
0 && (module.exports = {
|
|
112
|
-
|
|
130
|
+
BotsRegistryHandler,
|
|
113
131
|
CredentialsHandler,
|
|
114
132
|
GlobalCredentialsHandler
|
|
115
133
|
});
|
package/src/lib/interfaces.d.ts
CHANGED
|
@@ -24,23 +24,20 @@ export interface EnvironmentCredentials {
|
|
|
24
24
|
}
|
|
25
25
|
/** Store: one entry per environment so multiple envs can be logged in. */
|
|
26
26
|
export type GlobalCredentialsStore = Record<string, EnvironmentCredentials>;
|
|
27
|
+
export interface ProviderAccountEntry {
|
|
28
|
+
id: string;
|
|
29
|
+
provider: string;
|
|
30
|
+
is_test: boolean;
|
|
31
|
+
is_active: boolean;
|
|
32
|
+
}
|
|
27
33
|
export interface BotDetail {
|
|
28
34
|
id: string;
|
|
29
35
|
name: string;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
created_at: string;
|
|
33
|
-
provider_accounts: any[];
|
|
34
|
-
is_debug: boolean;
|
|
35
|
-
is_published: boolean;
|
|
36
|
-
active_users: number;
|
|
37
|
-
}
|
|
38
|
-
export interface BotCredentials {
|
|
39
|
-
bot: BotDetail | null;
|
|
40
|
-
}
|
|
41
|
-
export interface LocalRuntimeBotCredentials {
|
|
42
|
-
localRuntimeBot: BotDetail | null;
|
|
36
|
+
providers?: ProviderAccountEntry[];
|
|
37
|
+
[key: string]: unknown;
|
|
43
38
|
}
|
|
39
|
+
export type BotRegistryEntry = BotDetail;
|
|
40
|
+
export type BotsRegistry = Record<string, BotRegistryEntry[]>;
|
|
44
41
|
export type JSONPrimitive = string | number | boolean | null;
|
|
45
42
|
export type JSONValue = JSONPrimitive | JSONObject | JSONArray;
|
|
46
43
|
export type JSONObject = {
|