@botpress/cli 0.0.3 → 0.0.5

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.
@@ -24,63 +24,29 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
25
  var project_exports = {};
26
26
  __export(project_exports, {
27
- ProjectCommands: () => ProjectCommands,
28
- ProjectPaths: () => ProjectPaths
27
+ ProjectCommands: () => ProjectCommands
29
28
  });
30
29
  module.exports = __toCommonJS(project_exports);
31
- var bpclient = __toESM(require("@botpress/client"));
32
30
  var import_bluebird = __toESM(require("bluebird"));
33
31
  var import_chalk = __toESM(require("chalk"));
34
32
  var import_fs = __toESM(require("fs"));
35
33
  var import_lodash = __toESM(require("lodash"));
36
34
  var import_path = __toESM(require("path"));
37
35
  var import_prompts = __toESM(require("prompts"));
38
- var consts = __toESM(require("../const"));
39
- var pathutils = __toESM(require("../paths"));
40
- var requireutils = __toESM(require("../requires"));
36
+ var consts = __toESM(require("../consts"));
37
+ var esbuildutils = __toESM(require("../esbuild-utils"));
38
+ var pathutils = __toESM(require("../path-utils"));
39
+ var requireutils = __toESM(require("../require-utils"));
41
40
  var import_worker = require("../worker");
42
- var import_api_utils = require("./api-utils");
43
41
  var import_base = require("./base");
44
42
  var errors = __toESM(require("./errors"));
45
- var esbuild = __toESM(require("./esbuild"));
46
43
  var generator = __toESM(require("./generator"));
47
44
  var import_integration_ref = require("./integration-ref");
