@supernovaio/cli
Version:
Supernova.io Command Line Interface
182 lines (180 loc) • 7.97 kB
JavaScript
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="dc2c29e0-3517-5a15-a324-b7cb8343d2ad")}catch(e){}}();
import ansiEscapes from "ansi-escapes";
import { createPrompt, isDownKey, isEnterKey, isNumberKey, isSpaceKey, isUpKey, makeTheme, Separator, useKeypress, useMemo, usePagination, usePrefix, useRef, useState, ValidationError, } from "@inquirer/core";
import figures from "@inquirer/figures";
import colors from "yoctocolors-cjs";
const checkboxTheme = {
icon: {
checked: colors.green(figures.circleFilled),
unchecked: figures.circle,
cursor: figures.pointer,
},
style: {
disabledChoice: text => colors.dim(`- ${text}`),
renderSelectedChoices: selectedChoices => selectedChoices.map(choice => choice.short).join(", "),
description: text => colors.blue(text),
},
helpMode: "auto",
};
function isSelectable(item) {
return !Separator.isSeparator(item) && !item.disabled;
}
function isChecked(item) {
return isSelectable(item) && Boolean(item.checked);
}
function toggle(item) {
return isSelectable(item) ? { ...item, checked: !item.checked } : item;
}
function check(checked) {
return function (item) {
return isSelectable(item) ? { ...item, checked } : item;
};
}
function normalizeChoices(choices) {
return choices.map(choice => {
if (Separator.isSeparator(choice)) {
return choice;
}
const name = choice.name ?? String(choice.value);
return {
value: choice.value,
name,
short: choice.short ?? name,
disabled: choice.disabled ?? false,
checked: choice.checked ?? false,
description: choice.description,
};
});
}
const implicitCheckbox = createPrompt((config, done) => {
const { instructions, pageSize = 7, loop = true, required, validate = () => true } = config;
const shortcuts = { all: "a", invert: "i", ...config.shortcuts };
const theme = makeTheme(checkboxTheme, undefined);
const firstRender = useRef(true);
const [status, setStatus] = useState("idle");
const [submittedItems, setSubmittedItems] = useState([]);
const prefix = usePrefix({ status, theme });
const [items, setItems] = useState(normalizeChoices(config.choices));
const bounds = useMemo(() => {
const first = items.findIndex(item => isSelectable(item));
const last = items.findLastIndex(item => isSelectable(item));
if (first === -1) {
throw new ValidationError("[checkbox prompt] No selectable choices. All choices are disabled.");
}
return { first, last };
}, [items]);
const [active, setActive] = useState(bounds.first);
const [showHelpTip, setShowHelpTip] = useState(true);
const [errorMsg, setError] = useState();
useKeypress(async (key) => {
if (isEnterKey(key)) {
const currentSelection = items.filter(item => isChecked(item));
const implicitSelection = currentSelection.length === 0 && isSelectable(items[active]) ? [items[active]] : currentSelection;
const isValid = await validate([...implicitSelection]);
if (required && implicitSelection.length === 0) {
setError("At least one choice must be selected");
}
else if (isValid === true) {
setSubmittedItems(implicitSelection);
setStatus("done");
done(implicitSelection.map(choice => choice.value));
}
else {
setError(isValid || "You must select a valid value");
}
}
else if (isUpKey(key) || isDownKey(key)) {
if (loop || (isUpKey(key) && active !== bounds.first) || (isDownKey(key) && active !== bounds.last)) {
const offset = isUpKey(key) ? -1 : 1;
let next = active;
do {
next = (next + offset + items.length) % items.length;
} while (!isSelectable(items[next]));
setActive(next);
}
}
else if (isSpaceKey(key)) {
setError(undefined);
setShowHelpTip(false);
setItems(items.map((choice, index) => (index === active ? toggle(choice) : choice)));
}
else if (key.name === shortcuts.all) {
const selectAll = items.some(choice => isSelectable(choice) && !choice.checked);
setItems(items.map(check(selectAll)));
}
else if (key.name === shortcuts.invert) {
setItems(items.map(choice => toggle(choice)));
}
else if (isNumberKey(key)) {
const position = Number(key.name) - 1;
const item = items[position];
if (item !== undefined && isSelectable(item)) {
setActive(position);
setItems(items.map((choice, index) => (index === position ? toggle(choice) : choice)));
}
}
});
const message = theme.style.message(config.message, status);
let description;
const page = usePagination({
items,
active,
renderItem({ item, isActive }) {
if (Separator.isSeparator(item)) {
return ` ${item.separator}`;
}
if (item.disabled) {
const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
return theme.style.disabledChoice(`${item.name} ${disabledLabel}`);
}
if (isActive) {
description = item.description;
}
const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked;
const color = isActive ? theme.style.highlight : (text) => text;
const cursor = isActive ? theme.icon.cursor : " ";
return color(`${cursor}${checkbox} ${item.name}`);
},
pageSize,
loop,
});
if (status === "done") {
const answer = theme.style.answer(theme.style.renderSelectedChoices(submittedItems, items));
return `${prefix} ${message} ${answer}`;
}
let helpTipTop = "";
let helpTipBottom = "";
if (theme.helpMode === "always" ||
(theme.helpMode === "auto" && showHelpTip && (instructions === undefined || instructions))) {
if (typeof instructions === "string") {
helpTipTop = instructions;
}
else {
const keys = [
`${theme.style.key("space")} to select`,
shortcuts.all ? `${theme.style.key(shortcuts.all)} to toggle all` : "",
shortcuts.invert ? `${theme.style.key(shortcuts.invert)} to invert selection` : "",
`and ${theme.style.key("enter")} to proceed`,
];
helpTipTop = ` (Press ${keys.filter(key => key !== "").join(", ")})`;
}
if (items.length > pageSize &&
(theme.helpMode === "always" || (theme.helpMode === "auto" && firstRender.current))) {
helpTipBottom = `\n${theme.style.help("(Use arrow keys to reveal more options)")}`;
firstRender.current = false;
}
}
const choiceDescription = description ? `\n${theme.style.description(description)}` : "";
const error = errorMsg ? `\n${theme.style.error(errorMsg)}` : "";
return `${prefix} ${message}${helpTipTop}\n${page}${helpTipBottom}${choiceDescription}${error}${ansiEscapes.cursorHide}`;
});
export async function promptImplicitCheckbox(config) {
return implicitCheckbox({
choices: config.choices,
message: config.message,
loop: false,
required: true,
});
}
//# sourceMappingURL=implicit-checkbox.js.map
//# debugId=dc2c29e0-3517-5a15-a324-b7cb8343d2ad