@botonic/nx-plugin 2.30.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 +13 -0
- package/executors.json +0 -5
- package/package.json +1 -1
- 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/vite/node.config.ts.template +2 -7
- package/src/lib/api-service.d.ts +19 -20
- package/src/lib/api-service.js +150 -82
- 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 +52 -23
- package/src/lib/util/executor-helpers.js +494 -106
- package/src/plugin.js +5 -14
- package/src/executors/deploy-local-runtime/executor.d.ts +0 -5
- package/src/executors/deploy-local-runtime/executor.js +0 -148
- 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/vite/botonic-ssr-deps.ts.template +0 -56
- package/src/generators/preset/files/package.json +0 -26
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { resolve } from 'path'
|
|
2
2
|
import type { UserConfig } from 'vite'
|
|
3
3
|
|
|
4
|
-
import { getBotonicThirdPartyDeps } from './botonic-ssr-deps'
|
|
5
4
|
import { BUILD_CONFIG } from './build.config'
|
|
6
5
|
|
|
7
6
|
const projectRoot = resolve(__dirname, '..')
|
|
@@ -13,13 +12,9 @@ export function getNodeConfig(): UserConfig {
|
|
|
13
12
|
root: projectRoot,
|
|
14
13
|
cacheDir: resolve(projectRoot, BUILD_CONFIG.CACHE_DIR.node),
|
|
15
14
|
|
|
16
|
-
// Bundle all
|
|
17
|
-
// artifact. By default Vite SSR externalizes node_modules, but Lambda has no
|
|
18
|
-
// node_modules at runtime so everything must be self-contained.
|
|
19
|
-
// Third-party deps are derived programmatically from the @botonic/* package.json
|
|
20
|
-
// files so this list stays correct as plugins add new dependencies.
|
|
15
|
+
// Bundle all dependencies into the Lambda artifact — no node_modules at runtime.
|
|
21
16
|
ssr: {
|
|
22
|
-
noExternal:
|
|
17
|
+
noExternal: true,
|
|
23
18
|
},
|
|
24
19
|
|
|
25
20
|
build: {
|
package/src/lib/api-service.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { AxiosHeaders, AxiosInstance, AxiosResponse } from 'axios';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import type { BotDetail, Me, OAuth } from './interfaces';
|
|
2
|
+
import { GlobalCredentialsHandler } from './credentials-handler';
|
|
3
|
+
import type { BotDetail, Me, OAuth, ProviderAccountEntry } from './interfaces';
|
|
5
4
|
interface IntegrationResponse {
|
|
6
5
|
detail: string;
|
|
7
6
|
provider_account: {
|
|
@@ -26,9 +25,8 @@ interface IntegrationResponse {
|
|
|
26
25
|
netlify_url: string | null;
|
|
27
26
|
}
|
|
28
27
|
interface BotonicAPIServiceConfig {
|
|
29
|
-
isLocalRuntimeDeployment?: boolean;
|
|
30
28
|
projectRoot?: string;
|
|
31
|
-
/** Monorepo/workspace root. When set, global credentials are stored at workspaceRoot/.botonic/credentials.json (source of truth). */
|
|
29
|
+
/** Monorepo/workspace root. When set, global credentials are stored at workspaceRoot/.botonic/env-credentials.json (source of truth). */
|
|
32
30
|
workspaceRoot?: string;
|
|
33
31
|
environmentVariables?: Record<string, string>;
|
|
34
32
|
targetEnvironment?: string;
|
|
@@ -37,18 +35,17 @@ export declare class BotonicAPIService {
|
|
|
37
35
|
clientId: string;
|
|
38
36
|
baseUrl: string;
|
|
39
37
|
loginUrl: string;
|
|
40
|
-
|
|
38
|
+
private botsRegistryHandler;
|
|
41
39
|
globalCredentialsHandler: InstanceType<typeof GlobalCredentialsHandler>;
|
|
42
40
|
oauth?: OAuth;
|
|
41
|
+
private _tokenExpiresAt?;
|
|
43
42
|
me?: Me;
|
|
44
43
|
/** Cached from credentials for display when me is not loaded yet. */
|
|
45
44
|
loggedUserName?: string;
|
|
46
45
|
loggedEnvironmentUrl?: string;
|
|
47
46
|
bot: BotDetail | null;
|
|
48
|
-
localRuntimeBot: BotDetail | null;
|
|
49
47
|
headers: AxiosHeaders;
|
|
50
48
|
apiClient: AxiosInstance;
|
|
51
|
-
isLocalRuntimeDeployment?: boolean;
|
|
52
49
|
projectRoot?: string;
|
|
53
50
|
targetEnvironment?: string;
|
|
54
51
|
constructor(config?: BotonicAPIServiceConfig);
|
|
@@ -56,20 +53,21 @@ export declare class BotonicAPIService {
|
|
|
56
53
|
botInfo(): BotDetail;
|
|
57
54
|
getOauth(): OAuth;
|
|
58
55
|
isAuthenticated(): boolean;
|
|
59
|
-
/** True when in local runtime mode and a bot was loaded (e.g. from app .botonic.json). */
|
|
60
|
-
hasLocalRuntimeBot(): boolean;
|
|
61
56
|
ensureAuthenticated(): Promise<void>;
|
|
62
|
-
setCurrentBot(bot:
|
|
63
|
-
|
|
57
|
+
setCurrentBot(bot: BotDetail | null): void;
|
|
58
|
+
selectBot(bot: BotDetail): Promise<void>;
|
|
64
59
|
private loadGlobalCredentials;
|
|
65
60
|
/**
|
|
66
61
|
* Returns store as env -> credentials. Migrates old single-credential format to { local: creds }.
|
|
67
62
|
*/
|
|
68
63
|
private normalizeCredentialsStore;
|
|
69
|
-
private
|
|
64
|
+
private loadBotFromRegistry;
|
|
65
|
+
private saveToBotsRegistry;
|
|
66
|
+
saveProviders(providers: ProviderAccountEntry[]): void;
|
|
67
|
+
fetchProviders(botId: string): Promise<ProviderAccountEntry[]>;
|
|
68
|
+
saveBotEntry(bot: BotDetail): void;
|
|
70
69
|
private setHeaders;
|
|
71
70
|
private saveGlobalCredentials;
|
|
72
|
-
private saveBotCredentials;
|
|
73
71
|
private refreshToken;
|
|
74
72
|
login(email: string, password: string): Promise<void>;
|
|
75
73
|
logout(): Promise<void>;
|
|
@@ -83,17 +81,12 @@ export declare class BotonicAPIService {
|
|
|
83
81
|
getDisplayName(): string;
|
|
84
82
|
createWebchatIntegration(botId: string, integrationName: string): Promise<AxiosResponse<IntegrationResponse>>;
|
|
85
83
|
signup(email: string, password: string, orgName: string, campaign: any): Promise<any>;
|
|
86
|
-
createBot(botName: string): Promise<AxiosResponse>;
|
|
84
|
+
createBot(botName: string, isTest?: boolean): Promise<AxiosResponse>;
|
|
87
85
|
getBots(): Promise<AxiosResponse>;
|
|
88
86
|
deleteBot(botId: string): Promise<AxiosResponse>;
|
|
89
87
|
getProviders(botId?: string): Promise<AxiosResponse>;
|
|
90
88
|
deployBot(bundlePath: string, botConfigJson: any): Promise<any>;
|
|
91
89
|
deployStatus(deployId: string): Promise<AxiosResponse>;
|
|
92
|
-
deployLocalRuntime({ botConfigJson, lambdaFunctionName, lambdaEndpoint, }: {
|
|
93
|
-
botConfigJson: BotConfigJSON;
|
|
94
|
-
lambdaFunctionName: string;
|
|
95
|
-
lambdaEndpoint: string;
|
|
96
|
-
}): Promise<AxiosResponse<unknown, any, {}>>;
|
|
97
90
|
build({ projectRoot, projectName, }: {
|
|
98
91
|
projectRoot: string;
|
|
99
92
|
projectName: string;
|
|
@@ -102,6 +95,12 @@ export declare class BotonicAPIService {
|
|
|
102
95
|
private apiPost;
|
|
103
96
|
private apiGet;
|
|
104
97
|
private apiDelete;
|
|
98
|
+
private apiPut;
|
|
99
|
+
registerDevSessionWhatsapp(botId: string, chatProviderId: string, devSessionUrl: string, lambdaFunctionName: string, botConfig?: object): Promise<AxiosResponse>;
|
|
100
|
+
registerDevSessionWebchat(botId: string, chatProviderId: string, devSessionUrl: string, lambdaFunctionName: string, botConfig?: object): Promise<AxiosResponse>;
|
|
101
|
+
unregisterDevSessionWhatsapp(botId: string, chatProviderId: string): Promise<AxiosResponse>;
|
|
102
|
+
unregisterDevSessionWebchat(botId: string, chatProviderId: string): Promise<AxiosResponse>;
|
|
103
|
+
refreshTokenIfNeeded(): Promise<void>;
|
|
105
104
|
private getMe;
|
|
106
105
|
private validateToken;
|
|
107
106
|
private isTokenExpired;
|
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/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 {};
|