@botpress/cli 0.0.4 → 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.
- package/dist/app/api-utils.js +5 -4
- package/dist/app/base.js +39 -1
- package/dist/app/errors.js +18 -19
- package/dist/app/file-paths.js +82 -0
- package/dist/app/generator/module.js +1 -1
- package/dist/app/index.js +15 -10
- package/dist/app/project.js +198 -240
- package/dist/app/user.js +5 -16
- package/dist/config.js +8 -3
- package/dist/{const.js → consts.js} +12 -34
- package/dist/{app/esbuild.js → esbuild-utils.js} +3 -3
- package/dist/index.js +1 -1
- package/dist/logger/index.js +5 -5
- package/dist/{paths.js → path-utils.js} +3 -3
- package/dist/{requires.js → require-utils.js} +3 -3
- package/dist/worker/child-entrypoint.js +4 -2
- package/package.json +1 -1
- package/readme.md +0 -1
- package/dist/index.js.map +0 -7
- package/dist/init.js.map +0 -7
- package/dist/type-utils.js +0 -16
package/dist/app/project.js
CHANGED
|
@@ -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("../
|
|
39
|
-
var
|
|
40
|
-
var
|
|
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(
|
|
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.
|
|
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
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
|
158
|
-
if (!
|
|
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
|
-
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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,
|
|
230
|
+
throw errors.BotpressCLIError.wrap(thrown, "Could not deploy dev bot");
|
|
218
231
|
});
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
|
228
|
-
const
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const { bot:
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
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,
|
|
287
|
-
const
|
|
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,
|
|
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,
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
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
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
|
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(
|
|
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,
|
|
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,
|
|
149
|
-
const publicIntegrations = await api.listAllPages(publicLister,
|
|
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("./
|
|
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,
|