48
- class ProjectPaths {
49
- abs;
50
- rel;
51
- static from(paths, overrides) {
52
- const rel = { ...paths.rel, ...overrides };
53
- return new ProjectPaths(rel);
54
- }
55
- constructor({ workDir, definition, entryPoint: entrypoint, outDir }) {
56
- const absWorkdir = pathutils.absoluteFrom(pathutils.cwd(), workDir);
57
- const absDefinition = pathutils.absoluteFrom(absWorkdir, definition);
58
- const absEntrypoint = pathutils.absoluteFrom(absWorkdir, entrypoint);
59
- const absOutdir = pathutils.absoluteFrom(absWorkdir, outDir);
60
- this.abs = { workDir: absWorkdir, definition: absDefinition, entryPoint: absEntrypoint, outDir: absOutdir };
61
- const relDefinition = pathutils.relativeFrom(this.abs.workDir, this.abs.definition);
62
- const relEntrypoint = pathutils.relativeFrom(this.abs.workDir, this.abs.entryPoint);
63
- const relOutdir = pathutils.relativeFrom(this.abs.workDir, this.abs.outDir);
64
- const relWorkdir = ".";
65
- this.rel = { workDir: relWorkdir, definition: relDefinition, entryPoint: relEntrypoint, outDir: relOutdir };
66
- }
67
- }
68
- const ENTRY_CODE = (entrypoint) => {
69
- const unixPath = pathutils.toUnix(entrypoint);
70
- const importFrom = pathutils.rmExtension(unixPath);
71
- return `
72
- import x from './${importFrom}'
73
- export default x
74
- export const handler = x.handler
75
- `;
76
- };
77
45
  class ProjectCommands extends import_base.BaseCommands {
78
- constructor(_props, _paths, _projectCache, _userCache, logger) {
79
- super(logger);
80
- this._props = _props;
46
+ constructor(props, _paths, _projectCache, userCache, logger) {
47
+ super(props, userCache, logger);
81
48
  this._paths = _paths;
82
49
  this._projectCache = _projectCache;
83
- this._userCache = _userCache;
84
50
  }
85
51
  async installIntegration(integrationRef, argv) {
86
52
  const integrationDef = await this._readIntegrationDefinitionFromFS();
@@ -110,20 +76,17 @@ class ProjectCommands extends import_base.BaseCommands {
110
76
  await this._generateIntegrationInstance(integration);
111
77
  }
112
78
  async buildProject(argv) {
113
- const { abs } = this._paths;
114
79
  const t0 = Date.now();
115
80
  const integrationDef = await this._readIntegrationDefinitionFromFS();
116
81
  if (integrationDef) {
117
- await this._generateImplementationTypings(integrationDef);
118
- await import_fs.default.promises.writeFile(consts.defDataOutfile(abs.outDir), JSON.stringify(integrationDef, void 0, 2));
82
+ await this.generateTypings(argv);
119
83
  }
120
84
  await this.bundleProject(argv);
121
85
  const dt = Date.now() - t0;
122
86
  this._logger.log(`Build completed in ${dt}ms`);
123
87
  }
124
88
  async serveProject(argv) {
125
- const { abs } = this._paths;
126
- const outfile = consts.outfile(abs.outDir);
89
+ const outfile = this._paths.abs.outFile;
127
90
  if (!import_fs.default.existsSync(outfile)) {
128
91
  throw new errors.NoBundleFoundError();
129
92
  }
@@ -137,29 +100,37 @@ class ProjectCommands extends import_base.BaseCommands {
137
100
  const { rel, abs } = this._paths;
138
101
  const line = this._logger.line();
139
102
  const logLevel = this._props.verbose ? "info" : "silent";
140
- try {
141
- if (integrationDef) {
142
- const { name } = integrationDef;
143
- line.started(`Bundling integration ${import_chalk.default.bold(name)}...`);
144
- } else {
145
- line.started("Bundling bot...");
146
- }
147
- const code = ENTRY_CODE(rel.entryPoint);
148
- const outfile = consts.outfile(rel.outDir);
149
- line.debug(`Writing bundle to ${outfile}`);
150
- await esbuild.buildCode({ code, cwd: abs.workDir, outfile, logLevel, write: true });
151
- line.success(`Bundle available at ${import_chalk.default.grey(rel.outDir)}`);
152
- } finally {
153
- line.commit();
154
- }
103
+ if (integrationDef) {
104
+ const { name } = integrationDef;
105
+ line.started(`Bundling integration ${import_chalk.default.bold(name)}...`);
106
+ } else {
107
+ line.started("Bundling bot...");
108
+ }
109
+ const unixPath = pathutils.toUnix(rel.entryPoint);
110
+ const importFrom = pathutils.rmExtension(unixPath);
111
+ const code = `import x from './${importFrom}'; export default x; export const handler = x.handler;`;
112
+ const outfile = abs.outFile;
113
+ line.debug(`Writing bundle to ${outfile}`);
114
+ await esbuildutils.buildCode({ code, cwd: abs.workDir, outfile, logLevel, write: true });
115
+ line.success(`Bundle available at ${import_chalk.default.grey(rel.outDir)}`);
155
116
  }
156
117
  async generateTypings(_argv) {
157
- const integrationDefinition = await this._readIntegrationDefinitionFromFS();
158
- if (!integrationDefinition) {
118
+ const integrationDef = await this._readIntegrationDefinitionFromFS();
119
+ if (!integrationDef) {
159
120
  this._logger.warn("No typings to generate for bot");
160
121
  return;
161
122
  }
162
- return this._generateImplementationTypings(integrationDefinition);
123
+ const line = this._logger.line();
124
+ const { name } = integrationDef;
125
+ line.started(`Generating typings for integration ${import_chalk.default.bold(name)}...`);
126
+ const typingFiles = await generator.generateIntegrationImplementationTypings(
127
+ integrationDef,
128
+ consts.relativeToOutFolder.implementationDir
129
+ );
130
+ const indexFile = await generator.generateIntegrationIndex(consts.relativeToOutFolder.implementationDir);
131
+ const generatedFiles = [...typingFiles, indexFile];
132
+ await this._writeFilesToOutFolder(generatedFiles);
133
+ line.success(`Typings available at ${import_chalk.default.grey(this._paths.rel.outDir)}`);
163
134
  }
164
135
  async deployProject(argv) {
165
136
  const api = await this._ensureLoginAndCreateClient(argv);
@@ -173,85 +144,108 @@ class ProjectCommands extends import_base.BaseCommands {
173
144
  if (integrationDef) {
174
145
  return this._deployIntegration(api, integrationDef);
175
146
  }
176
- return this._deployBot(api, argv.botId);
147
+ return this._deployBot(api, argv.botId, argv.createNewBot);
177
148
  }
178
149
  async devProject(argv) {
179
150
  this._logger.warn("This command is experimental and subject to breaking changes without notice.");
180
- const { abs } = this._paths;
181
- const outfile = consts.outfile(abs.outDir);
182
- if (!import_fs.default.existsSync(outfile)) {
183
- throw new errors.NoBundleFoundError();
184
- }
185
151
  if (!argv.noBuild) {
186
152
  await this.buildProject(argv);
187
153
  }
188
154
  const api = await this._ensureLoginAndCreateClient(argv);
189
155
  const integrationDef = await this._readIntegrationDefinitionFromFS();
190
- const { cleanup } = await this._createDevRessource(api, argv.url, integrationDef);
191
- try {
192
- const importPath = pathutils.toUnix(outfile);
193
- const code = `require('${importPath}').default.start(${argv.port})`;
194
- await (0, import_worker.spawnChildProcess)(
195
- {
196
- type: "code",
197
- code,
198
- env: {
199
- BP_API_URL: api.host,
200
- BP_TOKEN: api.token
201
- }
202
- },
203
- this._logger
204
- );
205
- } finally {
206
- this._logger.log("Cleaning up ressources...");
207
- await cleanup();
156
+ if (integrationDef) {
157
+ await this._deployDevIntegration(api, argv.url, integrationDef);
158
+ } else {
159
+ await this._deployDevBot(api, argv.url);
160
+ }
161
+ const outfile = this._paths.abs.outFile;
162
+ const importPath = pathutils.toUnix(outfile);
163
+ const requireFrom = pathutils.rmExtension(importPath);
164
+ const code = `require('${requireFrom}').default.start(${argv.port})`;
165
+ await (0, import_worker.spawnChildProcess)(
166
+ {
167
+ type: "code",
168
+ code,
169
+ env: {
170
+ BP_API_URL: api.host,
171
+ BP_TOKEN: api.token
172
+ }
173
+ },
174
+ this._logger
175
+ );
176
+ }
177
+ async _deployDevIntegration(api, externalUrl, integrationDef) {
178
+ const devId = await this._projectCache.get("devId");
179
+ let integration = void 0;
180
+ if (devId) {
181
+ const resp = await api.client.getIntegration({ id: devId }).catch(async (thrown) => {
182
+ const err = errors.BotpressCLIError.wrap(thrown, `Could not find existing dev integration with id "${devId}"`);
183
+ this._logger.warn(err.message);
184
+ return { integration: void 0 };
185
+ });
186
+ if (resp.integration?.dev) {
187
+ integration = resp.integration;
188
+ } else {
189
+ await this._projectCache.rm("devId");
190
+ }
191
+ }
192
+ const line = this._logger.line();
193
+ line.started(`Deploying dev integration ${import_chalk.default.bold(integrationDef.name)}...`);
194
+ if (integration) {
195
+ const resp = await api.client.updateIntegration({ ...integrationDef, id: integration.id, url: externalUrl }).catch((thrown) => {
196
+ throw errors.BotpressCLIError.wrap(thrown, `Could not update dev integration "${integrationDef.name}"`);
197
+ });
198
+ integration = resp.integration;
199
+ } else {
200
+ const resp = await api.client.createIntegration({ ...integrationDef, dev: true, url: externalUrl }).catch((thrown) => {
201
+ throw errors.BotpressCLIError.wrap(thrown, `Could not deploy dev integration "${integrationDef.name}"`);
202
+ });
203
+ integration = resp.integration;
208
204
  }
205
+ line.success(`Dev Integration deployed with id "${integration.id}"`);
206
+ await this._projectCache.set("devId", integration.id);
209
207
  }
210
- async _createDevRessource(api, externalUrl, integrationDef) {
211
- if (integrationDef) {
212
- const { integration } = await api.client.createIntegration({
213
- ...integrationDef,
208
+ async _deployDevBot(api, externalUrl) {
209
+ const devId = await this._projectCache.get("devId");
210
+ let bot = void 0;
211
+ if (devId) {
212
+ const resp = await api.client.getBot({ id: devId }).catch(async (thrown) => {
213
+ const err = errors.BotpressCLIError.wrap(thrown, `Could not find existing dev bot with id "${devId}"`);
214
+ this._logger.warn(err.message);
215
+ return { bot: void 0 };
216
+ });
217
+ if (resp.bot?.dev) {
218
+ bot = resp.bot;
219
+ } else {
220
+ await this._projectCache.rm("devId");
221
+ }
222
+ }
223
+ if (!bot) {
224
+ const createLine = this._logger.line();
225
+ createLine.started("Creating dev bot...");
226
+ const resp = await api.client.createBot({
214
227
  dev: true,
215
228
  url: externalUrl
216
229
  }).catch((thrown) => {
217
- throw errors.BotpressCLIError.wrap(thrown, `Could not deploy dev integration "${integrationDef.name}"`);
230
+ throw errors.BotpressCLIError.wrap(thrown, "Could not deploy dev bot");
218
231
  });
219
- this._logger.success(`Dev Integration created with id "${integration.id}"`);
220
- return {
221
- cleanup: () => api.client.deleteIntegration({ id: integration.id }).then(() => {
222
- }).catch((thrown) => {
223
- throw errors.BotpressCLIError.wrap(thrown, `Could not delete dev integration "${integrationDef.name}"`);
224
- })
225
- };
232
+ bot = resp.bot;
233
+ createLine.success(`Dev Bot created with id "${bot.id}"`);
234
+ await this._projectCache.set("devId", bot.id);
226
235
  }
227
- const { abs } = this._paths;
228
- const outfile = consts.outfile(abs.outDir);
229
- const {
230
- default: { integrations: integrationList }
231
- } = requireutils.requireJsFile(outfile);
232
- const { bot: createdBot } = await api.client.createBot({
233
- dev: true,
234
- url: externalUrl
235
- }).catch((thrown) => {
236
- throw errors.BotpressCLIError.wrap(thrown, "Could not deploy dev bot");
237
- });
238
- const integrations = (0, import_lodash.default)(integrationList ?? []).keyBy((i) => i.id).mapValues(({ enabled, configuration }) => ({ enabled, configuration })).value();
239
- this._logger.debug("Bot created, updating integrations...", { integrations });
240
- const { bot: updatedBot } = await api.client.updateBot({ id: createdBot.id, integrations }).catch((thrown) => {
236
+ const outfile = this._paths.abs.outFile;
237
+ const { default: botImpl } = requireutils.requireJsFile(outfile);
238
+ const integrations = this._prepareIntegrations(botImpl, bot);
239
+ const updateLine = this._logger.line();
240
+ updateLine.started("Updating bot integrations...");
241
+ const { bot: updatedBot } = await api.client.updateBot({ id: bot.id, integrations, url: externalUrl }).catch((thrown) => {
241
242
  throw errors.BotpressCLIError.wrap(thrown, "Could not deploy dev bot");
242
243
  });
243
- this._logger.success(`Dev Bot created with id "${updatedBot.id}"`);
244
+ updateLine.success("Integrations installed successfully");
244
245
  this._displayWebhookUrls(updatedBot);
245
- return {
246
- cleanup: () => api.client.deleteBot({ id: updatedBot.id }).then(() => {
247
- }).catch((thrown) => {
248
- throw errors.BotpressCLIError.wrap(thrown, "Could not delete dev bot");
249
- })
250
- };
251
246
  }
252
247
  async _deployIntegration(api, integrationDef) {
253
- const { abs } = this._paths;
254
- const outfile = consts.outfile(abs.outDir);
248
+ const outfile = this._paths.abs.outFile;
255
249
  const code = await import_fs.default.promises.readFile(outfile, "utf-8");
256
250
  const { name, version } = integrationDef;
257
251
  const integration = await api.findIntegration({ type: "name", name, version });
@@ -268,29 +262,62 @@ class ProjectCommands extends import_base.BaseCommands {
268
262
  return;
269
263
  }
270
264
  const line = this._logger.line();
271
- try {
272
- line.started(`Deploying integration ${import_chalk.default.bold(integrationDef.name)} v${integrationDef.version}...`);
273
- if (integration) {
274
- await api.client.updateIntegration({ id: integration.id, ...integrationDef, code });
275
- } else {
276
- await api.client.createIntegration({ ...integrationDef, code });
277
- }
278
- line.success("Integration deployed");
279
- } catch (thrown) {
280
- const action = integration ? "update" : "create";
281
- throw errors.BotpressCLIError.wrap(thrown, `Could not ${action} integration "${integrationDef.name}"`);
282
- } finally {
283
- line.commit();
265
+ line.started(`Deploying integration ${import_chalk.default.bold(integrationDef.name)} v${integrationDef.version}...`);
266
+ if (integration) {
267
+ await api.client.updateIntegration({ id: integration.id, ...integrationDef, code }).catch((thrown) => {
268
+ throw errors.BotpressCLIError.wrap(thrown, `Could not update integration "${integrationDef.name}"`);
269
+ });
270
+ } else {
271
+ await api.client.createIntegration({ ...integrationDef, code }).catch((thrown) => {
272
+ throw errors.BotpressCLIError.wrap(thrown, `Could not create integration "${integrationDef.name}"`);
273
+ });
284
274
  }
275
+ line.success("Integration deployed");
285
276
  }
286
- async _deployBot(api, botId) {
287
- const { abs } = this._paths;
288
- const outfile = consts.outfile(abs.outDir);
277
+ async _deployBot(api, argvBotId, argvCreateNew) {
278
+ const outfile = this._paths.abs.outFile;
289
279
  const code = await import_fs.default.promises.readFile(outfile, "utf-8");
290
280
  const { default: botImpl } = requireutils.requireJsFile(outfile);
291
- const { tags, states, integrations: integrationList } = botImpl;
281
+ const { tags, states, events, recurringEvents, configuration: botConfiguration } = botImpl;
282
+ let bot;
283
+ if (argvBotId && argvCreateNew) {
284
+ throw new errors.BotpressCLIError("Cannot specify both --botId and --createNew");
285
+ } else if (argvCreateNew) {
286
+ const confirm = await this._confirm("Are you sure you want to create a new bot ?");
287
+ if (!confirm) {
288
+ this._logger.log("Aborted");
289
+ return;
290
+ }
291
+ bot = await this._createNewBot(api);
292
+ } else {
293
+ bot = await this._getExistingBot(api, argvBotId);
294
+ const confirm = await this._confirm(`Are you sure you want to deploy the bot "${bot.name}"?`);
295
+ if (!confirm) {
296
+ this._logger.log("Aborted");
297
+ return;
298
+ }
299
+ }
300
+ const integrations = this._prepareIntegrations(botImpl, bot);
301
+ const line = this._logger.line();
302
+ line.started(`Deploying bot ${import_chalk.default.bold(bot.name)}...`);
303
+ const { bot: updatedBot } = await api.client.updateBot({
304
+ id: bot.id,
305
+ code,
306
+ states,
307
+ recurringEvents,
308
+ configuration: botConfiguration,
309
+ events,
310
+ tags,
311
+ integrations
312
+ }).catch((thrown) => {
313
+ throw errors.BotpressCLIError.wrap(thrown, `Could not update bot "${bot.name}"`);
314
+ });
315
+ line.success("Bot deployed");
316
+ this._displayWebhookUrls(updatedBot);
317
+ }
318
+ async _getExistingBot(api, botId) {
292
319
  const promptedBotId = await this._projectCache.sync("botId", botId, async (defaultId) => {
293
- const userBots = await api.listAllPages(api.client.listBots, "bots").catch((thrown) => {
320
+ const userBots = await api.listAllPages(api.client.listBots, (r) => r.bots).catch((thrown) => {
294
321
  throw errors.BotpressCLIError.wrap(thrown, "Could not fetch existing bots");
295
322
  });
296
323
  if (!userBots.length) {
@@ -309,34 +336,25 @@ class ProjectCommands extends import_base.BaseCommands {
309
336
  }
310
337
  return prompted;
311
338
  });
312
- const { bot: botInfo } = await api.client.getBot({ id: promptedBotId }).catch((thrown) => {
339
+ const { bot: fetchedBot } = await api.client.getBot({ id: promptedBotId }).catch((thrown) => {
313
340
  throw errors.BotpressCLIError.wrap(thrown, "Could not get bot info");
314
341
  });
342
+ return fetchedBot;
343
+ }
344
+ async _createNewBot(api) {
345
+ const line = this._logger.line();
346
+ const { bot: createdBot } = await api.client.createBot({}).catch((thrown) => {
347
+ throw errors.BotpressCLIError.wrap(thrown, "Could not create bot");
348
+ });
349
+ line.success(`Bot created with ID "${createdBot.id}" and name "${createdBot.name}"`);
350
+ await this._projectCache.set("botId", createdBot.id);
351
+ return createdBot;
352
+ }
353
+ _prepareIntegrations(botImpl, botInfo) {
354
+ const { integrations: integrationList } = botImpl;
315
355
  const integrationsToUninstall = (0, import_lodash.default)(botInfo.integrations).keys().filter((key) => !integrationList?.map((i) => i.id).includes(key)).zipObject().mapValues(() => null).value();
316
356
  const integrationsToInstall = (0, import_lodash.default)(integrationList ?? []).keyBy((i) => i.id).mapValues(({ enabled, configuration }) => ({ enabled, configuration })).value();
317
- const integrations = { ...integrationsToUninstall, ...integrationsToInstall };
318
- const confirm = await this._confirm(`Are you sure you want to deploy bot ${botInfo.name} ?`);
319
- if (!confirm) {
320
- this._logger.log("Aborted");
321
- return;
322
- }
323
- const line = this._logger.line();
324
- try {
325
- line.started(`Deploying bot ${import_chalk.default.bold(botInfo.name)}...`);
326
- const { bot: updatedBot } = await api.client.updateBot({
327
- id: promptedBotId,
328
- code,
329
- states,
330
- tags,
331
- integrations
332
- });
333
- line.success("Bot deployed");
334
- this._displayWebhookUrls(updatedBot);
335
- } catch (thrown) {
336
- throw errors.BotpressCLIError.wrap(thrown, "Could not update bot");
337
- } finally {
338
- line.commit();
339
- }
357
+ return { ...integrationsToUninstall, ...integrationsToInstall };
340
358
  }
341
359
  _displayWebhookUrls(bot) {
342
360
  if (!import_lodash.default.keys(bot.integrations).length) {
@@ -357,8 +375,7 @@ class ProjectCommands extends import_base.BaseCommands {
357
375
  }
358
376
  }
359
377
  async _listIntegrationInstances() {
360
- const { abs } = this._paths;
361
- const installPath = consts.installDir(abs.outDir);
378
+ const installPath = this._paths.abs.installDir;
362
379
  if (!import_fs.default.existsSync(installPath)) {
363
380
  this._logger.debug("Install path does not exist. Skipping listing of integration instances");
364
381
  return [];
@@ -383,70 +400,23 @@ class ProjectCommands extends import_base.BaseCommands {
383
400
  };
384
401
  });
385
402
  }
386
- async _confirm(message) {
387
- if (this._props.confirm) {
388
- this._logger.debug(`Confirming automatically: ${message}`);
389
- return true;
390
- }
391
- const { confirm } = await (0, import_prompts.default)({
392
- type: "confirm",
393
- name: "confirm",
394
- message,
395
- initial: false
396
- });
397
- if (!confirm) {
398
- return false;
399
- }
400
- return true;
401
- }
402
- async _generateImplementationTypings(integrationDef) {
403
- const line = this._logger.line();
404
- const { name } = integrationDef;
405
- line.started(`Generating typings for integration ${import_chalk.default.bold(name)}...`);
406
- const { rel } = this._paths;
407
- try {
408
- const typingFiles = await generator.generateIntegrationImplementationTypings(
409
- integrationDef,
410
- consts.relativeToOutFolder.implementationTypings
411
- );
412
- const indexFile = await generator.generateIntegrationIndex(consts.relativeToOutFolder.implementationTypings);
413
- const generatedFiles = [...typingFiles, indexFile];
414
- await this._writeFilesToOutFolder(generatedFiles);
415
- line.success(`Typings available at ${import_chalk.default.grey(rel.outDir)}`);
416
- } catch (thrown) {
417
- throw errors.BotpressCLIError.wrap(thrown, "Could not generate typings");
418
- } finally {
419
- line.commit();
420
- }
421
- }
422
403
  async _uninstallIntegration(instance) {
423
- const { abs } = this._paths;
424
- try {
425
- const instancePath = import_path.default.join(consts.installDir(abs.outDir), instance.dirname);
426
- await import_fs.default.promises.rm(instancePath, { recursive: true });
427
- await this._generateBotIndex();
428
- } catch (thrown) {
429
- throw errors.BotpressCLIError.wrap(thrown, "Could not uninstall integration");
430
- }
404
+ const installDir = this._paths.abs.installDir;
405
+ const instancePath = import_path.default.join(installDir, instance.dirname);
406
+ await import_fs.default.promises.rm(instancePath, { recursive: true });
407
+ await this._generateBotIndex();
431
408
  }
432
409
  async _generateIntegrationInstance(integration) {
433
410
  const line = this._logger.line();
434
411
  const { name, version } = integration;
435
412
  line.started(`Installing ${import_chalk.default.bold(name)} v${version}...`);
436
- const { rel } = this._paths;
437
- try {
438
- const instanceFiles = await generator.generateIntegrationInstance(
439
- integration,
440
- consts.relativeToOutFolder.installDir
441
- );
442
- await this._writeFilesToOutFolder(instanceFiles);
443
- await this._generateBotIndex();
444
- line.success(`Installed integration available at ${import_chalk.default.grey(rel.outDir)}`);
445
- } catch (thrown) {
446
- throw errors.BotpressCLIError.wrap(thrown, "Could not install integration");
447
- } finally {
448
- line.commit();
449
- }
413
+ const instanceFiles = await generator.generateIntegrationInstance(
414
+ integration,
415
+ consts.relativeToOutFolder.installDir
416
+ );
417
+ await this._writeFilesToOutFolder(instanceFiles);
418
+ await this._generateBotIndex();
419
+ line.success(`Installed integration available at ${import_chalk.default.grey(this._paths.rel.outDir)}`);
450
420
  }
451
421
  async _generateBotIndex() {
452
422
  const allInstances = await this._listIntegrationInstances();
@@ -457,9 +427,8 @@ class ProjectCommands extends import_base.BaseCommands {
457
427
  await this._writeFilesToOutFolder([indexFile]);
458
428
  }
459
429
  async _writeFilesToOutFolder(files) {
460
- const { abs } = this._paths;
461
430
  for (const file of files) {
462
- const filePath = pathutils.absoluteFrom(abs.outDir, file.path);
431
+ const filePath = pathutils.absoluteFrom(this._paths.abs.outDir, file.path);
463
432
  const dirPath = import_path.default.dirname(filePath);
464
433
  await import_fs.default.promises.mkdir(dirPath, { recursive: true });
465
434
  await import_fs.default.promises.writeFile(filePath, file.content);
@@ -471,7 +440,7 @@ class ProjectCommands extends import_base.BaseCommands {
471
440
  this._logger.debug(`Integration definition not found at ${rel.definition}`);
472
441
  return;
473
442
  }
474
- const { outputFiles } = await esbuild.buildEntrypoint({
443
+ const { outputFiles } = await esbuildutils.buildEntrypoint({
475
444
  cwd: abs.workDir,
476
445
  outfile: "",
477
446
  entrypoint: rel.definition,
@@ -484,19 +453,8 @@ class ProjectCommands extends import_base.BaseCommands {
484
453
  const { default: definition } = requireutils.requireJsCode(artifact.text);
485
454
  return definition;
486
455
  }
487
- async _ensureLoginAndCreateClient(argv) {
488
- const token = await this._userCache.get("token");
489
- const workspaceId = argv.workspaceId ?? await this._userCache.get("workspaceId");
490
- const host = argv.host ?? await this._userCache.get("host");
491
- if (!(token && workspaceId && host)) {
492
- throw new errors.NotLoggedInError();
493
- }
494
- const client = new bpclient.Client({ host, token, workspaceId });
495
- return new import_api_utils.ApiUtils(client, host, token, workspaceId, this._logger);
496
- }
497
456
  }
498
457
  // Annotate the CommonJS export names for ESM import in node:
499
458
  0 && (module.exports = {
500
- ProjectCommands,
501
- ProjectPaths
459
+ ProjectCommands
502
460
  });
package/dist/app/user.js CHANGED
@@ -36,9 +36,8 @@ var import_base = require("./base");
36
36
  var errors = __toESM(require("./errors"));
37
37
  var import_integration_ref = require("./integration-ref");
38
38
  class UserCommands extends import_base.BaseCommands {
39
- constructor(_props, _userCache, logger) {
40
- super(logger);
41
- this._userCache = _userCache;
39
+ constructor(props, userCache, logger) {
40
+ super(props, userCache, logger);
42
41
  }
43
42
  async login(argv) {
44
43
  const promptedToken = await this._userCache.sync("token", argv.token, async (previousToken) => {
@@ -106,7 +105,7 @@ class UserCommands extends import_base.BaseCommands {
106
105
  async listBots(argv) {
107
106
  const api = await this._ensureLoginAndCreateClient(argv);
108
107
  try {
109
- const bots = await api.listAllPages(api.client.listBots, "bots");
108
+ const bots = await api.listAllPages(api.client.listBots, (r) => r.bots);
110
109
  this._logger.success("Bots:");
111
110
  this._logger.json(bots);
112
111
  } catch (thrown) {
@@ -145,8 +144,8 @@ class UserCommands extends import_base.BaseCommands {
145
144
  const privateLister = (req) => api.client.listIntegrations({ nextToken: req.nextToken, name: argv.name, version: argv.version });
146
145
  const publicLister = (req) => api.client.listPublicIntegrations({ nextToken: req.nextToken, name: argv.name, version: argv.version });
147
146
  try {
148
- const privateIntegrations = await api.listAllPages(privateLister, "integrations");
149
- const publicIntegrations = await api.listAllPages(publicLister, "integrations");
147
+ const privateIntegrations = await api.listAllPages(privateLister, (r) => r.integrations);
148
+ const publicIntegrations = await api.listAllPages(publicLister, (r) => r.integrations);
150
149
  const integrations = import_lodash.default.uniqBy([...privateIntegrations, ...publicIntegrations], (i) => i.id);
151
150
  this._logger.success("Integrations:");
152
151
  this._logger.json(integrations);
@@ -181,16 +180,6 @@ class UserCommands extends import_base.BaseCommands {
181
180
  this._logger.success(`Integration ${import_chalk.default.bold(integrationRef)} deleted`);
182
181
  return;
183
182
  }
184
- async _ensureLoginAndCreateClient(argv) {
185
- const token = await this._userCache.get("token");
186
- const workspaceId = argv.workspaceId ?? await this._userCache.get("workspaceId");
187
- const host = argv.host ?? await this._userCache.get("host");
188
- if (!(token && workspaceId && host)) {
189
- throw new errors.NotLoggedInError();
190
- }
191
- const client = new bpclient.Client({ host, token, workspaceId });
192
- return new import_api_utils.ApiUtils(client, host, token, workspaceId, this._logger);
193
- }
194
183
  }
195
184
  // Annotate the CommonJS export names for ESM import in node:
196
185
  0 && (module.exports = {
package/dist/config.js CHANGED
@@ -47,7 +47,7 @@ __export(config_exports, {
47
47
  serveSchema: () => serveSchema
48
48
  });
49
49
  module.exports = __toCommonJS(config_exports);
50
- var consts = __toESM(require("./const"));
50
+ var consts = __toESM(require("./consts"));
51
51
  const botpressHome = {
52
52
  type: "string",
53
53
  description: "The path to the Botpress home directory",
@@ -97,7 +97,11 @@ const workDir = {
97
97
  };
98
98
  const botId = {
99
99
  type: "string",
100
- description: "The bot ID to deploy"
100
+ description: "The bot ID to deploy. Only used when deploying a bot"
101
+ };
102
+ const createNewBot = {
103
+ type: "boolean",
104
+ description: "Create a new bot when deploying. Only used when deploying a bot"
101
105
  };
102
106
  const url = {
103
107
  type: "string",
@@ -166,7 +170,8 @@ const deploySchema = {
166
170
  ...projectSchema,
167
171
  ...loggedInSchema,
168
172
  botId,
169
- noBuild
173
+ noBuild,
174
+ createNewBot
170
175
  };
171
176
  const devSchema = {
172
177
  ...projectSchema,