speedybot
Version:
<p align="center"> <a href="https://github.com/valgaze/speedybot"> <img src="https://img.shields.io/npm/v/speedybot.svg" /> </a> <a href="https://github.com/valgaze/speedybot"> <img src="https://img.shields.io/npm/dm/speedybot.svg" /> </a>
465 lines • 16.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SpeedyCard = exports.SpeedyCardId = exports.checkers = void 0;
const index_1 = require("./index");
exports.checkers = {
isSpeedyCard(input) {
return (typeof input === "object" &&
"build" in input &&
typeof input.build === "function");
},
isCard(cardCandidate) {
if (this.isSpeedyCard(cardCandidate)) {
return true;
}
return ("$schema" in cardCandidate &&
"type" in cardCandidate &&
"version" in cardCandidate);
},
isEmail(candidate) {
const res = candidate.includes("@") && candidate.includes(".");
return res;
},
};
exports.SpeedyCardId = {
dropdown: "addPickerDropdown_result",
};
class SpeedyCard {
constructor() {
this.json = {
$schema: "http://adaptivecards.io/schemas/adaptive-card.json",
type: "AdaptiveCard",
version: "1.0",
body: [],
};
this.tools = {
checkColor(candidate) {
const colorMapping = {
default: "Default",
dark: "Dark",
light: "Light",
accent: "Accent",
good: "Good",
warning: "Warning",
attention: "Attention",
blue: "Accent",
red: "Attention",
green: "Good",
yellow: "Warning",
};
const lowerCaseInput = candidate.toLowerCase();
return colorMapping[lowerCaseInput] || "Default";
},
};
this._stash = {
needsSubmit: false,
title: "",
subTitle: "",
chips: [],
data: {},
submitLabel: "Submit",
};
this.id = {};
}
needsSubmit() {
return Boolean(this._stash.needsSubmit);
}
checkId(id = "") {
if (id in this.id) {
this.id[id]++;
const num = this.id[id];
const modifiedId = `${id}_${num}`;
return modifiedId;
}
else {
this.id[id] = 1;
return id;
}
}
addTitle(title) {
this._stash.title = title;
return this;
}
addSubtitle(subTitle) {
this._stash.subTitle = subTitle;
return this;
}
addTable(input, separator = false) {
const payload = {
type: "FactSet",
separator,
facts: Array.isArray(input)
? input.map(([label, value]) => ({ title: label, value }))
: Object.entries(input).map(([label, value]) => ({
title: label,
value,
})),
};
this.json.body.push(payload);
return this;
}
addChip(payload, id = index_1.CONSTANTS.CHIP_LABEL) {
return this.addChips([payload], id);
}
addChips(chips, id = index_1.CONSTANTS.CHIP_LABEL) {
const chipPayload = chips.map((chip) => {
let chipLabel = "";
let chipAction = "";
if (typeof chip === "string") {
chipLabel = chip;
chipAction = chip;
}
else {
const { title, value = "" } = chip;
chipLabel = title;
if (value) {
chipAction = value;
}
else {
chipAction = title;
}
}
const payload = {
type: "Action.Submit",
title: chipLabel,
data: {
[id]: chipAction,
},
};
return payload;
});
this.json.actions = this.json.actions
? this.json.actions.concat(chipPayload)
: chipPayload;
return this;
}
addImage(url, config = {}) {
var _a, _b;
if (url) {
const payload = {
horizontalAlignment: (_a = config.align) !== null && _a !== void 0 ? _a : "Center",
size: (_b = config.size) !== null && _b !== void 0 ? _b : "ExtraLarge",
type: "Image",
url,
};
if (config.targetURL) {
const linkPayload = {
type: "Action.OpenUrl",
style: "positive",
isPrimary: true,
url: config.targetURL,
};
payload.selectAction = linkPayload;
}
this.json.body.push(payload);
}
return this;
}
addLink(url, label) {
return this.addText(`**[${label || url}](${url})**`);
}
addLinkButton(url, label) {
const id = String(Math.random()).slice(3);
const cleanId = this.checkId(id);
const payload = {
type: "Action.OpenUrl",
id: cleanId,
title: label !== null && label !== void 0 ? label : url,
url: url,
};
this.addAction(payload);
return this;
}
addText(text, config = {}) {
const { bold = false, size = "Medium", align = "Left", color, backgroundColor, vertAlign, } = config;
const payload = Object.assign(Object.assign({ type: "TextBlock", text: text, wrap: true, size, horizontalAlignment: align }, (color && { color: this.tools.checkColor(color) })), (bold && { weight: "Bolder" }));
if (backgroundColor || vertAlign) {
const containerPayload = Object.assign(Object.assign(Object.assign({ type: "Container", height: "stretch", items: [payload] }, (backgroundColor && {
style: this.tools.checkColor(backgroundColor),
})), (color && { color: this.tools.checkColor(color) })), (vertAlign && {
verticalContentAlignment: vertAlign,
}));
this.json.body.push(containerPayload);
}
else {
this.json.body.push(payload);
}
return this;
}
addHeader(text, config = {}) {
var _a, _b, _c, _d;
const hasURL = (_a = config.iconURL) === null || _a === void 0 ? void 0 : _a.includes("http");
const textPayload = {
items: [
Object.assign(Object.assign(Object.assign({ type: "TextBlock", text: text, wrap: true, size: config.textSize || "Large", horizontalAlignment: ((_b = config.textAlign) !== null && _b !== void 0 ? _b : config.rtl) ? "Right" : "Left" }, (config.textColor && {
color: this.tools.checkColor(config.textColor),
})), { verticalContentAlignment: "Center" }), (config.backgroundColor && {
style: this.tools.checkColor(config.backgroundColor),
})),
],
};
const iconPayload = config.iconURL
? hasURL
? {
width: "32px",
items: [
Object.assign(Object.assign({ type: "Image", horizontalAlignment: (_c = config.iconAlignment) !== null && _c !== void 0 ? _c : "Left", url: config.iconURL }, (config.iconRound && { style: "person" })), { width: `${(_d = config.iconWidth) !== null && _d !== void 0 ? _d : "16"}px` }),
],
}
: {
type: "Column",
width: "auto",
items: [
{
type: "TextBlock",
text: config.iconURL,
verticalContentAlignment: "Center",
},
],
}
: null;
const headerPayload = {
type: "ColumnSet",
columns: config.rtl
? [textPayload, iconPayload].filter(Boolean)
: [iconPayload, textPayload].filter(Boolean),
};
this._stash.header = headerPayload;
return this;
}
addBlock(content, config = {}) {
if (typeof content === "string") {
return this.addText(content, config);
}
if (content instanceof SpeedyCard) {
const { backgroundColor, vertAlign } = config;
const { body } = content.build();
const containerPayload = Object.assign(Object.assign(Object.assign(Object.assign({}, (config.separator && { separator: config.separator })), { type: "Container", height: "stretch", items: body }), (backgroundColor && {
style: this.tools.checkColor(backgroundColor),
})), (vertAlign && {
verticalContentAlignment: vertAlign,
}));
this._stash.needsSubmit = !this._stash.needsSubmit
? content.needsSubmit()
: this._stash.needsSubmit;
this.json.body.push(containerPayload);
}
return this;
}
addSubcard(card, textLabel = "") {
const subCard = {
type: "Action.ShowCard",
title: textLabel,
card: "build" in card && typeof card.build === "function"
? card.build()
: card,
};
this.addAction(subCard);
return this;
}
addPickerDropdown(choices, id = exports.SpeedyCardId.dropdown) {
const cleanId = this.checkId(id);
this._stash.needsSubmit = true;
const formattedChoices = choices.map((choice, idx) => {
if (typeof choice === "object") {
return choice;
}
return {
title: String(choice),
value: String(choice),
};
});
const payload = {
type: "Input.ChoiceSet",
id: cleanId,
value: "0",
isMultiSelect: false,
isVisible: true,
choices: formattedChoices,
};
this.json.body.push(payload);
return this;
}
addSingleSelect(choices, id = "addSingleSelectresult") {
return this.addSelect(choices, id, {
isMultiSelect: false,
style: "expanded",
});
}
addMultiSelect(choices, id = "addMultiSelect_result") {
return this.addSelect(choices, id, { isMultiSelect: true });
}
addSelect(choices, id, config = {}) {
this._stash.needsSubmit = true;
const cleanId = this.checkId(id);
let formattedChoices;
if (Array.isArray(choices) && typeof choices[0] === "string") {
formattedChoices = choices.map((choice) => ({
title: String(choice),
value: String(choice),
}));
}
else {
formattedChoices = choices;
}
const payload = Object.assign(Object.assign({ type: "Input.ChoiceSet", id: cleanId, value: "0", isMultiSelect: Boolean(config.isMultiSelect), isVisible: true }, (config.style && { style: "expanded" })), { choices: formattedChoices, style: "expanded" });
this.json.body.push(payload);
return this;
}
addPickerDate(textLabel, id = "addPickerDate_result") {
this._stash.needsSubmit = true;
const cleanId = this.checkId(id);
const textPayload = this.buildTextPayload(textLabel);
const datePicker = {
type: "Input.Date",
id: cleanId,
};
this.json.body.push(textPayload, datePicker);
return this;
}
addPickerTime(textLabel, id = "addPickerTime_result") {
this._stash.needsSubmit = true;
const cleanId = this.checkId(id);
const textPayload = this.buildTextPayload(textLabel);
const timePicker = {
type: "Input.Time",
id: cleanId,
};
this.json.body.push(textPayload, timePicker);
return this;
}
addTextInput(placeholder, id = "addTextInput_result") {
this._stash.needsSubmit = true;
const cleanId = this.checkId(id);
const payload = {
id: cleanId,
placeholder,
type: "Input.Text",
};
this.json.body.push(payload);
return this;
}
addTextarea(placeholder, id = "addTextarea_result") {
this._stash.needsSubmit = true;
const cleanId = this.checkId(id);
const payload = {
id: cleanId,
placeholder,
type: "Input.Text",
isMultiline: true,
};
this.json.body.push(payload);
return this;
}
setBackgroundImage(url) {
this.json.backgroundImage = url;
return this;
}
setSubmitButtonTitle(label) {
this._stash.submitLabel = label;
return this;
}
attachData(payload) {
this._stash.needsSubmit = true;
this._stash.data = payload;
return this;
}
buildTextPayload(text, textConfig = {}) {
const payload = Object.assign({ type: "TextBlock", text, size: "Medium", isSubtle: true, wrap: true, weight: "Lighter" }, textConfig);
return payload;
}
addAction(a) {
if (!this.json.actions) {
this.json.actions = [];
}
this.json.actions.push(a);
}
addDeleteButton(label = index_1.CONSTANTS.destroyLabel) {
return this.addButton(label, index_1.CONSTANTS.submitToken, index_1.CONSTANTS.action_delete);
}
addButton(label, id = "button_result", attachedData = {}) {
const payload = {
type: "Action.Submit",
title: label,
data: {
[id]: attachedData,
},
};
this.addAction(payload);
return this;
}
survey(questions, title = "📝 Survey") {
const card = new SpeedyCard();
card.addHeader(title);
questions.forEach((question, idx) => {
let id = question.id || `question_${idx + 1}`;
switch (question.type) {
case "text":
card.addTextInput(question.question, id);
break;
case "single-select":
card.addText(question.question);
card.addSingleSelect(question.choices || [], id);
break;
case "multi-select":
card.addText(question.question);
card.addMultiSelect(question.choices || [], id);
break;
case "picker-dropdown":
card.addText(question.question);
card.addPickerDropdown(question.choices || [], id);
break;
case "picker-date":
card.addPickerDate(question.question, id);
break;
case "picker-time":
card.addPickerTime(question.question, id);
break;
case "textarea":
card.addTextarea(question.question, id);
break;
}
});
return card;
}
build() {
const json = JSON.parse(JSON.stringify(this.json));
const needsSubmit = this._stash.needsSubmit;
if (this._stash.subTitle) {
json.body.unshift(this.buildTextPayload(this._stash.subTitle));
}
if (this._stash.title) {
json.body.unshift(this.buildTextPayload(this._stash.title, {
weight: "Bolder",
size: "ExtraLarge",
}));
}
if (needsSubmit) {
const payload = {
type: "Action.Submit",
title: this._stash.submitLabel,
};
if (this._stash.data && Object.keys(this._stash.data).length > 0) {
payload.data = this._stash.data;
}
if (!json.actions) {
json.actions = [];
}
json.actions.push(payload);
}
const hasHeader = Boolean(this._stash.header);
if (hasHeader) {
json.body = [
this._stash.header,
{
separator: true,
type: "Container",
items: json.body,
},
];
}
return json;
}
}
exports.SpeedyCard = SpeedyCard;
//# sourceMappingURL=cards.js.map