UNPKG

@supernovaio/cli

Version:

Supernova.io Command Line Interface

182 lines (180 loc) 7.97 kB
!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