@botpress/cli 0.2.4 → 0.2.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/api/bot-body.js +54 -0
- package/dist/api/bot-body.js.map +7 -0
- package/dist/{api-client.js → api/client.js} +9 -9
- package/dist/api/client.js.map +7 -0
- package/dist/api/integration-body.js +81 -0
- package/dist/api/integration-body.js.map +7 -0
- package/dist/command-implementations/deploy-command.js +29 -69
- package/dist/command-implementations/deploy-command.js.map +3 -3
- package/dist/command-implementations/dev-command.js +19 -8
- package/dist/command-implementations/dev-command.js.map +3 -3
- package/dist/command-implementations/global-command.js.map +1 -1
- package/dist/command-implementations/index.js +2 -2
- package/dist/command-implementations/index.js.map +2 -2
- package/dist/command-implementations/project-command.js +0 -6
- package/dist/command-implementations/project-command.js.map +2 -2
- package/dist/utils/record-utils.js +13 -3
- package/dist/utils/record-utils.js.map +2 -2
- package/dist/utils/record-utils.test.js +34 -0
- package/dist/utils/record-utils.test.js.map +7 -0
- package/package.json +3 -3
- package/templates/echo-bot/package.json +2 -2
- package/templates/empty-integration/package.json +2 -2
- package/dist/api-client.js.map +0 -7
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
|
+
var bot_body_exports = {};
|
|
26
|
+
__export(bot_body_exports, {
|
|
27
|
+
prepareUpdateBotBody: () => prepareUpdateBotBody
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(bot_body_exports);
|
|
30
|
+
var utils = __toESM(require("../utils"));
|
|
31
|
+
const prepareUpdateBotBody = (localBot, remoteBot) => ({
|
|
32
|
+
...localBot,
|
|
33
|
+
states: utils.records.setNullOnMissingValues(localBot.states, remoteBot.states),
|
|
34
|
+
recurringEvents: utils.records.setNullOnMissingValues(localBot.recurringEvents, remoteBot.recurringEvents),
|
|
35
|
+
events: utils.records.setNullOnMissingValues(localBot.events, remoteBot.events),
|
|
36
|
+
user: {
|
|
37
|
+
...localBot.user,
|
|
38
|
+
tags: utils.records.setNullOnMissingValues(localBot.user?.tags, remoteBot.user?.tags)
|
|
39
|
+
},
|
|
40
|
+
conversation: {
|
|
41
|
+
...localBot.conversation,
|
|
42
|
+
tags: utils.records.setNullOnMissingValues(localBot.conversation?.tags, remoteBot.conversation?.tags)
|
|
43
|
+
},
|
|
44
|
+
message: {
|
|
45
|
+
...localBot.message,
|
|
46
|
+
tags: utils.records.setNullOnMissingValues(localBot.message?.tags, remoteBot.message?.tags)
|
|
47
|
+
},
|
|
48
|
+
integrations: utils.records.setNullOnMissingValues(localBot.integrations, remoteBot.integrations)
|
|
49
|
+
});
|
|
50
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
51
|
+
0 && (module.exports = {
|
|
52
|
+
prepareUpdateBotBody
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=bot-body.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/api/bot-body.ts"],
|
|
4
|
+
"sourcesContent": ["import type * as bpclient from '@botpress/client'\nimport * as utils from '../utils'\n\nexport type CreateBotBody = Parameters<bpclient.Client['createBot']>[0]\nexport type UpdateBotBody = Parameters<bpclient.Client['updateBot']>[0]\n\nexport const prepareUpdateBotBody = (localBot: UpdateBotBody, remoteBot: bpclient.Bot): UpdateBotBody => ({\n ...localBot,\n states: utils.records.setNullOnMissingValues(localBot.states, remoteBot.states),\n recurringEvents: utils.records.setNullOnMissingValues(localBot.recurringEvents, remoteBot.recurringEvents),\n events: utils.records.setNullOnMissingValues(localBot.events, remoteBot.events),\n user: {\n ...localBot.user,\n tags: utils.records.setNullOnMissingValues(localBot.user?.tags, remoteBot.user?.tags),\n },\n conversation: {\n ...localBot.conversation,\n tags: utils.records.setNullOnMissingValues(localBot.conversation?.tags, remoteBot.conversation?.tags),\n },\n message: {\n ...localBot.message,\n tags: utils.records.setNullOnMissingValues(localBot.message?.tags, remoteBot.message?.tags),\n },\n integrations: utils.records.setNullOnMissingValues(localBot.integrations, remoteBot.integrations),\n})\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAKhB,MAAM,uBAAuB,CAAC,UAAyB,eAA4C;AAAA,EACxG,GAAG;AAAA,EACH,QAAQ,MAAM,QAAQ,uBAAuB,SAAS,QAAQ,UAAU,MAAM;AAAA,EAC9E,iBAAiB,MAAM,QAAQ,uBAAuB,SAAS,iBAAiB,UAAU,eAAe;AAAA,EACzG,QAAQ,MAAM,QAAQ,uBAAuB,SAAS,QAAQ,UAAU,MAAM;AAAA,EAC9E,MAAM;AAAA,IACJ,GAAG,SAAS;AAAA,IACZ,MAAM,MAAM,QAAQ,uBAAuB,SAAS,MAAM,MAAM,UAAU,MAAM,IAAI;AAAA,EACtF;AAAA,EACA,cAAc;AAAA,IACZ,GAAG,SAAS;AAAA,IACZ,MAAM,MAAM,QAAQ,uBAAuB,SAAS,cAAc,MAAM,UAAU,cAAc,IAAI;AAAA,EACtG;AAAA,EACA,SAAS;AAAA,IACP,GAAG,SAAS;AAAA,IACZ,MAAM,MAAM,QAAQ,uBAAuB,SAAS,SAAS,MAAM,UAAU,SAAS,IAAI;AAAA,EAC5F;AAAA,EACA,cAAc,MAAM,QAAQ,uBAAuB,SAAS,cAAc,UAAU,YAAY;AAClG;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -22,14 +22,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
|
-
var
|
|
26
|
-
__export(
|
|
25
|
+
var client_exports = {};
|
|
26
|
+
__export(client_exports, {
|
|
27
27
|
ApiClient: () => ApiClient
|
|
28
28
|
});
|
|
29
|
-
module.exports = __toCommonJS(
|
|
29
|
+
module.exports = __toCommonJS(client_exports);
|
|
30
30
|
var import_client = require("@botpress/client");
|
|
31
31
|
var import_lodash = __toESM(require("lodash"));
|
|
32
|
-
var import_integration_ref = require("
|
|
32
|
+
var import_integration_ref = require("../integration-ref");
|
|
33
33
|
class ApiClient {
|
|
34
34
|
constructor(props, _logger) {
|
|
35
35
|
this._logger = _logger;
|
|
@@ -60,15 +60,15 @@ class ApiClient {
|
|
|
60
60
|
}
|
|
61
61
|
async findPrivateIntegration(ref) {
|
|
62
62
|
if (ref.type === "id") {
|
|
63
|
-
return this.validateStatus(() => this.client.getIntegration(ref).then((r) => r.integration),
|
|
63
|
+
return this.validateStatus(() => this.client.getIntegration(ref).then((r) => r.integration), 404);
|
|
64
64
|
}
|
|
65
|
-
return this.validateStatus(() => this.client.getIntegrationByName(ref).then((r) => r.integration),
|
|
65
|
+
return this.validateStatus(() => this.client.getIntegrationByName(ref).then((r) => r.integration), 404);
|
|
66
66
|
}
|
|
67
67
|
async findPublicIntegration(ref) {
|
|
68
68
|
if (ref.type === "id") {
|
|
69
|
-
return this.validateStatus(() => this.client.getPublicIntegrationById(ref).then((r) => r.integration),
|
|
69
|
+
return this.validateStatus(() => this.client.getPublicIntegrationById(ref).then((r) => r.integration), 404);
|
|
70
70
|
}
|
|
71
|
-
return this.validateStatus(() => this.client.getPublicIntegration(ref).then((r) => r.integration),
|
|
71
|
+
return this.validateStatus(() => this.client.getPublicIntegration(ref).then((r) => r.integration), 404);
|
|
72
72
|
}
|
|
73
73
|
async testLogin() {
|
|
74
74
|
await this.client.listBots({});
|
|
@@ -105,4 +105,4 @@ class ApiClient {
|
|
|
105
105
|
0 && (module.exports = {
|
|
106
106
|
ApiClient
|
|
107
107
|
});
|
|
108
|
-
//# sourceMappingURL=
|
|
108
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/api/client.ts"],
|
|
4
|
+
"sourcesContent": ["import { Client, Integration, isApiError } from '@botpress/client'\nimport _ from 'lodash'\nimport { formatIntegrationRef, IntegrationRef } from '../integration-ref'\nimport type { Logger } from '../logger'\n\nexport type PageLister<R extends object> = (t: { nextToken?: string }) => Promise<R & { meta: { nextToken?: string } }>\n\nexport type ApiClientProps = {\n apiUrl: string\n token: string\n workspaceId?: string\n}\n\nexport type ApiClientFactory = {\n newClient: (props: ApiClientProps, logger: Logger) => ApiClient\n}\n\n/**\n * This class is used to wrap the Botpress API and provide a more convenient way to interact with it.\n */\nexport class ApiClient {\n public readonly client: Client\n public readonly url: string\n public readonly token: string\n public readonly workspaceId?: string\n\n public static newClient = (props: ApiClientProps, logger: Logger) => new ApiClient(props, logger)\n\n public constructor(props: ApiClientProps, private _logger: Logger) {\n const { apiUrl, token, workspaceId } = props\n this.client = new Client({ host: apiUrl, token, workspaceId })\n this.url = apiUrl\n this.token = token\n this.workspaceId = workspaceId\n }\n\n public async findIntegration(ref: IntegrationRef): Promise<Integration | undefined> {\n const formatted = formatIntegrationRef(ref)\n\n const privateIntegration = await this.findPrivateIntegration(ref)\n if (privateIntegration) {\n this._logger.debug(`Found integration \"${formatted}\" in workspace`)\n return privateIntegration\n }\n\n const publicIntegration = await this.findPublicIntegration(ref)\n if (publicIntegration) {\n this._logger.debug(`Found integration \"${formatted}\" in hub`)\n return publicIntegration\n }\n\n return\n }\n\n public async findPrivateIntegration(ref: IntegrationRef): Promise<Integration | undefined> {\n if (ref.type === 'id') {\n return this.validateStatus(() => this.client.getIntegration(ref).then((r) => r.integration), 404)\n }\n return this.validateStatus(() => this.client.getIntegrationByName(ref).then((r) => r.integration), 404)\n }\n\n public async findPublicIntegration(ref: IntegrationRef): Promise<Integration | undefined> {\n if (ref.type === 'id') {\n return this.validateStatus(() => this.client.getPublicIntegrationById(ref).then((r) => r.integration), 404)\n }\n return this.validateStatus(() => this.client.getPublicIntegration(ref).then((r) => r.integration), 404)\n }\n\n public async testLogin(): Promise<void> {\n await this.client.listBots({})\n }\n\n public async listAllPages<R extends object>(lister: PageLister<R>): Promise<R[]>\n public async listAllPages<R extends object, M>(lister: PageLister<R>, mapper?: (r: R) => M[]): Promise<M[]>\n public async listAllPages<R extends object, M>(lister: PageLister<R>, mapper?: (r: R) => M[]) {\n let nextToken: string | undefined\n const all: R[] = []\n\n do {\n const { meta, ...r } = await lister({ nextToken })\n all.push(r as R)\n nextToken = meta.nextToken\n } while (nextToken)\n\n if (!mapper) {\n return all\n }\n\n const mapped: M[] = all.flatMap((r) => mapper(r))\n return mapped\n }\n\n public async validateStatus<V>(fn: () => Promise<V>, allowedStatuses: number | number[]): Promise<V | undefined> {\n try {\n const v = await fn()\n return v\n } catch (err) {\n const allowedStatusesArray = _.isArray(allowedStatuses) ? allowedStatuses : [allowedStatuses]\n const isAllowed = isApiError(err) && err.code && allowedStatusesArray.includes(err.code)\n if (isAllowed) {\n return\n }\n throw err\n }\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAgD;AAChD,oBAAc;AACd,6BAAqD;AAkB9C,MAAM,UAAU;AAAA,EAQd,YAAY,OAA+B,SAAiB;AAAjB;AAChD,UAAM,EAAE,QAAQ,OAAO,YAAY,IAAI;AACvC,SAAK,SAAS,IAAI,qBAAO,EAAE,MAAM,QAAQ,OAAO,YAAY,CAAC;AAC7D,SAAK,MAAM;AACX,SAAK,QAAQ;AACb,SAAK,cAAc;AAAA,EACrB;AAAA,EAbgB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,OAAc,YAAY,CAAC,OAAuB,WAAmB,IAAI,UAAU,OAAO,MAAM;AAAA,EAUhG,MAAa,gBAAgB,KAAuD;AAClF,UAAM,gBAAY,6CAAqB,GAAG;AAE1C,UAAM,qBAAqB,MAAM,KAAK,uBAAuB,GAAG;AAChE,QAAI,oBAAoB;AACtB,WAAK,QAAQ,MAAM,sBAAsB,yBAAyB;AAClE,aAAO;AAAA,IACT;AAEA,UAAM,oBAAoB,MAAM,KAAK,sBAAsB,GAAG;AAC9D,QAAI,mBAAmB;AACrB,WAAK,QAAQ,MAAM,sBAAsB,mBAAmB;AAC5D,aAAO;AAAA,IACT;AAEA;AAAA,EACF;AAAA,EAEA,MAAa,uBAAuB,KAAuD;AACzF,QAAI,IAAI,SAAS,MAAM;AACrB,aAAO,KAAK,eAAe,MAAM,KAAK,OAAO,eAAe,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG;AAAA,IAClG;AACA,WAAO,KAAK,eAAe,MAAM,KAAK,OAAO,qBAAqB,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG;AAAA,EACxG;AAAA,EAEA,MAAa,sBAAsB,KAAuD;AACxF,QAAI,IAAI,SAAS,MAAM;AACrB,aAAO,KAAK,eAAe,MAAM,KAAK,OAAO,yBAAyB,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG;AAAA,IAC5G;AACA,WAAO,KAAK,eAAe,MAAM,KAAK,OAAO,qBAAqB,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG;AAAA,EACxG;AAAA,EAEA,MAAa,YAA2B;AACtC,UAAM,KAAK,OAAO,SAAS,CAAC,CAAC;AAAA,EAC/B;AAAA,EAIA,MAAa,aAAkC,QAAuB,QAAwB;AAC5F,QAAI;AACJ,UAAM,MAAW,CAAC;AAElB,OAAG;AACD,YAAM,EAAE,SAAS,EAAE,IAAI,MAAM,OAAO,EAAE,UAAU,CAAC;AACjD,UAAI,KAAK,CAAM;AACf,kBAAY,KAAK;AAAA,IACnB,SAAS;AAET,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,UAAM,SAAc,IAAI,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC;AAChD,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,eAAkB,IAAsB,iBAA4D;AAC/G,QAAI;AACF,YAAM,IAAI,MAAM,GAAG;AACnB,aAAO;AAAA,IACT,SAAS,KAAP;AACA,YAAM,uBAAuB,cAAAA,QAAE,QAAQ,eAAe,IAAI,kBAAkB,CAAC,eAAe;AAC5F,YAAM,gBAAY,0BAAW,GAAG,KAAK,IAAI,QAAQ,qBAAqB,SAAS,IAAI,IAAI;AACvF,UAAI,WAAW;AACb;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;",
|
|
6
|
+
"names": ["_"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
|
+
var integration_body_exports = {};
|
|
26
|
+
__export(integration_body_exports, {
|
|
27
|
+
prepareUpdateIntegrationBody: () => prepareUpdateIntegrationBody
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(integration_body_exports);
|
|
30
|
+
var utils = __toESM(require("../utils"));
|
|
31
|
+
const prepareUpdateIntegrationBody = (localIntegration, remoteIntegration) => {
|
|
32
|
+
const actions = utils.records.setNullOnMissingValues(localIntegration.actions, remoteIntegration.actions);
|
|
33
|
+
const events = utils.records.setNullOnMissingValues(localIntegration.events, remoteIntegration.events);
|
|
34
|
+
const states = utils.records.setNullOnMissingValues(localIntegration.states, remoteIntegration.states);
|
|
35
|
+
const user = {
|
|
36
|
+
...localIntegration.user,
|
|
37
|
+
tags: utils.records.setNullOnMissingValues(localIntegration.user?.tags, remoteIntegration.user?.tags)
|
|
38
|
+
};
|
|
39
|
+
const channels = prepareUpdateIntegrationChannelsBody(localIntegration.channels ?? {}, remoteIntegration.channels);
|
|
40
|
+
return {
|
|
41
|
+
...localIntegration,
|
|
42
|
+
actions,
|
|
43
|
+
events,
|
|
44
|
+
states,
|
|
45
|
+
user,
|
|
46
|
+
channels
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const prepareUpdateIntegrationChannelsBody = (localChannels, remoteChannels) => {
|
|
50
|
+
const channelBody = {};
|
|
51
|
+
const zipped = utils.records.zipObjects(localChannels, remoteChannels);
|
|
52
|
+
for (const [channelName, [localChannel, remoteChannel]] of Object.entries(zipped)) {
|
|
53
|
+
if (localChannel && remoteChannel) {
|
|
54
|
+
channelBody[channelName] = prepareUpdateIntegrationChannelBody(localChannel, remoteChannel);
|
|
55
|
+
} else if (localChannel) {
|
|
56
|
+
channelBody[channelName] = localChannel;
|
|
57
|
+
continue;
|
|
58
|
+
} else if (remoteChannel) {
|
|
59
|
+
channelBody[channelName] = null;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return channelBody;
|
|
64
|
+
};
|
|
65
|
+
const prepareUpdateIntegrationChannelBody = (localChannel, remoteChannel) => ({
|
|
66
|
+
...localChannel,
|
|
67
|
+
messages: utils.records.setNullOnMissingValues(localChannel?.messages, remoteChannel.messages),
|
|
68
|
+
message: {
|
|
69
|
+
...localChannel?.message,
|
|
70
|
+
tags: utils.records.setNullOnMissingValues(localChannel?.message?.tags, remoteChannel.message.tags)
|
|
71
|
+
},
|
|
72
|
+
conversation: {
|
|
73
|
+
...localChannel?.conversation,
|
|
74
|
+
tags: utils.records.setNullOnMissingValues(localChannel?.conversation?.tags, remoteChannel.conversation.tags)
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
78
|
+
0 && (module.exports = {
|
|
79
|
+
prepareUpdateIntegrationBody
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=integration-body.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/api/integration-body.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Client, Integration } from '@botpress/client'\nimport * as utils from '../utils'\n\nexport type CreateIntegrationBody = Parameters<Client['createIntegration']>[0]\nexport type UpdateIntegrationBody = Parameters<Client['updateIntegration']>[0]\n\ntype UpdateIntegrationChannelsBody = NonNullable<UpdateIntegrationBody['channels']>\ntype UpdateIntegrationChannelBody = UpdateIntegrationChannelsBody[string]\n\ntype Channels = Integration['channels']\ntype Channel = Integration['channels'][string]\n\nexport const prepareUpdateIntegrationBody = (\n localIntegration: UpdateIntegrationBody,\n remoteIntegration: Integration\n): UpdateIntegrationBody => {\n const actions = utils.records.setNullOnMissingValues(localIntegration.actions, remoteIntegration.actions)\n const events = utils.records.setNullOnMissingValues(localIntegration.events, remoteIntegration.events)\n const states = utils.records.setNullOnMissingValues(localIntegration.states, remoteIntegration.states)\n const user = {\n ...localIntegration.user,\n tags: utils.records.setNullOnMissingValues(localIntegration.user?.tags, remoteIntegration.user?.tags),\n }\n\n const channels = prepareUpdateIntegrationChannelsBody(localIntegration.channels ?? {}, remoteIntegration.channels)\n\n return {\n ...localIntegration,\n actions,\n events,\n states,\n user,\n channels,\n }\n}\n\nconst prepareUpdateIntegrationChannelsBody = (\n localChannels: UpdateIntegrationChannelsBody,\n remoteChannels: Channels\n): UpdateIntegrationChannelsBody => {\n const channelBody: UpdateIntegrationChannelsBody = {}\n\n const zipped = utils.records.zipObjects(localChannels, remoteChannels)\n for (const [channelName, [localChannel, remoteChannel]] of Object.entries(zipped)) {\n if (localChannel && remoteChannel) {\n // channel has to be updated\n channelBody[channelName] = prepareUpdateIntegrationChannelBody(localChannel, remoteChannel)\n } else if (localChannel) {\n // channel has to be created\n channelBody[channelName] = localChannel\n continue\n } else if (remoteChannel) {\n // channel has to be deleted\n channelBody[channelName] = null\n continue\n }\n }\n\n return channelBody\n}\n\nconst prepareUpdateIntegrationChannelBody = (\n localChannel: UpdateIntegrationChannelBody,\n remoteChannel: Channel\n): UpdateIntegrationChannelBody => ({\n ...localChannel,\n messages: utils.records.setNullOnMissingValues(localChannel?.messages, remoteChannel.messages),\n message: {\n ...localChannel?.message,\n tags: utils.records.setNullOnMissingValues(localChannel?.message?.tags, remoteChannel.message.tags),\n },\n conversation: {\n ...localChannel?.conversation,\n tags: utils.records.setNullOnMissingValues(localChannel?.conversation?.tags, remoteChannel.conversation.tags),\n },\n})\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAWhB,MAAM,+BAA+B,CAC1C,kBACA,sBAC0B;AAC1B,QAAM,UAAU,MAAM,QAAQ,uBAAuB,iBAAiB,SAAS,kBAAkB,OAAO;AACxG,QAAM,SAAS,MAAM,QAAQ,uBAAuB,iBAAiB,QAAQ,kBAAkB,MAAM;AACrG,QAAM,SAAS,MAAM,QAAQ,uBAAuB,iBAAiB,QAAQ,kBAAkB,MAAM;AACrG,QAAM,OAAO;AAAA,IACX,GAAG,iBAAiB;AAAA,IACpB,MAAM,MAAM,QAAQ,uBAAuB,iBAAiB,MAAM,MAAM,kBAAkB,MAAM,IAAI;AAAA,EACtG;AAEA,QAAM,WAAW,qCAAqC,iBAAiB,YAAY,CAAC,GAAG,kBAAkB,QAAQ;AAEjH,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,MAAM,uCAAuC,CAC3C,eACA,mBACkC;AAClC,QAAM,cAA6C,CAAC;AAEpD,QAAM,SAAS,MAAM,QAAQ,WAAW,eAAe,cAAc;AACrE,aAAW,CAAC,aAAa,CAAC,cAAc,aAAa,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjF,QAAI,gBAAgB,eAAe;AAEjC,kBAAY,eAAe,oCAAoC,cAAc,aAAa;AAAA,IAC5F,WAAW,cAAc;AAEvB,kBAAY,eAAe;AAC3B;AAAA,IACF,WAAW,eAAe;AAExB,kBAAY,eAAe;AAC3B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,MAAM,sCAAsC,CAC1C,cACA,mBACkC;AAAA,EAClC,GAAG;AAAA,EACH,UAAU,MAAM,QAAQ,uBAAuB,cAAc,UAAU,cAAc,QAAQ;AAAA,EAC7F,SAAS;AAAA,IACP,GAAG,cAAc;AAAA,IACjB,MAAM,MAAM,QAAQ,uBAAuB,cAAc,SAAS,MAAM,cAAc,QAAQ,IAAI;AAAA,EACpG;AAAA,EACA,cAAc;AAAA,IACZ,GAAG,cAAc;AAAA,IACjB,MAAM,MAAM,QAAQ,uBAAuB,cAAc,cAAc,MAAM,cAAc,aAAa,IAAI;AAAA,EAC9G;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -29,6 +29,9 @@ __export(deploy_command_exports, {
|
|
|
29
29
|
module.exports = __toCommonJS(deploy_command_exports);
|
|
30
30
|
var import_chalk = __toESM(require("chalk"));
|
|
31
31
|
var fs = __toESM(require("fs"));
|
|
32
|
+
var import_lodash = __toESM(require("lodash"));
|
|
33
|
+
var import_bot_body = require("../api/bot-body");
|
|
34
|
+
var import_integration_body = require("../api/integration-body");
|
|
32
35
|
var consts = __toESM(require("../consts"));
|
|
33
36
|
var errors = __toESM(require("../errors"));
|
|
34
37
|
var utils = __toESM(require("../utils"));
|
|
@@ -75,7 +78,7 @@ class DeployCommand extends import_project_command.ProjectCommand {
|
|
|
75
78
|
this.logger.log("Aborted");
|
|
76
79
|
return;
|
|
77
80
|
}
|
|
78
|
-
const
|
|
81
|
+
const createBody = {
|
|
79
82
|
...integrationDef,
|
|
80
83
|
icon: iconFileContent,
|
|
81
84
|
readme: readmeFileContent,
|
|
@@ -84,51 +87,23 @@ class DeployCommand extends import_project_command.ProjectCommand {
|
|
|
84
87
|
const line = this.logger.line();
|
|
85
88
|
line.started(`Deploying integration ${import_chalk.default.bold(integrationDef.name)} v${integrationDef.version}...`);
|
|
86
89
|
if (integration) {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
const updateBody = (0, import_integration_body.prepareUpdateIntegrationBody)(
|
|
91
|
+
{
|
|
92
|
+
id: integration.id,
|
|
93
|
+
...createBody
|
|
94
|
+
},
|
|
95
|
+
integration
|
|
96
|
+
);
|
|
97
|
+
await api.client.updateIntegration(updateBody).catch((thrown) => {
|
|
92
98
|
throw errors.BotpressCLIError.wrap(thrown, `Could not update integration "${integrationDef.name}"`);
|
|
93
99
|
});
|
|
94
100
|
} else {
|
|
95
|
-
await api.client.createIntegration(
|
|
101
|
+
await api.client.createIntegration(createBody).catch((thrown) => {
|
|
96
102
|
throw errors.BotpressCLIError.wrap(thrown, `Could not create integration "${integrationDef.name}"`);
|
|
97
103
|
});
|
|
98
104
|
}
|
|
99
105
|
line.success("Integration deployed");
|
|
100
106
|
}
|
|
101
|
-
_prepareUpdateIntegrationBody = (integration, body) => ({
|
|
102
|
-
...body,
|
|
103
|
-
actions: utils.records.setOnNullMissingValues(body.actions, integration.actions),
|
|
104
|
-
events: utils.records.setOnNullMissingValues(body.events, integration.events),
|
|
105
|
-
states: utils.records.setOnNullMissingValues(body.states, integration.states),
|
|
106
|
-
user: {
|
|
107
|
-
...body.user,
|
|
108
|
-
tags: utils.records.setOnNullMissingValues(body.user?.tags, integration.user?.tags)
|
|
109
|
-
},
|
|
110
|
-
channels: Object.entries(body.channels ?? {}).reduce((acc, [channelName, channelDef]) => {
|
|
111
|
-
const currentChannel = integration.channels[channelName];
|
|
112
|
-
return {
|
|
113
|
-
...acc,
|
|
114
|
-
[channelName]: {
|
|
115
|
-
...channelDef,
|
|
116
|
-
messages: utils.records.setOnNullMissingValues(channelDef?.messages, currentChannel?.messages),
|
|
117
|
-
message: {
|
|
118
|
-
...channelDef?.message,
|
|
119
|
-
tags: utils.records.setOnNullMissingValues(channelDef?.message?.tags, currentChannel?.message.tags)
|
|
120
|
-
},
|
|
121
|
-
conversation: {
|
|
122
|
-
...channelDef?.conversation,
|
|
123
|
-
tags: utils.records.setOnNullMissingValues(
|
|
124
|
-
channelDef?.conversation?.tags,
|
|
125
|
-
currentChannel?.conversation.tags
|
|
126
|
-
)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
}, {})
|
|
131
|
-
});
|
|
132
107
|
_readMediaFile = async (filePurpose, filePath) => {
|
|
133
108
|
if (!filePath) {
|
|
134
109
|
return void 0;
|
|
@@ -169,45 +144,30 @@ class DeployCommand extends import_project_command.ProjectCommand {
|
|
|
169
144
|
return;
|
|
170
145
|
}
|
|
171
146
|
}
|
|
172
|
-
const integrations = this.prepareIntegrations(botImpl, bot);
|
|
173
147
|
const line = this.logger.line();
|
|
174
148
|
line.started(`Deploying bot ${import_chalk.default.bold(bot.name)}...`);
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
149
|
+
const integrations = (0, import_lodash.default)(botImpl.definition.integrations ?? []).keyBy((i) => i.id).mapValues(({ enabled, configuration }) => ({ enabled, configuration })).value();
|
|
150
|
+
const updateBotBody = (0, import_bot_body.prepareUpdateBotBody)(
|
|
151
|
+
{
|
|
152
|
+
id: bot.id,
|
|
153
|
+
code,
|
|
154
|
+
states,
|
|
155
|
+
recurringEvents,
|
|
156
|
+
configuration: botConfiguration,
|
|
157
|
+
events,
|
|
158
|
+
user,
|
|
159
|
+
conversation,
|
|
160
|
+
message,
|
|
161
|
+
integrations
|
|
162
|
+
},
|
|
163
|
+
bot
|
|
164
|
+
);
|
|
187
165
|
const { bot: updatedBot } = await api.client.updateBot(updateBotBody).catch((thrown) => {
|
|
188
166
|
throw errors.BotpressCLIError.wrap(thrown, `Could not update bot "${bot.name}"`);
|
|
189
167
|
});
|
|
190
168
|
line.success("Bot deployed");
|
|
191
169
|
this.displayWebhookUrls(updatedBot);
|
|
192
170
|
}
|
|
193
|
-
_prepareUpdateBotBody = (bot, body) => ({
|
|
194
|
-
...body,
|
|
195
|
-
states: utils.records.setOnNullMissingValues(body.states, bot.states),
|
|
196
|
-
recurringEvents: utils.records.setOnNullMissingValues(body.recurringEvents, bot.recurringEvents),
|
|
197
|
-
events: utils.records.setOnNullMissingValues(body.events, bot.events),
|
|
198
|
-
user: {
|
|
199
|
-
...body.user,
|
|
200
|
-
tags: utils.records.setOnNullMissingValues(body.user?.tags, bot.user?.tags)
|
|
201
|
-
},
|
|
202
|
-
conversation: {
|
|
203
|
-
...body.conversation,
|
|
204
|
-
tags: utils.records.setOnNullMissingValues(body.conversation?.tags, bot.conversation?.tags)
|
|
205
|
-
},
|
|
206
|
-
message: {
|
|
207
|
-
...body.message,
|
|
208
|
-
tags: utils.records.setOnNullMissingValues(body.message?.tags, bot.message?.tags)
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
171
|
async _createNewBot(api) {
|
|
212
172
|
const line = this.logger.line();
|
|
213
173
|
const { bot: createdBot } = await api.client.createBot({}).catch((thrown) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/command-implementations/deploy-command.ts"],
|
|
4
|
-
"sourcesContent": ["import type * as bpclient from '@botpress/client'\nimport type { Bot as BotImpl, IntegrationDefinition } from '@botpress/sdk'\nimport chalk from 'chalk'\nimport * as fs from 'fs'\nimport type { ApiClient } from 'src/api-client'\nimport type commandDefinitions from '../command-definitions'\nimport * as consts from '../consts'\nimport * as errors from '../errors'\nimport * as utils from '../utils'\nimport { BuildCommand } from './build-command'\nimport { ProjectCommand } from './project-command'\n\ntype CreateIntegrationBody = Parameters<bpclient.Client['createIntegration']>[0]\ntype UpdateIntegrationBody = Parameters<bpclient.Client['updateIntegration']>[0]\ntype UpdateBotBody = Parameters<bpclient.Client['updateBot']>[0]\n\nexport type DeployCommandDefinition = typeof commandDefinitions.deploy\nexport class DeployCommand extends ProjectCommand<DeployCommandDefinition> {\n public async run(): Promise<void> {\n const api = await this.ensureLoginAndCreateClient(this.argv)\n if (api.url !== consts.defaultBotpressApiUrl) {\n this.logger.log(`Using custom url ${api.url}`)\n }\n\n if (!this.argv.noBuild) {\n await this._runBuild() // This ensures the bundle is always synced with source code\n }\n\n const integrationDef = await this.readIntegrationDefinitionFromFS()\n if (integrationDef) {\n return this._deployIntegration(api, integrationDef)\n }\n return this._deployBot(api, this.argv.botId, this.argv.createNewBot)\n }\n\n private async _runBuild() {\n return new BuildCommand(this.api, this.prompt, this.logger, this.argv).run()\n }\n\n private async _deployIntegration(api: ApiClient, integrationDef: IntegrationDefinition) {\n const outfile = this.projectPaths.abs.outFile\n let code = await fs.promises.readFile(outfile, 'utf-8')\n\n const secrets = await this.promptSecrets(integrationDef, this.argv)\n // TODO: provide these secrets to the backend by API and remove this string replacement hack\n for (const [secretName, secretValue] of Object.entries(secrets)) {\n code = code.replace(new RegExp(`process\\\\.env\\\\.${secretName}`, 'g'), `\"${secretValue}\"`)\n }\n\n const { name, version, icon: iconRelativeFilePath, readme: readmeRelativeFilePath } = integrationDef\n\n const iconFileContent = await this._readMediaFile('icon', iconRelativeFilePath)\n const readmeFileContent = await this._readMediaFile('readme', readmeRelativeFilePath)\n\n const integration = await api.findIntegration({ type: 'name', name, version })\n\n let message: string\n if (integration) {\n this.logger.warn('Integration already exists. If you decide to deploy, it will overwrite the existing one.')\n message = `Are you sure you want to override integration ${integrationDef.name} v${integrationDef.version}?`\n } else {\n message = `Are you sure you want to deploy integration ${integrationDef.name} v${integrationDef.version}?`\n }\n\n const confirm = await this.prompt.confirm(message)\n if (!confirm) {\n this.logger.log('Aborted')\n return\n }\n\n const publishBody: CreateIntegrationBody = {\n ...integrationDef,\n icon: iconFileContent,\n readme: readmeFileContent,\n code,\n }\n\n const line = this.logger.line()\n line.started(`Deploying integration ${chalk.bold(integrationDef.name)} v${integrationDef.version}...`)\n if (integration) {\n const publishUpdateBody: UpdateIntegrationBody = this._prepareUpdateIntegrationBody(integration, {\n id: integration.id,\n ...publishBody,\n })\n\n await api.client.updateIntegration(publishUpdateBody).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not update integration \"${integrationDef.name}\"`)\n })\n } else {\n await api.client.createIntegration(publishBody).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not create integration \"${integrationDef.name}\"`)\n })\n }\n line.success('Integration deployed')\n }\n\n // all fields that were removed are replaced by null for the API to remove them\n private _prepareUpdateIntegrationBody = (\n integration: bpclient.Integration,\n body: UpdateIntegrationBody\n ): UpdateIntegrationBody => ({\n ...body,\n actions: utils.records.setOnNullMissingValues(body.actions, integration.actions),\n events: utils.records.setOnNullMissingValues(body.events, integration.events),\n states: utils.records.setOnNullMissingValues(body.states, integration.states),\n user: {\n ...body.user,\n tags: utils.records.setOnNullMissingValues(body.user?.tags, integration.user?.tags),\n },\n channels: Object.entries(body.channels ?? {}).reduce((acc, [channelName, channelDef]) => {\n const currentChannel = integration.channels[channelName]\n return {\n ...acc,\n [channelName]: {\n ...channelDef,\n messages: utils.records.setOnNullMissingValues(channelDef?.messages, currentChannel?.messages),\n message: {\n ...channelDef?.message,\n tags: utils.records.setOnNullMissingValues(channelDef?.message?.tags, currentChannel?.message.tags),\n },\n conversation: {\n ...channelDef?.conversation,\n tags: utils.records.setOnNullMissingValues(\n channelDef?.conversation?.tags,\n currentChannel?.conversation.tags\n ),\n },\n },\n }\n }, {} as UpdateIntegrationBody['channels']),\n })\n\n private _readMediaFile = async (\n filePurpose: 'icon' | 'readme',\n filePath: string | undefined\n ): Promise<string | undefined> => {\n if (!filePath) {\n return undefined\n }\n\n const absoluteFilePath = utils.path.absoluteFrom(this.projectPaths.abs.workDir, filePath)\n return fs.promises.readFile(absoluteFilePath, 'base64').catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not read ${filePurpose} file \"${absoluteFilePath}\"`)\n })\n }\n\n private async _deployBot(api: ApiClient, argvBotId: string | undefined, argvCreateNew: boolean | undefined) {\n const outfile = this.projectPaths.abs.outFile\n const code = await fs.promises.readFile(outfile, 'utf-8')\n const { default: botImpl } = utils.require.requireJsFile<{ default: BotImpl }>(outfile)\n\n const {\n states,\n events,\n recurringEvents,\n configuration: botConfiguration,\n user,\n conversation,\n message,\n } = botImpl.definition\n\n let bot: bpclient.Bot\n if (argvBotId && argvCreateNew) {\n throw new errors.BotpressCLIError('Cannot specify both --botId and --createNew')\n } else if (argvCreateNew) {\n const confirm = await this.prompt.confirm('Are you sure you want to create a new bot ?')\n if (!confirm) {\n this.logger.log('Aborted')\n return\n }\n\n bot = await this._createNewBot(api)\n } else {\n bot = await this._getExistingBot(api, argvBotId)\n\n const confirm = await this.prompt.confirm(`Are you sure you want to deploy the bot \"${bot.name}\"?`)\n if (!confirm) {\n this.logger.log('Aborted')\n return\n }\n }\n\n const integrations = this.prepareIntegrations(botImpl, bot)\n\n const line = this.logger.line()\n line.started(`Deploying bot ${chalk.bold(bot.name)}...`)\n\n const updateBotBody: UpdateBotBody = this._prepareUpdateBotBody(bot, {\n id: bot.id,\n code,\n states,\n recurringEvents,\n configuration: botConfiguration,\n events,\n user,\n conversation,\n message,\n integrations,\n })\n\n const { bot: updatedBot } = await api.client.updateBot(updateBotBody).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not update bot \"${bot.name}\"`)\n })\n line.success('Bot deployed')\n this.displayWebhookUrls(updatedBot)\n }\n\n // all fields that were removed are replaced by null for the API to remove them\n private _prepareUpdateBotBody = (bot: bpclient.Bot, body: UpdateBotBody): UpdateBotBody => ({\n ...body,\n states: utils.records.setOnNullMissingValues(body.states, bot.states),\n recurringEvents: utils.records.setOnNullMissingValues(body.recurringEvents, bot.recurringEvents),\n events: utils.records.setOnNullMissingValues(body.events, bot.events),\n user: {\n ...body.user,\n tags: utils.records.setOnNullMissingValues(body.user?.tags, bot.user?.tags),\n },\n conversation: {\n ...body.conversation,\n tags: utils.records.setOnNullMissingValues(body.conversation?.tags, bot.conversation?.tags),\n },\n message: {\n ...body.message,\n tags: utils.records.setOnNullMissingValues(body.message?.tags, bot.message?.tags),\n },\n })\n\n private async _createNewBot(api: ApiClient): Promise<bpclient.Bot> {\n const line = this.logger.line()\n const { bot: createdBot } = await api.client.createBot({}).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not create bot')\n })\n line.success(`Bot created with ID \"${createdBot.id}\" and name \"${createdBot.name}\"`)\n await this.projectCache.set('botId', createdBot.id)\n return createdBot\n }\n\n private async _getExistingBot(api: ApiClient, botId: string | undefined): Promise<bpclient.Bot> {\n const promptedBotId = await this.projectCache.sync('botId', botId, async (defaultId) => {\n const userBots = await api\n .listAllPages(api.client.listBots, (r) => r.bots)\n .catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not fetch existing bots')\n })\n\n if (!userBots.length) {\n throw new errors.NoBotsFoundError()\n }\n\n const initial = userBots.find((bot) => bot.id === defaultId)\n\n const prompted = await this.prompt.select('Which bot do you want to deploy?', {\n initial: initial && { title: initial.name, value: initial.id },\n choices: userBots.map((bot) => ({ title: bot.name, value: bot.id })),\n })\n\n if (!prompted) {\n throw new errors.ParamRequiredError('Bot Id')\n }\n\n return prompted\n })\n\n const { bot: fetchedBot } = await api.client.getBot({ id: promptedBotId }).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not get bot info')\n })\n\n return fetchedBot\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAAkB;AAClB,SAAoB;
|
|
6
|
-
"names": ["chalk"]
|
|
4
|
+
"sourcesContent": ["import type * as bpclient from '@botpress/client'\nimport type { Bot as BotImpl, IntegrationDefinition } from '@botpress/sdk'\nimport chalk from 'chalk'\nimport * as fs from 'fs'\nimport _ from 'lodash'\nimport { prepareUpdateBotBody } from '../api/bot-body'\nimport type { ApiClient } from '../api/client'\nimport { prepareUpdateIntegrationBody, CreateIntegrationBody } from '../api/integration-body'\nimport type commandDefinitions from '../command-definitions'\nimport * as consts from '../consts'\nimport * as errors from '../errors'\nimport * as utils from '../utils'\nimport { BuildCommand } from './build-command'\nimport { ProjectCommand } from './project-command'\n\nexport type DeployCommandDefinition = typeof commandDefinitions.deploy\nexport class DeployCommand extends ProjectCommand<DeployCommandDefinition> {\n public async run(): Promise<void> {\n const api = await this.ensureLoginAndCreateClient(this.argv)\n if (api.url !== consts.defaultBotpressApiUrl) {\n this.logger.log(`Using custom url ${api.url}`)\n }\n\n if (!this.argv.noBuild) {\n await this._runBuild() // This ensures the bundle is always synced with source code\n }\n\n const integrationDef = await this.readIntegrationDefinitionFromFS()\n if (integrationDef) {\n return this._deployIntegration(api, integrationDef)\n }\n return this._deployBot(api, this.argv.botId, this.argv.createNewBot)\n }\n\n private async _runBuild() {\n return new BuildCommand(this.api, this.prompt, this.logger, this.argv).run()\n }\n\n private async _deployIntegration(api: ApiClient, integrationDef: IntegrationDefinition) {\n const outfile = this.projectPaths.abs.outFile\n let code = await fs.promises.readFile(outfile, 'utf-8')\n\n const secrets = await this.promptSecrets(integrationDef, this.argv)\n // TODO: provide these secrets to the backend by API and remove this string replacement hack\n for (const [secretName, secretValue] of Object.entries(secrets)) {\n code = code.replace(new RegExp(`process\\\\.env\\\\.${secretName}`, 'g'), `\"${secretValue}\"`)\n }\n\n const { name, version, icon: iconRelativeFilePath, readme: readmeRelativeFilePath } = integrationDef\n\n const iconFileContent = await this._readMediaFile('icon', iconRelativeFilePath)\n const readmeFileContent = await this._readMediaFile('readme', readmeRelativeFilePath)\n\n const integration = await api.findIntegration({ type: 'name', name, version })\n\n let message: string\n if (integration) {\n this.logger.warn('Integration already exists. If you decide to deploy, it will overwrite the existing one.')\n message = `Are you sure you want to override integration ${integrationDef.name} v${integrationDef.version}?`\n } else {\n message = `Are you sure you want to deploy integration ${integrationDef.name} v${integrationDef.version}?`\n }\n\n const confirm = await this.prompt.confirm(message)\n if (!confirm) {\n this.logger.log('Aborted')\n return\n }\n\n const createBody: CreateIntegrationBody = {\n ...integrationDef,\n icon: iconFileContent,\n readme: readmeFileContent,\n code,\n }\n\n const line = this.logger.line()\n line.started(`Deploying integration ${chalk.bold(integrationDef.name)} v${integrationDef.version}...`)\n if (integration) {\n const updateBody = prepareUpdateIntegrationBody(\n {\n id: integration.id,\n ...createBody,\n },\n integration\n )\n\n await api.client.updateIntegration(updateBody).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not update integration \"${integrationDef.name}\"`)\n })\n } else {\n await api.client.createIntegration(createBody).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not create integration \"${integrationDef.name}\"`)\n })\n }\n line.success('Integration deployed')\n }\n\n private _readMediaFile = async (\n filePurpose: 'icon' | 'readme',\n filePath: string | undefined\n ): Promise<string | undefined> => {\n if (!filePath) {\n return undefined\n }\n\n const absoluteFilePath = utils.path.absoluteFrom(this.projectPaths.abs.workDir, filePath)\n return fs.promises.readFile(absoluteFilePath, 'base64').catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not read ${filePurpose} file \"${absoluteFilePath}\"`)\n })\n }\n\n private async _deployBot(api: ApiClient, argvBotId: string | undefined, argvCreateNew: boolean | undefined) {\n const outfile = this.projectPaths.abs.outFile\n const code = await fs.promises.readFile(outfile, 'utf-8')\n const { default: botImpl } = utils.require.requireJsFile<{ default: BotImpl }>(outfile)\n\n const {\n states,\n events,\n recurringEvents,\n configuration: botConfiguration,\n user,\n conversation,\n message,\n } = botImpl.definition\n\n let bot: bpclient.Bot\n if (argvBotId && argvCreateNew) {\n throw new errors.BotpressCLIError('Cannot specify both --botId and --createNew')\n } else if (argvCreateNew) {\n const confirm = await this.prompt.confirm('Are you sure you want to create a new bot ?')\n if (!confirm) {\n this.logger.log('Aborted')\n return\n }\n\n bot = await this._createNewBot(api)\n } else {\n bot = await this._getExistingBot(api, argvBotId)\n\n const confirm = await this.prompt.confirm(`Are you sure you want to deploy the bot \"${bot.name}\"?`)\n if (!confirm) {\n this.logger.log('Aborted')\n return\n }\n }\n\n const line = this.logger.line()\n line.started(`Deploying bot ${chalk.bold(bot.name)}...`)\n\n const integrations = _(botImpl.definition.integrations ?? [])\n .keyBy((i) => i.id)\n .mapValues(({ enabled, configuration }) => ({ enabled, configuration }))\n .value()\n\n const updateBotBody = prepareUpdateBotBody(\n {\n id: bot.id,\n code,\n states,\n recurringEvents,\n configuration: botConfiguration,\n events,\n user,\n conversation,\n message,\n integrations,\n },\n bot\n )\n\n const { bot: updatedBot } = await api.client.updateBot(updateBotBody).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not update bot \"${bot.name}\"`)\n })\n line.success('Bot deployed')\n this.displayWebhookUrls(updatedBot)\n }\n\n private async _createNewBot(api: ApiClient): Promise<bpclient.Bot> {\n const line = this.logger.line()\n const { bot: createdBot } = await api.client.createBot({}).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not create bot')\n })\n line.success(`Bot created with ID \"${createdBot.id}\" and name \"${createdBot.name}\"`)\n await this.projectCache.set('botId', createdBot.id)\n return createdBot\n }\n\n private async _getExistingBot(api: ApiClient, botId: string | undefined): Promise<bpclient.Bot> {\n const promptedBotId = await this.projectCache.sync('botId', botId, async (defaultId) => {\n const userBots = await api\n .listAllPages(api.client.listBots, (r) => r.bots)\n .catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not fetch existing bots')\n })\n\n if (!userBots.length) {\n throw new errors.NoBotsFoundError()\n }\n\n const initial = userBots.find((bot) => bot.id === defaultId)\n\n const prompted = await this.prompt.select('Which bot do you want to deploy?', {\n initial: initial && { title: initial.name, value: initial.id },\n choices: userBots.map((bot) => ({ title: bot.name, value: bot.id })),\n })\n\n if (!prompted) {\n throw new errors.ParamRequiredError('Bot Id')\n }\n\n return prompted\n })\n\n const { bot: fetchedBot } = await api.client.getBot({ id: promptedBotId }).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not get bot info')\n })\n\n return fetchedBot\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["chalk", "_"]
|
|
7
7
|
}
|
|
@@ -29,8 +29,11 @@ __export(dev_command_exports, {
|
|
|
29
29
|
module.exports = __toCommonJS(dev_command_exports);
|
|
30
30
|
var import_axios = __toESM(require("axios"));
|
|
31
31
|
var import_chalk = __toESM(require("chalk"));
|
|
32
|
+
var import_lodash = __toESM(require("lodash"));
|
|
32
33
|
var pathlib = __toESM(require("path"));
|
|
33
34
|
var uuid = __toESM(require("uuid"));
|
|
35
|
+
var import_bot_body = require("../api/bot-body");
|
|
36
|
+
var import_integration_body = require("../api/integration-body");
|
|
34
37
|
var errors = __toESM(require("../errors"));
|
|
35
38
|
var utils = __toESM(require("../utils"));
|
|
36
39
|
var import_worker = require("../worker");
|
|
@@ -188,7 +191,11 @@ class DevCommand extends import_project_command.ProjectCommand {
|
|
|
188
191
|
const line = this.logger.line();
|
|
189
192
|
line.started(`Deploying dev integration ${import_chalk.default.bold(integrationDef.name)}...`);
|
|
190
193
|
if (integration) {
|
|
191
|
-
const
|
|
194
|
+
const updateIntegrationBody = (0, import_integration_body.prepareUpdateIntegrationBody)(
|
|
195
|
+
{ ...integrationDef, id: integration.id, url: externalUrl },
|
|
196
|
+
integration
|
|
197
|
+
);
|
|
198
|
+
const resp = await api.client.updateIntegration(updateIntegrationBody).catch((thrown) => {
|
|
192
199
|
throw errors.BotpressCLIError.wrap(thrown, `Could not update dev integration "${integrationDef.name}"`);
|
|
193
200
|
});
|
|
194
201
|
integration = resp.integration;
|
|
@@ -231,15 +238,19 @@ class DevCommand extends import_project_command.ProjectCommand {
|
|
|
231
238
|
}
|
|
232
239
|
const outfile = this.projectPaths.abs.outFile;
|
|
233
240
|
const { default: botImpl } = utils.require.requireJsFile(outfile);
|
|
234
|
-
const integrations = this.prepareIntegrations(botImpl, bot);
|
|
235
241
|
const updateLine = this.logger.line();
|
|
236
242
|
updateLine.started("Deploying dev bot...");
|
|
237
|
-
const {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
+
const integrations = (0, import_lodash.default)(botImpl.definition.integrations ?? []).keyBy((i) => i.id).mapValues(({ enabled, configuration }) => ({ enabled, configuration })).value();
|
|
244
|
+
const updateBotBody = (0, import_bot_body.prepareUpdateBotBody)(
|
|
245
|
+
{
|
|
246
|
+
...botImpl.definition,
|
|
247
|
+
id: bot.id,
|
|
248
|
+
integrations,
|
|
249
|
+
url: externalUrl
|
|
250
|
+
},
|
|
251
|
+
bot
|
|
252
|
+
);
|
|
253
|
+
const { bot: updatedBot } = await api.client.updateBot(updateBotBody).catch((thrown) => {
|
|
243
254
|
throw errors.BotpressCLIError.wrap(thrown, "Could not deploy dev bot");
|
|
244
255
|
});
|
|
245
256
|
updateLine.success(`Dev Bot deployed with id "${updatedBot.id}"`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/command-implementations/dev-command.ts"],
|
|
4
|
-
"sourcesContent": ["import type * as bpclient from '@botpress/client'\nimport type { Bot as BotImpl, IntegrationDefinition } from '@botpress/sdk'\nimport { TunnelRequest, TunnelResponse } from '@bpinternal/tunnel'\nimport axios, { AxiosRequestConfig, AxiosResponse } from 'axios'\nimport chalk from 'chalk'\nimport * as pathlib from 'path'\nimport * as uuid from 'uuid'\nimport type { ApiClient } from '../api-client'\nimport type commandDefinitions from '../command-definitions'\nimport * as errors from '../errors'\nimport * as utils from '../utils'\nimport { Worker } from '../worker'\nimport { BuildCommand } from './build-command'\nimport { ProjectCommand } from './project-command'\n\nconst DEFAULT_BOT_PORT = 8075\nconst DEFAULT_INTEGRATION_PORT = 8076\nconst TUNNEL_HELLO_INTERVAL = 5000\n\nexport type DevCommandDefinition = typeof commandDefinitions.dev\nexport class DevCommand extends ProjectCommand<DevCommandDefinition> {\n private _initialDef: IntegrationDefinition | undefined = undefined\n\n public async run(): Promise<void> {\n this.logger.warn('This command is experimental and subject to breaking changes without notice.')\n\n const api = await this.ensureLoginAndCreateClient(this.argv)\n\n this._initialDef = await this.readIntegrationDefinitionFromFS()\n\n let env: Record<string, string> = {\n ...process.env,\n BP_API_URL: api.url,\n BP_TOKEN: api.token,\n }\n\n let defaultPort = DEFAULT_BOT_PORT\n if (this._initialDef) {\n defaultPort = DEFAULT_INTEGRATION_PORT\n const secrets = await this.promptSecrets(this._initialDef, this.argv)\n env = { ...env, ...secrets }\n }\n\n const port = this.argv.port ?? defaultPort\n\n const urlParseResult = utils.url.parse(this.argv.tunnelUrl)\n if (urlParseResult.status === 'error') {\n throw new errors.BotpressCLIError(`Invalid tunnel URL: ${urlParseResult.error}`)\n }\n\n const tunnelId = uuid.v4()\n\n const { url: parsedTunnelUrl } = urlParseResult\n const isSecured = parsedTunnelUrl.protocol === 'https' || parsedTunnelUrl.protocol === 'wss'\n\n const wsTunnelUrl: string = utils.url.format({ ...parsedTunnelUrl, protocol: isSecured ? 'wss' : 'ws' })\n const httpTunnelUrl: string = utils.url.format({\n ...parsedTunnelUrl,\n protocol: isSecured ? 'https' : 'http',\n path: `/${tunnelId}`,\n })\n\n const supervisor = new utils.tunnel.TunnelSupervisor(wsTunnelUrl, tunnelId, this.logger)\n supervisor.events.on('connected', ({ tunnel }) => {\n // prevents the tunnel from closing due to inactivity\n const timer = setInterval(() => tunnel.hello(), TUNNEL_HELLO_INTERVAL)\n tunnel.events.on('close', () => clearInterval(timer))\n\n tunnel.events.on(\n 'request',\n (req) =>\n void this._forwardTunnelRequest(`http://localhost:${port}`, req)\n .then((res) => {\n tunnel.send(res)\n })\n .catch((thrown) => {\n const err = errors.BotpressCLIError.wrap(thrown, 'An error occurred while handling request')\n this.logger.error(err.message)\n tunnel.send({\n requestId: req.id,\n status: 500,\n body: err.message,\n })\n })\n )\n })\n await supervisor.start()\n\n await this._runBuild()\n await this._deploy(api, httpTunnelUrl)\n const worker = await this._spawnWorker(env, port)\n\n try {\n const watcher = await utils.filewatcher.FileWatcher.watch(\n this.argv.workDir,\n async (events) => {\n const typescriptEvents = events.filter((e) => pathlib.extname(e.path) === '.ts')\n if (typescriptEvents.length === 0) {\n return\n }\n\n this.logger.log('Changes detected, rebuilding')\n await this._restart(api, worker, httpTunnelUrl)\n },\n {\n ignore: [this.projectPaths.abs.outDir],\n }\n )\n\n await Promise.race([worker.wait(), watcher.wait(), supervisor.wait()])\n\n if (worker.running) {\n await worker.kill()\n }\n await watcher.close()\n supervisor.close()\n } catch (thrown) {\n throw errors.BotpressCLIError.wrap(thrown, 'An error occurred while running the dev server')\n } finally {\n if (worker.running) {\n await worker.kill()\n }\n }\n }\n\n private _restart = async (api: ApiClient, worker: Worker, tunnelUrl: string) => {\n try {\n await this._runBuild()\n } catch (thrown) {\n const error = errors.BotpressCLIError.wrap(thrown, 'Build failed')\n this.logger.error(error.message)\n return\n }\n\n await this._deploy(api, tunnelUrl)\n await worker.reload()\n }\n\n private _deploy = async (api: ApiClient, tunnelUrl: string) => {\n const integrationDef = await this.readIntegrationDefinitionFromFS()\n if (integrationDef) {\n this._checkSecrets(integrationDef)\n await this._deployDevIntegration(api, tunnelUrl, integrationDef)\n } else {\n await this._deployDevBot(api, tunnelUrl)\n }\n }\n\n private _checkSecrets(integrationDef: IntegrationDefinition) {\n const initialSecrets = this._initialDef?.secrets ?? []\n const currentSecrets = integrationDef.secrets ?? []\n const newSecrets = currentSecrets.filter((s) => !initialSecrets.includes(s))\n if (newSecrets.length > 0) {\n throw new errors.BotpressCLIError('Secrets were added while the server was running. A restart is required.')\n }\n }\n\n private _spawnWorker = async (env: Record<string, string>, port: number) => {\n const outfile = this.projectPaths.abs.outFile\n const importPath = utils.path.toUnix(outfile)\n const requireFrom = utils.path.rmExtension(importPath)\n const code = `require('${requireFrom}').default.start(${port})`\n const worker = await Worker.spawn(\n {\n type: 'code',\n code,\n env,\n },\n this.logger\n ).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not start dev worker')\n })\n\n return worker\n }\n\n private _runBuild() {\n return new BuildCommand(this.api, this.prompt, this.logger, this.argv).run()\n }\n\n private async _deployDevIntegration(\n api: ApiClient,\n externalUrl: string,\n integrationDef: IntegrationDefinition\n ): Promise<void> {\n const devId = await this.projectCache.get('devId')\n\n let integration: bpclient.Integration | undefined = undefined\n\n if (devId) {\n const resp = await api.client.getIntegration({ id: devId }).catch(async (thrown) => {\n const err = errors.BotpressCLIError.wrap(thrown, `Could not find existing dev integration with id \"${devId}\"`)\n this.logger.warn(err.message)\n return { integration: undefined }\n })\n\n if (resp.integration?.dev) {\n integration = resp.integration\n } else {\n await this.projectCache.rm('devId')\n }\n }\n\n const line = this.logger.line()\n line.started(`Deploying dev integration ${chalk.bold(integrationDef.name)}...`)\n if (integration) {\n const resp = await api.client\n .updateIntegration({ ...integrationDef, id: integration.id, url: externalUrl })\n .catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not update dev integration \"${integrationDef.name}\"`)\n })\n integration = resp.integration\n } else {\n const resp = await api.client\n .createIntegration({ ...integrationDef, dev: true, url: externalUrl })\n .catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not deploy dev integration \"${integrationDef.name}\"`)\n })\n integration = resp.integration\n }\n\n line.success(`Dev Integration deployed with id \"${integration.id}\"`)\n await this.projectCache.set('devId', integration.id)\n }\n\n private async _deployDevBot(api: ApiClient, externalUrl: string): Promise<void> {\n const devId = await this.projectCache.get('devId')\n\n let bot: bpclient.Bot | undefined = undefined\n\n if (devId) {\n const resp = await api.client.getBot({ id: devId }).catch(async (thrown) => {\n const err = errors.BotpressCLIError.wrap(thrown, `Could not find existing dev bot with id \"${devId}\"`)\n this.logger.warn(err.message)\n return { bot: undefined }\n })\n\n if (resp.bot?.dev) {\n bot = resp.bot\n } else {\n await this.projectCache.rm('devId')\n }\n }\n\n if (!bot) {\n const createLine = this.logger.line()\n createLine.started('Creating dev bot...')\n const resp = await api.client\n .createBot({\n dev: true,\n url: externalUrl,\n })\n .catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not deploy dev bot')\n })\n\n bot = resp.bot\n createLine.success(`Dev Bot created with id \"${bot.id}\"`)\n await this.projectCache.set('devId', bot.id)\n }\n\n const outfile = this.projectPaths.abs.outFile\n const { default: botImpl } = utils.require.requireJsFile<{ default: BotImpl }>(outfile)\n\n const integrations = this.prepareIntegrations(botImpl, bot)\n\n const updateLine = this.logger.line()\n updateLine.started('Deploying dev bot...')\n\n const { bot: updatedBot } = await api.client\n .updateBot({\n ...botImpl.definition,\n id: bot.id,\n integrations,\n url: externalUrl,\n })\n .catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not deploy dev bot')\n })\n updateLine.success(`Dev Bot deployed with id \"${updatedBot.id}\"`)\n\n this.displayWebhookUrls(updatedBot)\n }\n\n private _forwardTunnelRequest = async (baseUrl: string, request: TunnelRequest): Promise<TunnelResponse> => {\n const axiosConfig = {\n method: request.method,\n url: this._formatLocalUrl(baseUrl, request),\n headers: request.headers,\n data: request.body,\n responseType: 'text',\n validateStatus: () => true,\n } satisfies AxiosRequestConfig\n\n this.logger.debug(`Forwarding request to ${axiosConfig.url}`)\n const response = await axios(axiosConfig)\n this.logger.debug('Sending back response up the tunnel')\n\n return {\n requestId: request.id,\n status: response.status,\n headers: this._getHeaders(response.headers),\n body: response.data,\n }\n }\n\n private _formatLocalUrl = (baseUrl: string, req: TunnelRequest): string => {\n if (req.query) {\n return `${baseUrl}${req.path}?${req.query}`\n }\n return `${baseUrl}${req.path}`\n }\n\n private _getHeaders = (res: AxiosResponse['headers']): TunnelResponse['headers'] => {\n const headers: TunnelResponse['headers'] = {}\n for (const key in res) {\n if (typeof res[key] === 'string' || typeof res[key] === 'number') {\n headers[key] = res[key]\n }\n }\n return headers\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAAyD;AACzD,mBAAkB;AAClB,cAAyB;AACzB,WAAsB;
|
|
6
|
-
"names": ["chalk", "axios"]
|
|
4
|
+
"sourcesContent": ["import type * as bpclient from '@botpress/client'\nimport type { Bot as BotImpl, IntegrationDefinition } from '@botpress/sdk'\nimport { TunnelRequest, TunnelResponse } from '@bpinternal/tunnel'\nimport axios, { AxiosRequestConfig, AxiosResponse } from 'axios'\nimport chalk from 'chalk'\nimport _ from 'lodash'\nimport * as pathlib from 'path'\nimport * as uuid from 'uuid'\nimport { prepareUpdateBotBody } from '../api/bot-body'\nimport type { ApiClient } from '../api/client'\nimport { prepareUpdateIntegrationBody } from '../api/integration-body'\nimport type commandDefinitions from '../command-definitions'\nimport * as errors from '../errors'\nimport * as utils from '../utils'\nimport { Worker } from '../worker'\nimport { BuildCommand } from './build-command'\nimport { ProjectCommand } from './project-command'\n\nconst DEFAULT_BOT_PORT = 8075\nconst DEFAULT_INTEGRATION_PORT = 8076\nconst TUNNEL_HELLO_INTERVAL = 5000\n\nexport type DevCommandDefinition = typeof commandDefinitions.dev\nexport class DevCommand extends ProjectCommand<DevCommandDefinition> {\n private _initialDef: IntegrationDefinition | undefined = undefined\n\n public async run(): Promise<void> {\n this.logger.warn('This command is experimental and subject to breaking changes without notice.')\n\n const api = await this.ensureLoginAndCreateClient(this.argv)\n\n this._initialDef = await this.readIntegrationDefinitionFromFS()\n\n let env: Record<string, string> = {\n ...process.env,\n BP_API_URL: api.url,\n BP_TOKEN: api.token,\n }\n\n let defaultPort = DEFAULT_BOT_PORT\n if (this._initialDef) {\n defaultPort = DEFAULT_INTEGRATION_PORT\n const secrets = await this.promptSecrets(this._initialDef, this.argv)\n env = { ...env, ...secrets }\n }\n\n const port = this.argv.port ?? defaultPort\n\n const urlParseResult = utils.url.parse(this.argv.tunnelUrl)\n if (urlParseResult.status === 'error') {\n throw new errors.BotpressCLIError(`Invalid tunnel URL: ${urlParseResult.error}`)\n }\n\n const tunnelId = uuid.v4()\n\n const { url: parsedTunnelUrl } = urlParseResult\n const isSecured = parsedTunnelUrl.protocol === 'https' || parsedTunnelUrl.protocol === 'wss'\n\n const wsTunnelUrl: string = utils.url.format({ ...parsedTunnelUrl, protocol: isSecured ? 'wss' : 'ws' })\n const httpTunnelUrl: string = utils.url.format({\n ...parsedTunnelUrl,\n protocol: isSecured ? 'https' : 'http',\n path: `/${tunnelId}`,\n })\n\n const supervisor = new utils.tunnel.TunnelSupervisor(wsTunnelUrl, tunnelId, this.logger)\n supervisor.events.on('connected', ({ tunnel }) => {\n // prevents the tunnel from closing due to inactivity\n const timer = setInterval(() => tunnel.hello(), TUNNEL_HELLO_INTERVAL)\n tunnel.events.on('close', () => clearInterval(timer))\n\n tunnel.events.on(\n 'request',\n (req) =>\n void this._forwardTunnelRequest(`http://localhost:${port}`, req)\n .then((res) => {\n tunnel.send(res)\n })\n .catch((thrown) => {\n const err = errors.BotpressCLIError.wrap(thrown, 'An error occurred while handling request')\n this.logger.error(err.message)\n tunnel.send({\n requestId: req.id,\n status: 500,\n body: err.message,\n })\n })\n )\n })\n await supervisor.start()\n\n await this._runBuild()\n await this._deploy(api, httpTunnelUrl)\n const worker = await this._spawnWorker(env, port)\n\n try {\n const watcher = await utils.filewatcher.FileWatcher.watch(\n this.argv.workDir,\n async (events) => {\n const typescriptEvents = events.filter((e) => pathlib.extname(e.path) === '.ts')\n if (typescriptEvents.length === 0) {\n return\n }\n\n this.logger.log('Changes detected, rebuilding')\n await this._restart(api, worker, httpTunnelUrl)\n },\n {\n ignore: [this.projectPaths.abs.outDir],\n }\n )\n\n await Promise.race([worker.wait(), watcher.wait(), supervisor.wait()])\n\n if (worker.running) {\n await worker.kill()\n }\n await watcher.close()\n supervisor.close()\n } catch (thrown) {\n throw errors.BotpressCLIError.wrap(thrown, 'An error occurred while running the dev server')\n } finally {\n if (worker.running) {\n await worker.kill()\n }\n }\n }\n\n private _restart = async (api: ApiClient, worker: Worker, tunnelUrl: string) => {\n try {\n await this._runBuild()\n } catch (thrown) {\n const error = errors.BotpressCLIError.wrap(thrown, 'Build failed')\n this.logger.error(error.message)\n return\n }\n\n await this._deploy(api, tunnelUrl)\n await worker.reload()\n }\n\n private _deploy = async (api: ApiClient, tunnelUrl: string) => {\n const integrationDef = await this.readIntegrationDefinitionFromFS()\n if (integrationDef) {\n this._checkSecrets(integrationDef)\n await this._deployDevIntegration(api, tunnelUrl, integrationDef)\n } else {\n await this._deployDevBot(api, tunnelUrl)\n }\n }\n\n private _checkSecrets(integrationDef: IntegrationDefinition) {\n const initialSecrets = this._initialDef?.secrets ?? []\n const currentSecrets = integrationDef.secrets ?? []\n const newSecrets = currentSecrets.filter((s) => !initialSecrets.includes(s))\n if (newSecrets.length > 0) {\n throw new errors.BotpressCLIError('Secrets were added while the server was running. A restart is required.')\n }\n }\n\n private _spawnWorker = async (env: Record<string, string>, port: number) => {\n const outfile = this.projectPaths.abs.outFile\n const importPath = utils.path.toUnix(outfile)\n const requireFrom = utils.path.rmExtension(importPath)\n const code = `require('${requireFrom}').default.start(${port})`\n const worker = await Worker.spawn(\n {\n type: 'code',\n code,\n env,\n },\n this.logger\n ).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not start dev worker')\n })\n\n return worker\n }\n\n private _runBuild() {\n return new BuildCommand(this.api, this.prompt, this.logger, this.argv).run()\n }\n\n private async _deployDevIntegration(\n api: ApiClient,\n externalUrl: string,\n integrationDef: IntegrationDefinition\n ): Promise<void> {\n const devId = await this.projectCache.get('devId')\n\n let integration: bpclient.Integration | undefined = undefined\n\n if (devId) {\n const resp = await api.client.getIntegration({ id: devId }).catch(async (thrown) => {\n const err = errors.BotpressCLIError.wrap(thrown, `Could not find existing dev integration with id \"${devId}\"`)\n this.logger.warn(err.message)\n return { integration: undefined }\n })\n\n if (resp.integration?.dev) {\n integration = resp.integration\n } else {\n await this.projectCache.rm('devId')\n }\n }\n\n const line = this.logger.line()\n line.started(`Deploying dev integration ${chalk.bold(integrationDef.name)}...`)\n\n if (integration) {\n const updateIntegrationBody = prepareUpdateIntegrationBody(\n { ...integrationDef, id: integration.id, url: externalUrl },\n integration\n )\n\n const resp = await api.client.updateIntegration(updateIntegrationBody).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not update dev integration \"${integrationDef.name}\"`)\n })\n integration = resp.integration\n } else {\n const resp = await api.client\n .createIntegration({ ...integrationDef, dev: true, url: externalUrl })\n .catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, `Could not deploy dev integration \"${integrationDef.name}\"`)\n })\n integration = resp.integration\n }\n\n line.success(`Dev Integration deployed with id \"${integration.id}\"`)\n await this.projectCache.set('devId', integration.id)\n }\n\n private async _deployDevBot(api: ApiClient, externalUrl: string): Promise<void> {\n const devId = await this.projectCache.get('devId')\n\n let bot: bpclient.Bot | undefined = undefined\n\n if (devId) {\n const resp = await api.client.getBot({ id: devId }).catch(async (thrown) => {\n const err = errors.BotpressCLIError.wrap(thrown, `Could not find existing dev bot with id \"${devId}\"`)\n this.logger.warn(err.message)\n return { bot: undefined }\n })\n\n if (resp.bot?.dev) {\n bot = resp.bot\n } else {\n await this.projectCache.rm('devId')\n }\n }\n\n if (!bot) {\n const createLine = this.logger.line()\n createLine.started('Creating dev bot...')\n const resp = await api.client\n .createBot({\n dev: true,\n url: externalUrl,\n })\n .catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not deploy dev bot')\n })\n\n bot = resp.bot\n createLine.success(`Dev Bot created with id \"${bot.id}\"`)\n await this.projectCache.set('devId', bot.id)\n }\n\n const outfile = this.projectPaths.abs.outFile\n const { default: botImpl } = utils.require.requireJsFile<{ default: BotImpl }>(outfile)\n\n const updateLine = this.logger.line()\n updateLine.started('Deploying dev bot...')\n\n const integrations = _(botImpl.definition.integrations ?? [])\n .keyBy((i) => i.id)\n .mapValues(({ enabled, configuration }) => ({ enabled, configuration }))\n .value()\n\n const updateBotBody = prepareUpdateBotBody(\n {\n ...botImpl.definition,\n id: bot.id,\n integrations,\n url: externalUrl,\n },\n bot\n )\n\n const { bot: updatedBot } = await api.client.updateBot(updateBotBody).catch((thrown) => {\n throw errors.BotpressCLIError.wrap(thrown, 'Could not deploy dev bot')\n })\n updateLine.success(`Dev Bot deployed with id \"${updatedBot.id}\"`)\n\n this.displayWebhookUrls(updatedBot)\n }\n\n private _forwardTunnelRequest = async (baseUrl: string, request: TunnelRequest): Promise<TunnelResponse> => {\n const axiosConfig = {\n method: request.method,\n url: this._formatLocalUrl(baseUrl, request),\n headers: request.headers,\n data: request.body,\n responseType: 'text',\n validateStatus: () => true,\n } satisfies AxiosRequestConfig\n\n this.logger.debug(`Forwarding request to ${axiosConfig.url}`)\n const response = await axios(axiosConfig)\n this.logger.debug('Sending back response up the tunnel')\n\n return {\n requestId: request.id,\n status: response.status,\n headers: this._getHeaders(response.headers),\n body: response.data,\n }\n }\n\n private _formatLocalUrl = (baseUrl: string, req: TunnelRequest): string => {\n if (req.query) {\n return `${baseUrl}${req.path}?${req.query}`\n }\n return `${baseUrl}${req.path}`\n }\n\n private _getHeaders = (res: AxiosResponse['headers']): TunnelResponse['headers'] => {\n const headers: TunnelResponse['headers'] = {}\n for (const key in res) {\n if (typeof res[key] === 'string' || typeof res[key] === 'number') {\n headers[key] = res[key]\n }\n }\n return headers\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["chalk", "_", "axios"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/command-implementations/global-command.ts"],
|
|
4
|
-
"sourcesContent": ["import type { YargsConfig } from '@bpinternal/yargs-extra'\nimport chalk from 'chalk'\nimport fs from 'fs'\nimport latestVersion from 'latest-version'\nimport _ from 'lodash'\nimport * as pathlib from 'path'\nimport semver from 'semver'\nimport type { ApiClientFactory } from '../api
|
|
4
|
+
"sourcesContent": ["import type { YargsConfig } from '@bpinternal/yargs-extra'\nimport chalk from 'chalk'\nimport fs from 'fs'\nimport latestVersion from 'latest-version'\nimport _ from 'lodash'\nimport * as pathlib from 'path'\nimport semver from 'semver'\nimport type { ApiClientFactory } from '../api/client'\nimport type * as config from '../config'\nimport * as consts from '../consts'\nimport * as errors from '../errors'\nimport type { CommandArgv, CommandDefinition } from '../typings'\nimport * as utils from '../utils'\nimport { BaseCommand } from './base-command'\n\nexport type GlobalCommandDefinition = CommandDefinition<typeof config.schemas.global>\nexport type GlobalCache = { apiUrl: string; token: string; workspaceId: string }\n\nexport type ConfigurableGlobalPaths = { botpressHomeDir: string; cliRootDir: utils.path.AbsolutePath }\nexport type ConstantGlobalPaths = typeof consts.fromHomeDir & typeof consts.fromCliRootDir\nexport type AllGlobalPaths = ConfigurableGlobalPaths & ConstantGlobalPaths\n\nclass GlobalPaths extends utils.path.PathStore<keyof AllGlobalPaths> {\n public constructor(argv: CommandArgv<GlobalCommandDefinition>) {\n const absBotpressHome = utils.path.absoluteFrom(utils.path.cwd(), argv.botpressHome)\n super({\n cliRootDir: consts.cliRootDir,\n botpressHomeDir: absBotpressHome,\n ..._.mapValues(consts.fromHomeDir, (p) => utils.path.absoluteFrom(absBotpressHome, p)),\n ..._.mapValues(consts.fromCliRootDir, (p) => utils.path.absoluteFrom(consts.cliRootDir, p)),\n })\n }\n}\n\ntype PackageJson = { name: string; version: string }\n\nconst UPDATE_MSG = (props: PackageJson & { latest: string }) =>\n `${chalk.bold('Update available')} ${chalk.dim(props.version)} \u2192 ${chalk.green(props.latest)}\n\nTo update, run:\n for npm ${chalk.cyan(`npm i -g ${props.name}`)}\n for yarn ${chalk.cyan(`yarn global add ${props.name}`)}\n for pnpm ${chalk.cyan(`pnpm i -g ${props.name}`)}`\n\nexport abstract class GlobalCommand<C extends GlobalCommandDefinition> extends BaseCommand<C> {\n protected api: ApiClientFactory\n protected prompt: utils.prompt.CLIPrompt\n\n public constructor(\n api: ApiClientFactory,\n prompt: utils.prompt.CLIPrompt,\n ...args: ConstructorParameters<typeof BaseCommand<C>>\n ) {\n super(...args)\n this.api = api\n this.prompt = prompt\n }\n\n protected get globalPaths() {\n return new GlobalPaths(this.argv)\n }\n\n protected get globalCache() {\n return new utils.cache.FSKeyValueCache<GlobalCache>(this.globalPaths.abs.globalCacheFile)\n }\n\n protected override bootstrap = async () => {\n const pkgJson = await this._readPackageJson()\n\n const versionText = chalk.bold(`v${pkgJson.version}`)\n this.logger.log(`Botpress CLI ${versionText}`, { prefix: '\uD83E\uDD16' })\n\n await this._notifyUpdate(pkgJson)\n\n const paths = this.globalPaths\n if (paths.abs.botpressHomeDir !== consts.defaultBotpressHome) {\n this.logger.log(`Using custom botpress home: ${paths.abs.botpressHomeDir}`, { prefix: '\uD83C\uDFE0' })\n }\n }\n\n protected override teardown = async () => {\n this.logger.cleanup()\n }\n\n protected async ensureLoginAndCreateClient(credentials: YargsConfig<typeof config.schemas.credentials>) {\n const cache = this.globalCache\n const token = await cache.get('token')\n const workspaceId = credentials.workspaceId ?? (await cache.get('workspaceId'))\n const apiUrl = credentials.apiUrl ?? (await cache.get('apiUrl'))\n\n if (!(token && workspaceId && apiUrl)) {\n throw new errors.NotLoggedInError()\n }\n\n return this.api.newClient({ apiUrl, token, workspaceId }, this.logger)\n }\n\n private _notifyUpdate = async (pkgJson: PackageJson): Promise<void> => {\n try {\n const latest = await latestVersion(pkgJson.name)\n const isOutdated = semver.lt(pkgJson.version, latest)\n if (isOutdated) {\n this.logger.box(UPDATE_MSG({ ...pkgJson, latest }))\n }\n } catch (thrown) {\n const err = errors.BotpressCLIError.map(thrown)\n this.logger.debug(`Failed to check for updates: ${err.message}`)\n }\n }\n\n private _readPackageJson = async (): Promise<PackageJson> => {\n const path = pathlib.join(this.globalPaths.abs.cliRootDir, 'package.json')\n const strContent = await fs.promises.readFile(path, 'utf8')\n const jsonContent = JSON.parse(strContent)\n return jsonContent\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["_", "chalk", "latestVersion", "semver", "fs"]
|
|
7
7
|
}
|
|
@@ -27,7 +27,7 @@ __export(command_implementations_exports, {
|
|
|
27
27
|
default: () => command_implementations_default
|
|
28
28
|
});
|
|
29
29
|
module.exports = __toCommonJS(command_implementations_exports);
|
|
30
|
-
var
|
|
30
|
+
var import_client = require("../api/client");
|
|
31
31
|
var import_logger = require("../logger");
|
|
32
32
|
var utils = __toESM(require("../utils"));
|
|
33
33
|
var import_add_command = require("./add-command");
|
|
@@ -45,7 +45,7 @@ var import_serve_command = require("./serve-command");
|
|
|
45
45
|
const getHandler = (cls) => async (argv) => {
|
|
46
46
|
const logger = new import_logger.Logger(argv);
|
|
47
47
|
const prompt = new utils.prompt.CLIPrompt(argv, logger);
|
|
48
|
-
return new cls(
|
|
48
|
+
return new cls(import_client.ApiClient, prompt, logger, argv).handler();
|
|
49
49
|
};
|
|
50
50
|
var command_implementations_default = {
|
|
51
51
|
login: getHandler(import_login_command.LoginCommand),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/command-implementations/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { ApiClient } from '../api
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { ApiClient } from '../api/client'\nimport type commandDefinitions from '../command-definitions'\nimport type { ImplementationTree } from '../command-tree'\nimport { Logger } from '../logger'\nimport type { CommandArgv } from '../typings'\nimport * as utils from '../utils'\nimport { AddCommand } from './add-command'\nimport type { BaseCommand } from './base-command'\nimport * as bots from './bot-commands'\nimport { BuildCommand } from './build-command'\nimport { BundleCommand } from './bundle-command'\nimport { DeployCommand } from './deploy-command'\nimport { DevCommand } from './dev-command'\nimport { GenerateCommand } from './gen-command'\nimport type { GlobalCommand, GlobalCommandDefinition } from './global-command'\nimport { InitCommand } from './init-command'\nimport * as integrations from './integration-commands'\nimport { LoginCommand } from './login-command'\nimport { LogoutCommand } from './logout-command'\nimport { ServeCommand } from './serve-command'\n\ntype GlobalCtor<C extends GlobalCommandDefinition> = new (\n ...args: ConstructorParameters<typeof GlobalCommand<C>>\n) => BaseCommand<C>\n\nconst getHandler =\n <C extends GlobalCommandDefinition>(cls: GlobalCtor<C>) =>\n async (argv: CommandArgv<C>) => {\n const logger = new Logger(argv)\n const prompt = new utils.prompt.CLIPrompt(argv, logger)\n return new cls(ApiClient, prompt, logger, argv).handler()\n }\n\nexport default {\n login: getHandler(LoginCommand),\n logout: getHandler(LogoutCommand),\n bots: {\n subcommands: {\n create: getHandler(bots.CreateBotCommand),\n get: getHandler(bots.GetBotCommand),\n delete: getHandler(bots.DeleteBotCommand),\n list: getHandler(bots.ListBotsCommand),\n },\n },\n integrations: {\n subcommands: {\n get: getHandler(integrations.GetIntegrationCommand),\n list: getHandler(integrations.ListIntegrationsCommand),\n delete: getHandler(integrations.DeleteIntegrationCommand),\n },\n },\n init: getHandler(InitCommand),\n generate: getHandler(GenerateCommand),\n bundle: getHandler(BundleCommand),\n build: getHandler(BuildCommand),\n serve: getHandler(ServeCommand),\n deploy: getHandler(DeployCommand),\n add: getHandler(AddCommand),\n dev: getHandler(DevCommand),\n} satisfies ImplementationTree<typeof commandDefinitions>\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA0B;AAG1B,oBAAuB;AAEvB,YAAuB;AACvB,yBAA2B;AAE3B,WAAsB;AACtB,2BAA6B;AAC7B,4BAA8B;AAC9B,4BAA8B;AAC9B,yBAA2B;AAC3B,yBAAgC;AAEhC,0BAA4B;AAC5B,mBAA8B;AAC9B,2BAA6B;AAC7B,4BAA8B;AAC9B,2BAA6B;AAM7B,MAAM,aACJ,CAAoC,QACpC,OAAO,SAAyB;AAC9B,QAAM,SAAS,IAAI,qBAAO,IAAI;AAC9B,QAAM,SAAS,IAAI,MAAM,OAAO,UAAU,MAAM,MAAM;AACtD,SAAO,IAAI,IAAI,yBAAW,QAAQ,QAAQ,IAAI,EAAE,QAAQ;AAC1D;AAEF,IAAO,kCAAQ;AAAA,EACb,OAAO,WAAW,iCAAY;AAAA,EAC9B,QAAQ,WAAW,mCAAa;AAAA,EAChC,MAAM;AAAA,IACJ,aAAa;AAAA,MACX,QAAQ,WAAW,KAAK,gBAAgB;AAAA,MACxC,KAAK,WAAW,KAAK,aAAa;AAAA,MAClC,QAAQ,WAAW,KAAK,gBAAgB;AAAA,MACxC,MAAM,WAAW,KAAK,eAAe;AAAA,IACvC;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ,aAAa;AAAA,MACX,KAAK,WAAW,aAAa,qBAAqB;AAAA,MAClD,MAAM,WAAW,aAAa,uBAAuB;AAAA,MACrD,QAAQ,WAAW,aAAa,wBAAwB;AAAA,IAC1D;AAAA,EACF;AAAA,EACA,MAAM,WAAW,+BAAW;AAAA,EAC5B,UAAU,WAAW,kCAAe;AAAA,EACpC,QAAQ,WAAW,mCAAa;AAAA,EAChC,OAAO,WAAW,iCAAY;AAAA,EAC9B,OAAO,WAAW,iCAAY;AAAA,EAC9B,QAAQ,WAAW,mCAAa;AAAA,EAChC,KAAK,WAAW,6BAAU;AAAA,EAC1B,KAAK,WAAW,6BAAU;AAC5B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -85,12 +85,6 @@ class ProjectCommand extends import_global_command.GlobalCommand {
|
|
|
85
85
|
await import_fs.default.promises.writeFile(filePath, file.content);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
prepareIntegrations(botImpl, botInfo) {
|
|
89
|
-
const { integrations: integrationList } = botImpl.definition;
|
|
90
|
-
const integrationsToUninstall = (0, import_lodash.default)(botInfo.integrations).keys().filter((key) => !integrationList?.map((i) => i.id).includes(key)).zipObject().mapValues(() => null).value();
|
|
91
|
-
const integrationsToInstall = (0, import_lodash.default)(integrationList ?? []).keyBy((i) => i.id).mapValues(({ enabled, configuration }) => ({ enabled, configuration })).value();
|
|
92
|
-
return { ...integrationsToUninstall, ...integrationsToInstall };
|
|
93
|
-
}
|
|
94
88
|
displayWebhookUrls(bot) {
|
|
95
89
|
if (!import_lodash.default.keys(bot.integrations).length) {
|
|
96
90
|
this.logger.debug("No integrations in bot");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/command-implementations/project-command.ts"],
|
|
4
|
-
"sourcesContent": ["import type * as bpclient from '@botpress/client'\nimport type
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAAkB;AAClB,gBAAe;AACf,oBAAc;AACd,kBAAoB;AACpB,cAAyB;AAEzB,aAAwB;AACxB,aAAwB;AAExB,YAAuB;AACvB,4BAA8B;
|
|
4
|
+
"sourcesContent": ["import type * as bpclient from '@botpress/client'\nimport type * as bpsdk from '@botpress/sdk'\nimport type { YargsConfig } from '@bpinternal/yargs-extra'\nimport chalk from 'chalk'\nimport fs from 'fs'\nimport _ from 'lodash'\nimport pathlib from 'path'\nimport * as codegen from '../code-generation'\nimport type * as config from '../config'\nimport * as consts from '../consts'\nimport * as errors from '../errors'\nimport type { CommandArgv, CommandDefinition } from '../typings'\nimport * as utils from '../utils'\nimport { GlobalCommand } from './global-command'\n\nexport type ProjectCommandDefinition = CommandDefinition<typeof config.schemas.project>\nexport type ProjectCache = { botId: string; devId: string }\n\ntype ConfigurableProjectPaths = { entryPoint: string; outDir: string; workDir: string }\ntype ConstantProjectPaths = typeof consts.fromOutDir & typeof consts.fromWorkDir\ntype AllProjectPaths = ConfigurableProjectPaths & ConstantProjectPaths\n\nclass ProjectPaths extends utils.path.PathStore<keyof AllProjectPaths> {\n public constructor(argv: CommandArgv<ProjectCommandDefinition>) {\n const absWorkDir = utils.path.absoluteFrom(utils.path.cwd(), argv.workDir)\n const absEntrypoint = utils.path.absoluteFrom(absWorkDir, argv.entryPoint)\n const absOutDir = utils.path.absoluteFrom(absWorkDir, argv.outDir)\n super({\n workDir: absWorkDir,\n entryPoint: absEntrypoint,\n outDir: absOutDir,\n ..._.mapValues(consts.fromOutDir, (p) => utils.path.absoluteFrom(absOutDir, p)),\n ..._.mapValues(consts.fromWorkDir, (p) => utils.path.absoluteFrom(absWorkDir, p)),\n })\n }\n}\n\nexport abstract class ProjectCommand<C extends ProjectCommandDefinition> extends GlobalCommand<C> {\n protected get projectPaths() {\n return new ProjectPaths(this.argv)\n }\n\n protected get projectCache() {\n return new utils.cache.FSKeyValueCache<ProjectCache>(this.projectPaths.abs.projectCacheFile)\n }\n\n protected async readIntegrationDefinitionFromFS(): Promise<bpsdk.IntegrationDefinition | undefined> {\n const abs = this.projectPaths.abs\n const rel = this.projectPaths.rel('workDir')\n\n if (!fs.existsSync(abs.definition)) {\n this.logger.debug(`Integration definition not found at ${rel.definition}`)\n return\n }\n\n const { outputFiles } = await utils.esbuild.buildEntrypoint({\n cwd: abs.workDir,\n outfile: '',\n entrypoint: rel.definition,\n write: false,\n })\n\n const artifact = outputFiles[0]\n if (!artifact) {\n throw new errors.BotpressCLIError('Could not read integration definition')\n }\n\n const { default: definition } = utils.require.requireJsCode<{ default: bpsdk.IntegrationDefinition }>(artifact.text)\n return definition\n }\n\n protected async writeGeneratedFilesToOutFolder(files: codegen.File[]) {\n for (const file of files) {\n const filePath = utils.path.absoluteFrom(this.projectPaths.abs.outDir, file.path)\n const dirPath = pathlib.dirname(filePath)\n await fs.promises.mkdir(dirPath, { recursive: true })\n await fs.promises.writeFile(filePath, file.content)\n }\n }\n\n protected displayWebhookUrls(bot: bpclient.Bot) {\n if (!_.keys(bot.integrations).length) {\n this.logger.debug('No integrations in bot')\n return\n }\n\n this.logger.log('Integrations:')\n for (const integration of Object.values(bot.integrations)) {\n if (!integration.enabled) {\n this.logger.log(`${chalk.grey(integration.name)} ${chalk.italic('(disabled)')}: ${integration.webhookUrl}`, {\n prefix: { symbol: '\u25CB', indent: 2 },\n })\n } else {\n this.logger.log(`${chalk.bold(integration.name)} : ${integration.webhookUrl}`, {\n prefix: { symbol: '\u25CF', indent: 2 },\n })\n }\n }\n }\n\n protected async promptSecrets(\n integrationDef: bpsdk.IntegrationDefinition,\n argv: YargsConfig<typeof config.schemas.secrets>\n ): Promise<Record<string, string>> {\n const { secrets: secretDefinitions } = integrationDef\n if (!secretDefinitions) {\n return {}\n }\n\n const secretArgv = this._parseArgvSecrets(argv.secrets)\n const invalidSecret = Object.keys(secretArgv).find((s) => !secretDefinitions.includes(s))\n if (invalidSecret) {\n throw new errors.BotpressCLIError(`Secret ${invalidSecret} is not defined in integration definition`)\n }\n\n const values: Record<string, string> = {}\n for (const secretDef of secretDefinitions) {\n const argvSecret = secretArgv[secretDef]\n if (argvSecret) {\n this.logger.debug(`Using secret \"${secretDef}\" from argv`)\n values[secretDef] = argvSecret\n continue\n }\n\n const prompted = await this.prompt.text(`Enter value for secret \"${secretDef}\"`)\n if (!prompted) {\n throw new errors.BotpressCLIError('Secret is required')\n }\n values[secretDef] = prompted\n }\n\n const envVariables = _.mapKeys(values, (_v, k) => codegen.secretEnvVariableName(k))\n return envVariables\n }\n\n private _parseArgvSecrets(argvSecrets: string[]): Record<string, string> {\n const parsed: Record<string, string> = {}\n for (const secret of argvSecrets) {\n const [key, value] = this._splitOnce(secret, '=')\n if (!value) {\n throw new errors.BotpressCLIError(\n `Secret \"${key}\" is missing a value. Expected format: \"SECRET_NAME=secretValue\"`\n )\n }\n parsed[key!] = value\n }\n\n return parsed\n }\n\n private _splitOnce = (text: string, separator: string): [string, string | undefined] => {\n const index = text.indexOf(separator)\n if (index === -1) {\n return [text, undefined]\n }\n return [text.slice(0, index), text.slice(index + 1)]\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["_", "fs", "pathlib", "chalk"]
|
|
7
7
|
}
|
|
@@ -18,10 +18,11 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var record_utils_exports = {};
|
|
20
20
|
__export(record_utils_exports, {
|
|
21
|
-
|
|
21
|
+
setNullOnMissingValues: () => setNullOnMissingValues,
|
|
22
|
+
zipObjects: () => zipObjects
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(record_utils_exports);
|
|
24
|
-
const
|
|
25
|
+
const setNullOnMissingValues = (record = {}, oldRecord = {}) => {
|
|
25
26
|
const newRecord = {};
|
|
26
27
|
for (const [key, value] of Object.entries(record)) {
|
|
27
28
|
newRecord[key] = value;
|
|
@@ -33,8 +34,17 @@ const setOnNullMissingValues = (record = {}, oldRecord = {}) => {
|
|
|
33
34
|
}
|
|
34
35
|
return newRecord;
|
|
35
36
|
};
|
|
37
|
+
const zipObjects = (recordA, recordB) => {
|
|
38
|
+
const allKeys = /* @__PURE__ */ new Set([...Object.keys(recordA), ...Object.keys(recordB)]);
|
|
39
|
+
const newRecord = {};
|
|
40
|
+
for (const key of allKeys) {
|
|
41
|
+
newRecord[key] = [recordA[key] ?? null, recordB[key] ?? null];
|
|
42
|
+
}
|
|
43
|
+
return newRecord;
|
|
44
|
+
};
|
|
36
45
|
// Annotate the CommonJS export names for ESM import in node:
|
|
37
46
|
0 && (module.exports = {
|
|
38
|
-
|
|
47
|
+
setNullOnMissingValues,
|
|
48
|
+
zipObjects
|
|
39
49
|
});
|
|
40
50
|
//# sourceMappingURL=record-utils.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/record-utils.ts"],
|
|
4
|
-
"sourcesContent": ["export const
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,yBAAyB,CACpC,SAA4B,CAAC,GAC7B,YAA+B,CAAC,MACH;AAC7B,QAAM,YAAsC,CAAC;AAE7C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,cAAU,OAAO;AAAA,EACnB;AAEA,aAAW,SAAS,OAAO,KAAK,SAAS,GAAG;AAC1C,QAAI,CAAC,OAAO,QAAQ;AAClB,gBAAU,SAAS;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
4
|
+
"sourcesContent": ["export const setNullOnMissingValues = <A, B>(\n record: Record<string, A> = {},\n oldRecord: Record<string, B> = {}\n): Record<string, A | null> => {\n const newRecord: Record<string, A | null> = {}\n\n for (const [key, value] of Object.entries(record)) {\n newRecord[key] = value\n }\n\n for (const value of Object.keys(oldRecord)) {\n if (!record[value]) {\n newRecord[value] = null\n }\n }\n\n return newRecord\n}\n\nexport const zipObjects = <A, B>(\n recordA: Record<string, A>,\n recordB: Record<string, B>\n): Record<string, [A | null, B | null]> => {\n const allKeys = new Set([...Object.keys(recordA), ...Object.keys(recordB)])\n const newRecord: Record<string, [A | null, B | null]> = {}\n\n for (const key of allKeys) {\n newRecord[key] = [recordA[key] ?? null, recordB[key] ?? null]\n }\n\n return newRecord\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,yBAAyB,CACpC,SAA4B,CAAC,GAC7B,YAA+B,CAAC,MACH;AAC7B,QAAM,YAAsC,CAAC;AAE7C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,cAAU,OAAO;AAAA,EACnB;AAEA,aAAW,SAAS,OAAO,KAAK,SAAS,GAAG;AAC1C,QAAI,CAAC,OAAO,QAAQ;AAClB,gBAAU,SAAS;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,MAAM,aAAa,CACxB,SACA,YACyC;AACzC,QAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,OAAO,GAAG,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC;AAC1E,QAAM,YAAkD,CAAC;AAEzD,aAAW,OAAO,SAAS;AACzB,cAAU,OAAO,CAAC,QAAQ,QAAQ,MAAM,QAAQ,QAAQ,IAAI;AAAA,EAC9D;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
18
|
+
mod
|
|
19
|
+
));
|
|
20
|
+
var import_vitest = require("vitest");
|
|
21
|
+
var recordUtils = __toESM(require("./record-utils"));
|
|
22
|
+
(0, import_vitest.test)("zip objects should return both values only when key is defined in both objects", () => {
|
|
23
|
+
const objA = { a: 1, b: 2, c: 3 };
|
|
24
|
+
const objB = { c: 4, d: 5 };
|
|
25
|
+
const zipped = recordUtils.zipObjects(objA, objB);
|
|
26
|
+
const expected = {
|
|
27
|
+
a: [1, null],
|
|
28
|
+
b: [2, null],
|
|
29
|
+
c: [3, 4],
|
|
30
|
+
d: [null, 5]
|
|
31
|
+
};
|
|
32
|
+
(0, import_vitest.expect)(zipped).toEqual(expected);
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=record-utils.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/record-utils.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { test, expect } from 'vitest'\nimport * as recordUtils from './record-utils'\n\ntest('zip objects should return both values only when key is defined in both objects', () => {\n const objA = { a: 1, b: 2, c: 3 }\n const objB = { c: 4, d: 5 }\n\n const zipped = recordUtils.zipObjects(objA, objB)\n\n const expected = {\n a: [1, null],\n b: [2, null],\n c: [3, 4],\n d: [null, 5],\n }\n\n expect(zipped).toEqual(expected)\n})\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA,oBAA6B;AAC7B,kBAA6B;AAAA,IAE7B,oBAAK,kFAAkF,MAAM;AAC3F,QAAM,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAChC,QAAM,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE;AAE1B,QAAM,SAAS,YAAY,WAAW,MAAM,IAAI;AAEhD,QAAM,WAAW;AAAA,IACf,GAAG,CAAC,GAAG,IAAI;AAAA,IACX,GAAG,CAAC,GAAG,IAAI;AAAA,IACX,GAAG,CAAC,GAAG,CAAC;AAAA,IACR,GAAG,CAAC,MAAM,CAAC;AAAA,EACb;AAEA,4BAAO,MAAM,EAAE,QAAQ,QAAQ;AACjC,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botpress/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Botpress CLI",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "pnpm run bundle && pnpm run template:gen",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"main": "dist/index.js",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@botpress/client": "0.
|
|
23
|
+
"@botpress/client": "0.2.0",
|
|
24
24
|
"@bpinternal/tunnel": "^0.1.0",
|
|
25
25
|
"@bpinternal/yargs-extra": "^0.0.3",
|
|
26
26
|
"@parcel/watcher": "^2.1.0",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"zod-to-json-schema": "^3.20.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@botpress/sdk": "0.1.
|
|
50
|
+
"@botpress/sdk": "0.1.6",
|
|
51
51
|
"@bpinternal/log4bot": "^0.0.4",
|
|
52
52
|
"@types/bluebird": "^3.5.38",
|
|
53
53
|
"@types/prompts": "^2.0.14",
|
package/dist/api-client.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/api-client.ts"],
|
|
4
|
-
"sourcesContent": ["import { Client, Integration, isApiError } from '@botpress/client'\nimport _ from 'lodash'\nimport { formatIntegrationRef, IntegrationRef } from './integration-ref'\nimport type { Logger } from './logger'\n\nexport type PageLister<R extends object> = (t: { nextToken?: string }) => Promise<R & { meta: { nextToken?: string } }>\n\nexport type ApiClientProps = {\n apiUrl: string\n token: string\n workspaceId?: string\n}\n\nexport type ApiClientFactory = {\n newClient: (props: ApiClientProps, logger: Logger) => ApiClient\n}\n\n/**\n * This class is used to wrap the Botpress API and provide a more convenient way to interact with it.\n */\nexport class ApiClient {\n public readonly client: Client\n public readonly url: string\n public readonly token: string\n public readonly workspaceId?: string\n\n public static newClient = (props: ApiClientProps, logger: Logger) => new ApiClient(props, logger)\n\n public constructor(props: ApiClientProps, private _logger: Logger) {\n const { apiUrl, token, workspaceId } = props\n this.client = new Client({ host: apiUrl, token, workspaceId })\n this.url = apiUrl\n this.token = token\n this.workspaceId = workspaceId\n }\n\n public async findIntegration(ref: IntegrationRef): Promise<Integration | undefined> {\n const formatted = formatIntegrationRef(ref)\n\n const privateIntegration = await this.findPrivateIntegration(ref)\n if (privateIntegration) {\n this._logger.debug(`Found integration \"${formatted}\" in workspace`)\n return privateIntegration\n }\n\n const publicIntegration = await this.findPublicIntegration(ref)\n if (publicIntegration) {\n this._logger.debug(`Found integration \"${formatted}\" in hub`)\n return publicIntegration\n }\n\n return\n }\n\n public async findPrivateIntegration(ref: IntegrationRef): Promise<Integration | undefined> {\n if (ref.type === 'id') {\n return this.validateStatus(() => this.client.getIntegration(ref).then((r) => r.integration), [404, 500]) // TODO: fix that\n }\n return this.validateStatus(() => this.client.getIntegrationByName(ref).then((r) => r.integration), [404, 500])\n }\n\n public async findPublicIntegration(ref: IntegrationRef): Promise<Integration | undefined> {\n if (ref.type === 'id') {\n return this.validateStatus(() => this.client.getPublicIntegrationById(ref).then((r) => r.integration), [404, 500])\n }\n return this.validateStatus(() => this.client.getPublicIntegration(ref).then((r) => r.integration), [404, 500])\n }\n\n public async testLogin(): Promise<void> {\n await this.client.listBots({})\n }\n\n public async listAllPages<R extends object>(lister: PageLister<R>): Promise<R[]>\n public async listAllPages<R extends object, M>(lister: PageLister<R>, mapper?: (r: R) => M[]): Promise<M[]>\n public async listAllPages<R extends object, M>(lister: PageLister<R>, mapper?: (r: R) => M[]) {\n let nextToken: string | undefined\n const all: R[] = []\n\n do {\n const { meta, ...r } = await lister({ nextToken })\n all.push(r as R)\n nextToken = meta.nextToken\n } while (nextToken)\n\n if (!mapper) {\n return all\n }\n\n const mapped: M[] = all.flatMap((r) => mapper(r))\n return mapped\n }\n\n public async validateStatus<V>(fn: () => Promise<V>, allowedStatuses: number | number[]): Promise<V | undefined> {\n try {\n const v = await fn()\n return v\n } catch (err) {\n const allowedStatusesArray = _.isArray(allowedStatuses) ? allowedStatuses : [allowedStatuses]\n const isAllowed = isApiError(err) && err.code && allowedStatusesArray.includes(err.code)\n if (isAllowed) {\n return\n }\n throw err\n }\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAgD;AAChD,oBAAc;AACd,6BAAqD;AAkB9C,MAAM,UAAU;AAAA,EAQd,YAAY,OAA+B,SAAiB;AAAjB;AAChD,UAAM,EAAE,QAAQ,OAAO,YAAY,IAAI;AACvC,SAAK,SAAS,IAAI,qBAAO,EAAE,MAAM,QAAQ,OAAO,YAAY,CAAC;AAC7D,SAAK,MAAM;AACX,SAAK,QAAQ;AACb,SAAK,cAAc;AAAA,EACrB;AAAA,EAbgB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,OAAc,YAAY,CAAC,OAAuB,WAAmB,IAAI,UAAU,OAAO,MAAM;AAAA,EAUhG,MAAa,gBAAgB,KAAuD;AAClF,UAAM,gBAAY,6CAAqB,GAAG;AAE1C,UAAM,qBAAqB,MAAM,KAAK,uBAAuB,GAAG;AAChE,QAAI,oBAAoB;AACtB,WAAK,QAAQ,MAAM,sBAAsB,yBAAyB;AAClE,aAAO;AAAA,IACT;AAEA,UAAM,oBAAoB,MAAM,KAAK,sBAAsB,GAAG;AAC9D,QAAI,mBAAmB;AACrB,WAAK,QAAQ,MAAM,sBAAsB,mBAAmB;AAC5D,aAAO;AAAA,IACT;AAEA;AAAA,EACF;AAAA,EAEA,MAAa,uBAAuB,KAAuD;AACzF,QAAI,IAAI,SAAS,MAAM;AACrB,aAAO,KAAK,eAAe,MAAM,KAAK,OAAO,eAAe,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,KAAK,GAAG,CAAC;AAAA,IACzG;AACA,WAAO,KAAK,eAAe,MAAM,KAAK,OAAO,qBAAqB,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,KAAK,GAAG,CAAC;AAAA,EAC/G;AAAA,EAEA,MAAa,sBAAsB,KAAuD;AACxF,QAAI,IAAI,SAAS,MAAM;AACrB,aAAO,KAAK,eAAe,MAAM,KAAK,OAAO,yBAAyB,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,KAAK,GAAG,CAAC;AAAA,IACnH;AACA,WAAO,KAAK,eAAe,MAAM,KAAK,OAAO,qBAAqB,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,KAAK,GAAG,CAAC;AAAA,EAC/G;AAAA,EAEA,MAAa,YAA2B;AACtC,UAAM,KAAK,OAAO,SAAS,CAAC,CAAC;AAAA,EAC/B;AAAA,EAIA,MAAa,aAAkC,QAAuB,QAAwB;AAC5F,QAAI;AACJ,UAAM,MAAW,CAAC;AAElB,OAAG;AACD,YAAM,EAAE,SAAS,EAAE,IAAI,MAAM,OAAO,EAAE,UAAU,CAAC;AACjD,UAAI,KAAK,CAAM;AACf,kBAAY,KAAK;AAAA,IACnB,SAAS;AAET,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,UAAM,SAAc,IAAI,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC;AAChD,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,eAAkB,IAAsB,iBAA4D;AAC/G,QAAI;AACF,YAAM,IAAI,MAAM,GAAG;AACnB,aAAO;AAAA,IACT,SAAS,KAAP;AACA,YAAM,uBAAuB,cAAAA,QAAE,QAAQ,eAAe,IAAI,kBAAkB,CAAC,eAAe;AAC5F,YAAM,gBAAY,0BAAW,GAAG,KAAK,IAAI,QAAQ,qBAAqB,SAAS,IAAI,IAAI;AACvF,UAAI,WAAW;AACb;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;",
|
|
6
|
-
"names": ["_"]
|
|
7
|
-
}
|