Deployed the page to Github Pages.
This commit is contained in:
parent
1d79754e93
commit
2c89899458
62797 changed files with 6551425 additions and 15279 deletions
22
node_modules/@inquirer/checkbox/LICENSE
generated
vendored
Normal file
22
node_modules/@inquirer/checkbox/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2023 Simon Boudrias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
160
node_modules/@inquirer/checkbox/README.md
generated
vendored
Normal file
160
node_modules/@inquirer/checkbox/README.md
generated
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
# `@inquirer/checkbox`
|
||||
|
||||
Simple interactive command line prompt to display a list of checkboxes (multi select).
|
||||
|
||||

|
||||
|
||||
# Installation
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>npm</th>
|
||||
<th>yarn</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
npm install @inquirer/prompts
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
yarn add @inquirer/prompts
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colSpan="2" align="center">Or</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
npm install @inquirer/checkbox
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
yarn add @inquirer/checkbox
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
# Usage
|
||||
|
||||
```js
|
||||
import { checkbox, Separator } from '@inquirer/prompts';
|
||||
// Or
|
||||
// import checkbox, { Separator } from '@inquirer/checkbox';
|
||||
|
||||
const answer = await checkbox({
|
||||
message: 'Select a package manager',
|
||||
choices: [
|
||||
{ name: 'npm', value: 'npm' },
|
||||
{ name: 'yarn', value: 'yarn' },
|
||||
new Separator(),
|
||||
{ name: 'pnpm', value: 'pnpm', disabled: true },
|
||||
{
|
||||
name: 'pnpm',
|
||||
value: 'pnpm',
|
||||
disabled: '(pnpm is not available)',
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Property | Type | Required | Description |
|
||||
| -------- | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| message | `string` | yes | The question to ask |
|
||||
| choices | `Choice[]` | yes | List of the available choices. |
|
||||
| pageSize | `number` | no | By default, lists of choice longer than 7 will be paginated. Use this option to control how many choices will appear on the screen at once. |
|
||||
| loop | `boolean` | no | Defaults to `true`. When set to `false`, the cursor will be constrained to the top and bottom of the choice list without looping. |
|
||||
| required | `boolean` | no | When set to `true`, ensures at least one choice must be selected. |
|
||||
| validate | `async (Choice[]) => boolean \| string` | no | On submit, validate the choices. When returning a string, it'll be used as the error message displayed to the user. Note: returning a rejected promise, we'll assume a code error happened and crash. |
|
||||
| theme | [See Theming](#Theming) | no | Customize look of the prompt. |
|
||||
|
||||
`Separator` objects can be used in the `choices` array to render non-selectable lines in the choice list. By default it'll render a line, but you can provide the text as argument (`new Separator('-- Dependencies --')`). This option is often used to add labels to groups within long list of options.
|
||||
|
||||
### `Choice` object
|
||||
|
||||
The `Choice` object is typed as
|
||||
|
||||
```ts
|
||||
type Choice<Value> = {
|
||||
value: Value;
|
||||
name?: string;
|
||||
description?: string;
|
||||
short?: string;
|
||||
checked?: boolean;
|
||||
disabled?: boolean | string;
|
||||
};
|
||||
```
|
||||
|
||||
Here's each property:
|
||||
|
||||
- `value`: The value is what will be returned by `await checkbox()`.
|
||||
- `name`: This is the string displayed in the choice list.
|
||||
- `description`: Option for a longer description string that'll appear under the list when the cursor highlight a given choice.
|
||||
- `short`: Once the prompt is done (press enter), we'll use `short` if defined to render next to the question. By default we'll use `name`.
|
||||
- `checked`: If `true`, the option will be checked by default.
|
||||
- `disabled`: Disallow the option from being selected. If `disabled` is a string, it'll be used as a help tip explaining why the choice isn't available.
|
||||
|
||||
Also note the `choices` array can contain `Separator`s to help organize long lists.
|
||||
|
||||
`choices` can also be an array of string, in which case the string will be used both as the `value` and the `name`.
|
||||
|
||||
## Theming
|
||||
|
||||
You can theme a prompt by passing a `theme` object option. The theme object only need to includes the keys you wish to modify, we'll fallback on the defaults for the rest.
|
||||
|
||||
```ts
|
||||
type Theme = {
|
||||
prefix: string;
|
||||
spinner: {
|
||||
interval: number;
|
||||
frames: string[];
|
||||
};
|
||||
style: {
|
||||
answer: (text: string) => string;
|
||||
message: (text: string) => string;
|
||||
error: (text: string) => string;
|
||||
defaultAnswer: (text: string) => string;
|
||||
help: (text: string) => string;
|
||||
highlight: (text: string) => string;
|
||||
key: (text: string) => string;
|
||||
disabledChoice: (text: string) => string;
|
||||
description: (text: string) => string;
|
||||
renderSelectedChoices: <T>(
|
||||
selectedChoices: ReadonlyArray<Choice<T>>,
|
||||
allChoices: ReadonlyArray<Choice<T> | Separator>,
|
||||
) => string;
|
||||
};
|
||||
icon: {
|
||||
checked: string;
|
||||
unchecked: string;
|
||||
cursor: string;
|
||||
};
|
||||
helpMode: 'always' | 'never' | 'auto';
|
||||
};
|
||||
```
|
||||
|
||||
### `theme.helpMode`
|
||||
|
||||
- `auto` (default): Hide the help tips after an interaction occurs. The scroll tip will hide after any interactions, the selection tip will hide as soon as a first selection is done.
|
||||
- `always`: The help tips will always show and never hide.
|
||||
- `never`: The help tips will never show.
|
||||
|
||||
# License
|
||||
|
||||
Copyright (c) 2023 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart))<br/>
|
||||
Licensed under the MIT license.
|
203
node_modules/@inquirer/checkbox/dist/cjs/index.js
generated
vendored
Normal file
203
node_modules/@inquirer/checkbox/dist/cjs/index.js
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Separator = void 0;
|
||||
const core_1 = require("@inquirer/core");
|
||||
const yoctocolors_cjs_1 = __importDefault(require("yoctocolors-cjs"));
|
||||
const figures_1 = __importDefault(require("@inquirer/figures"));
|
||||
const ansi_escapes_1 = __importDefault(require("ansi-escapes"));
|
||||
const checkboxTheme = {
|
||||
icon: {
|
||||
checked: yoctocolors_cjs_1.default.green(figures_1.default.circleFilled),
|
||||
unchecked: figures_1.default.circle,
|
||||
cursor: figures_1.default.pointer,
|
||||
},
|
||||
style: {
|
||||
disabledChoice: (text) => yoctocolors_cjs_1.default.dim(`- ${text}`),
|
||||
renderSelectedChoices: (selectedChoices) => selectedChoices.map((choice) => choice.short).join(', '),
|
||||
description: (text) => yoctocolors_cjs_1.default.cyan(text),
|
||||
},
|
||||
helpMode: 'auto',
|
||||
};
|
||||
function isSelectable(item) {
|
||||
return !core_1.Separator.isSeparator(item) && !item.disabled;
|
||||
}
|
||||
function isChecked(item) {
|
||||
return isSelectable(item) && Boolean(item.checked);
|
||||
}
|
||||
function toggle(item) {
|
||||
return isSelectable(item) ? Object.assign(Object.assign({}, item), { checked: !item.checked }) : item;
|
||||
}
|
||||
function check(checked) {
|
||||
return function (item) {
|
||||
return isSelectable(item) ? Object.assign(Object.assign({}, item), { checked }) : item;
|
||||
};
|
||||
}
|
||||
function normalizeChoices(choices) {
|
||||
return choices.map((choice) => {
|
||||
var _a, _b, _c, _d;
|
||||
if (core_1.Separator.isSeparator(choice))
|
||||
return choice;
|
||||
if (typeof choice === 'string') {
|
||||
return {
|
||||
value: choice,
|
||||
name: choice,
|
||||
short: choice,
|
||||
disabled: false,
|
||||
checked: false,
|
||||
};
|
||||
}
|
||||
const name = (_a = choice.name) !== null && _a !== void 0 ? _a : String(choice.value);
|
||||
return {
|
||||
value: choice.value,
|
||||
name,
|
||||
short: (_b = choice.short) !== null && _b !== void 0 ? _b : name,
|
||||
description: choice.description,
|
||||
disabled: (_c = choice.disabled) !== null && _c !== void 0 ? _c : false,
|
||||
checked: (_d = choice.checked) !== null && _d !== void 0 ? _d : false,
|
||||
};
|
||||
});
|
||||
}
|
||||
exports.default = (0, core_1.createPrompt)((config, done) => {
|
||||
const { instructions, pageSize = 7, loop = true, required, validate = () => true, } = config;
|
||||
const theme = (0, core_1.makeTheme)(checkboxTheme, config.theme);
|
||||
const prefix = (0, core_1.usePrefix)({ theme });
|
||||
const firstRender = (0, core_1.useRef)(true);
|
||||
const [status, setStatus] = (0, core_1.useState)('pending');
|
||||
const [items, setItems] = (0, core_1.useState)(normalizeChoices(config.choices));
|
||||
const bounds = (0, core_1.useMemo)(() => {
|
||||
const first = items.findIndex(isSelectable);
|
||||
const last = items.findLastIndex(isSelectable);
|
||||
if (first < 0) {
|
||||
throw new core_1.ValidationError('[checkbox prompt] No selectable choices. All choices are disabled.');
|
||||
}
|
||||
return { first, last };
|
||||
}, [items]);
|
||||
const [active, setActive] = (0, core_1.useState)(bounds.first);
|
||||
const [showHelpTip, setShowHelpTip] = (0, core_1.useState)(true);
|
||||
const [errorMsg, setError] = (0, core_1.useState)();
|
||||
(0, core_1.useKeypress)((key) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
if ((0, core_1.isEnterKey)(key)) {
|
||||
const selection = items.filter(isChecked);
|
||||
const isValid = yield validate([...selection]);
|
||||
if (required && !items.some(isChecked)) {
|
||||
setError('At least one choice must be selected');
|
||||
}
|
||||
else if (isValid === true) {
|
||||
setStatus('done');
|
||||
done(selection.map((choice) => choice.value));
|
||||
}
|
||||
else {
|
||||
setError(isValid || 'You must select a valid value');
|
||||
}
|
||||
}
|
||||
else if ((0, core_1.isUpKey)(key) || (0, core_1.isDownKey)(key)) {
|
||||
if (loop ||
|
||||
((0, core_1.isUpKey)(key) && active !== bounds.first) ||
|
||||
((0, core_1.isDownKey)(key) && active !== bounds.last)) {
|
||||
const offset = (0, core_1.isUpKey)(key) ? -1 : 1;
|
||||
let next = active;
|
||||
do {
|
||||
next = (next + offset + items.length) % items.length;
|
||||
} while (!isSelectable(items[next]));
|
||||
setActive(next);
|
||||
}
|
||||
}
|
||||
else if ((0, core_1.isSpaceKey)(key)) {
|
||||
setError(undefined);
|
||||
setShowHelpTip(false);
|
||||
setItems(items.map((choice, i) => (i === active ? toggle(choice) : choice)));
|
||||
}
|
||||
else if (key.name === 'a') {
|
||||
const selectAll = items.some((choice) => isSelectable(choice) && !choice.checked);
|
||||
setItems(items.map(check(selectAll)));
|
||||
}
|
||||
else if (key.name === 'i') {
|
||||
setItems(items.map(toggle));
|
||||
}
|
||||
else if ((0, core_1.isNumberKey)(key)) {
|
||||
// Adjust index to start at 1
|
||||
const position = Number(key.name) - 1;
|
||||
const item = items[position];
|
||||
if (item != null && isSelectable(item)) {
|
||||
setActive(position);
|
||||
setItems(items.map((choice, i) => (i === position ? toggle(choice) : choice)));
|
||||
}
|
||||
}
|
||||
}));
|
||||
const message = theme.style.message(config.message);
|
||||
let description;
|
||||
const page = (0, core_1.usePagination)({
|
||||
items,
|
||||
active,
|
||||
renderItem({ item, isActive }) {
|
||||
if (core_1.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 : (x) => x;
|
||||
const cursor = isActive ? theme.icon.cursor : ' ';
|
||||
return color(`${cursor}${checkbox} ${item.name}`);
|
||||
},
|
||||
pageSize,
|
||||
loop,
|
||||
});
|
||||
if (status === 'done') {
|
||||
const selection = items.filter(isChecked);
|
||||
const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, 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`,
|
||||
`${theme.style.key('a')} to toggle all`,
|
||||
`${theme.style.key('i')} to invert selection`,
|
||||
`and ${theme.style.key('enter')} to proceed`,
|
||||
];
|
||||
helpTipTop = ` (Press ${keys.join(', ')})`;
|
||||
}
|
||||
if (items.length > pageSize &&
|
||||
(theme.helpMode === 'always' ||
|
||||
(theme.helpMode === 'auto' && firstRender.current))) {
|
||||
helpTipBottom = `\n${theme.style.help('(Use arrow keys to reveal more choices)')}`;
|
||||
firstRender.current = false;
|
||||
}
|
||||
}
|
||||
const choiceDescription = description
|
||||
? `\n${theme.style.description(description)}`
|
||||
: ``;
|
||||
let error = '';
|
||||
if (errorMsg) {
|
||||
error = `\n${theme.style.error(errorMsg)}`;
|
||||
}
|
||||
return `${prefix} ${message}${helpTipTop}\n${page}${helpTipBottom}${choiceDescription}${error}${ansi_escapes_1.default.cursorHide}`;
|
||||
});
|
||||
var core_2 = require("@inquirer/core");
|
||||
Object.defineProperty(exports, "Separator", { enumerable: true, get: function () { return core_2.Separator; } });
|
45
node_modules/@inquirer/checkbox/dist/cjs/types/index.d.ts
generated
vendored
Normal file
45
node_modules/@inquirer/checkbox/dist/cjs/types/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { Separator, type Theme } from '@inquirer/core';
|
||||
import type { PartialDeep } from '@inquirer/type';
|
||||
type CheckboxTheme = {
|
||||
icon: {
|
||||
checked: string;
|
||||
unchecked: string;
|
||||
cursor: string;
|
||||
};
|
||||
style: {
|
||||
disabledChoice: (text: string) => string;
|
||||
renderSelectedChoices: <T>(selectedChoices: ReadonlyArray<NormalizedChoice<T>>, allChoices: ReadonlyArray<NormalizedChoice<T> | Separator>) => string;
|
||||
description: (text: string) => string;
|
||||
};
|
||||
helpMode: 'always' | 'never' | 'auto';
|
||||
};
|
||||
type Choice<Value> = {
|
||||
value: Value;
|
||||
name?: string;
|
||||
description?: string;
|
||||
short?: string;
|
||||
disabled?: boolean | string;
|
||||
checked?: boolean;
|
||||
type?: never;
|
||||
};
|
||||
type NormalizedChoice<Value> = {
|
||||
value: Value;
|
||||
name: string;
|
||||
description?: string;
|
||||
short: string;
|
||||
disabled: boolean | string;
|
||||
checked: boolean;
|
||||
};
|
||||
declare const _default: <Value>(config: {
|
||||
message: string;
|
||||
prefix?: string | undefined;
|
||||
pageSize?: number | undefined;
|
||||
instructions?: (string | boolean) | undefined;
|
||||
choices: readonly (string | Separator)[] | readonly (Separator | Choice<Value>)[];
|
||||
loop?: boolean | undefined;
|
||||
required?: boolean | undefined;
|
||||
validate?: ((choices: readonly Choice<Value>[]) => boolean | string | Promise<string | boolean>) | undefined;
|
||||
theme?: PartialDeep<Theme<CheckboxTheme>> | undefined;
|
||||
}, context?: import("@inquirer/type").Context) => import("@inquirer/type").CancelablePromise<Value[]>;
|
||||
export default _default;
|
||||
export { Separator } from '@inquirer/core';
|
186
node_modules/@inquirer/checkbox/dist/esm/index.mjs
generated
vendored
Normal file
186
node_modules/@inquirer/checkbox/dist/esm/index.mjs
generated
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
import { createPrompt, useState, useKeypress, usePrefix, usePagination, useRef, useMemo, makeTheme, isUpKey, isDownKey, isSpaceKey, isNumberKey, isEnterKey, ValidationError, Separator, } from '@inquirer/core';
|
||||
import colors from 'yoctocolors-cjs';
|
||||
import figures from '@inquirer/figures';
|
||||
import ansiEscapes from 'ansi-escapes';
|
||||
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.cyan(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;
|
||||
if (typeof choice === 'string') {
|
||||
return {
|
||||
value: choice,
|
||||
name: choice,
|
||||
short: choice,
|
||||
disabled: false,
|
||||
checked: false,
|
||||
};
|
||||
}
|
||||
const name = choice.name ?? String(choice.value);
|
||||
return {
|
||||
value: choice.value,
|
||||
name,
|
||||
short: choice.short ?? name,
|
||||
description: choice.description,
|
||||
disabled: choice.disabled ?? false,
|
||||
checked: choice.checked ?? false,
|
||||
};
|
||||
});
|
||||
}
|
||||
export default createPrompt((config, done) => {
|
||||
const { instructions, pageSize = 7, loop = true, required, validate = () => true, } = config;
|
||||
const theme = makeTheme(checkboxTheme, config.theme);
|
||||
const prefix = usePrefix({ theme });
|
||||
const firstRender = useRef(true);
|
||||
const [status, setStatus] = useState('pending');
|
||||
const [items, setItems] = useState(normalizeChoices(config.choices));
|
||||
const bounds = useMemo(() => {
|
||||
const first = items.findIndex(isSelectable);
|
||||
const last = items.findLastIndex(isSelectable);
|
||||
if (first < 0) {
|
||||
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 selection = items.filter(isChecked);
|
||||
const isValid = await validate([...selection]);
|
||||
if (required && !items.some(isChecked)) {
|
||||
setError('At least one choice must be selected');
|
||||
}
|
||||
else if (isValid === true) {
|
||||
setStatus('done');
|
||||
done(selection.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, i) => (i === active ? toggle(choice) : choice)));
|
||||
}
|
||||
else if (key.name === 'a') {
|
||||
const selectAll = items.some((choice) => isSelectable(choice) && !choice.checked);
|
||||
setItems(items.map(check(selectAll)));
|
||||
}
|
||||
else if (key.name === 'i') {
|
||||
setItems(items.map(toggle));
|
||||
}
|
||||
else if (isNumberKey(key)) {
|
||||
// Adjust index to start at 1
|
||||
const position = Number(key.name) - 1;
|
||||
const item = items[position];
|
||||
if (item != null && isSelectable(item)) {
|
||||
setActive(position);
|
||||
setItems(items.map((choice, i) => (i === position ? toggle(choice) : choice)));
|
||||
}
|
||||
}
|
||||
});
|
||||
const message = theme.style.message(config.message);
|
||||
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 : (x) => x;
|
||||
const cursor = isActive ? theme.icon.cursor : ' ';
|
||||
return color(`${cursor}${checkbox} ${item.name}`);
|
||||
},
|
||||
pageSize,
|
||||
loop,
|
||||
});
|
||||
if (status === 'done') {
|
||||
const selection = items.filter(isChecked);
|
||||
const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, 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`,
|
||||
`${theme.style.key('a')} to toggle all`,
|
||||
`${theme.style.key('i')} to invert selection`,
|
||||
`and ${theme.style.key('enter')} to proceed`,
|
||||
];
|
||||
helpTipTop = ` (Press ${keys.join(', ')})`;
|
||||
}
|
||||
if (items.length > pageSize &&
|
||||
(theme.helpMode === 'always' ||
|
||||
(theme.helpMode === 'auto' && firstRender.current))) {
|
||||
helpTipBottom = `\n${theme.style.help('(Use arrow keys to reveal more choices)')}`;
|
||||
firstRender.current = false;
|
||||
}
|
||||
}
|
||||
const choiceDescription = description
|
||||
? `\n${theme.style.description(description)}`
|
||||
: ``;
|
||||
let error = '';
|
||||
if (errorMsg) {
|
||||
error = `\n${theme.style.error(errorMsg)}`;
|
||||
}
|
||||
return `${prefix} ${message}${helpTipTop}\n${page}${helpTipBottom}${choiceDescription}${error}${ansiEscapes.cursorHide}`;
|
||||
});
|
||||
export { Separator } from '@inquirer/core';
|
45
node_modules/@inquirer/checkbox/dist/esm/types/index.d.mts
generated
vendored
Normal file
45
node_modules/@inquirer/checkbox/dist/esm/types/index.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { Separator, type Theme } from '@inquirer/core';
|
||||
import type { PartialDeep } from '@inquirer/type';
|
||||
type CheckboxTheme = {
|
||||
icon: {
|
||||
checked: string;
|
||||
unchecked: string;
|
||||
cursor: string;
|
||||
};
|
||||
style: {
|
||||
disabledChoice: (text: string) => string;
|
||||
renderSelectedChoices: <T>(selectedChoices: ReadonlyArray<NormalizedChoice<T>>, allChoices: ReadonlyArray<NormalizedChoice<T> | Separator>) => string;
|
||||
description: (text: string) => string;
|
||||
};
|
||||
helpMode: 'always' | 'never' | 'auto';
|
||||
};
|
||||
type Choice<Value> = {
|
||||
value: Value;
|
||||
name?: string;
|
||||
description?: string;
|
||||
short?: string;
|
||||
disabled?: boolean | string;
|
||||
checked?: boolean;
|
||||
type?: never;
|
||||
};
|
||||
type NormalizedChoice<Value> = {
|
||||
value: Value;
|
||||
name: string;
|
||||
description?: string;
|
||||
short: string;
|
||||
disabled: boolean | string;
|
||||
checked: boolean;
|
||||
};
|
||||
declare const _default: <Value>(config: {
|
||||
message: string;
|
||||
prefix?: string | undefined;
|
||||
pageSize?: number | undefined;
|
||||
instructions?: (string | boolean) | undefined;
|
||||
choices: readonly (string | Separator)[] | readonly (Separator | Choice<Value>)[];
|
||||
loop?: boolean | undefined;
|
||||
required?: boolean | undefined;
|
||||
validate?: ((choices: readonly Choice<Value>[]) => boolean | string | Promise<string | boolean>) | undefined;
|
||||
theme?: PartialDeep<Theme<CheckboxTheme>> | undefined;
|
||||
}, context?: import("@inquirer/type").Context) => import("@inquirer/type").CancelablePromise<Value[]>;
|
||||
export default _default;
|
||||
export { Separator } from '@inquirer/core';
|
35
node_modules/@inquirer/checkbox/dist/types/index.d.ts
generated
vendored
Normal file
35
node_modules/@inquirer/checkbox/dist/types/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { Separator, type Theme } from '@inquirer/core';
|
||||
import type { PartialDeep } from '@inquirer/type';
|
||||
type CheckboxTheme = {
|
||||
icon: {
|
||||
checked: string;
|
||||
unchecked: string;
|
||||
cursor: string;
|
||||
};
|
||||
style: {
|
||||
disabledChoice: (text: string) => string;
|
||||
renderSelectedChoices: <T>(selectedChoices: ReadonlyArray<Choice<T>>, allChoices: ReadonlyArray<Choice<T> | Separator>) => string;
|
||||
};
|
||||
helpMode: 'always' | 'never' | 'auto';
|
||||
};
|
||||
type Choice<Value> = {
|
||||
name?: string;
|
||||
value: Value;
|
||||
disabled?: boolean | string;
|
||||
checked?: boolean;
|
||||
type?: never;
|
||||
};
|
||||
type Item<Value> = Separator | Choice<Value>;
|
||||
declare const _default: <Value>(config: {
|
||||
message: string;
|
||||
prefix?: string;
|
||||
pageSize?: number;
|
||||
instructions?: string | boolean;
|
||||
choices: readonly (Separator | Choice<Value>)[];
|
||||
loop?: boolean;
|
||||
required?: boolean;
|
||||
validate?: ((items: readonly Item<Value>[]) => boolean | string | Promise<string | boolean>) | undefined;
|
||||
theme?: PartialDeep<Theme<CheckboxTheme>>;
|
||||
}, context?: import("@inquirer/type").Context) => import("@inquirer/type").CancelablePromise<Value[]>;
|
||||
export default _default;
|
||||
export { Separator } from '@inquirer/core';
|
92
node_modules/@inquirer/checkbox/package.json
generated
vendored
Normal file
92
node_modules/@inquirer/checkbox/package.json
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"name": "@inquirer/checkbox",
|
||||
"version": "2.5.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"description": "Inquirer checkbox prompt",
|
||||
"main": "./dist/cjs/index.js",
|
||||
"typings": "./dist/cjs/types/index.d.ts",
|
||||
"files": [
|
||||
"dist/**/*"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SBoudrias/Inquirer.js.git"
|
||||
},
|
||||
"keywords": [
|
||||
"answer",
|
||||
"answers",
|
||||
"ask",
|
||||
"base",
|
||||
"cli",
|
||||
"command",
|
||||
"command-line",
|
||||
"confirm",
|
||||
"enquirer",
|
||||
"generate",
|
||||
"generator",
|
||||
"hyper",
|
||||
"input",
|
||||
"inquire",
|
||||
"inquirer",
|
||||
"interface",
|
||||
"iterm",
|
||||
"javascript",
|
||||
"menu",
|
||||
"node",
|
||||
"nodejs",
|
||||
"prompt",
|
||||
"promptly",
|
||||
"prompts",
|
||||
"question",
|
||||
"readline",
|
||||
"scaffold",
|
||||
"scaffolder",
|
||||
"scaffolding",
|
||||
"stdin",
|
||||
"stdout",
|
||||
"terminal",
|
||||
"tty",
|
||||
"ui",
|
||||
"yeoman",
|
||||
"yo",
|
||||
"zsh"
|
||||
],
|
||||
"author": "Simon Boudrias <admin@simonboudrias.com>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/SBoudrias/Inquirer.js/blob/main/packages/checkbox/README.md",
|
||||
"dependencies": {
|
||||
"@inquirer/core": "^9.1.0",
|
||||
"@inquirer/figures": "^1.0.5",
|
||||
"@inquirer/type": "^1.5.3",
|
||||
"ansi-escapes": "^4.3.2",
|
||||
"yoctocolors-cjs": "^2.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@inquirer/testing": "^2.1.32"
|
||||
},
|
||||
"scripts": {
|
||||
"tsc": "yarn run tsc:esm && yarn run tsc:cjs",
|
||||
"tsc:esm": "rm -rf dist/esm && tsc -p ./tsconfig.json",
|
||||
"tsc:cjs": "rm -rf dist/cjs && tsc -p ./tsconfig.cjs.json && node ../../tools/fix-ext.mjs",
|
||||
"attw": "attw --pack"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/esm/types/index.d.mts",
|
||||
"default": "./dist/esm/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/cjs/types/index.d.ts",
|
||||
"default": "./dist/cjs/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sideEffects": false,
|
||||
"gitHead": "0c039599ef88fe9eb804fe083ee386ec906a856f"
|
||||
}
|
22
node_modules/@inquirer/confirm/LICENSE
generated
vendored
Normal file
22
node_modules/@inquirer/confirm/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2023 Simon Boudrias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
92
node_modules/@inquirer/confirm/README.md
generated
vendored
Normal file
92
node_modules/@inquirer/confirm/README.md
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
# `@inquirer/confirm`
|
||||
|
||||
Simple interactive command line prompt to gather boolean input from users.
|
||||
|
||||

|
||||
|
||||
# Installation
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>npm</th>
|
||||
<th>yarn</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
npm install @inquirer/prompts
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
yarn add @inquirer/prompts
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colSpan="2" align="center">Or</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
npm install @inquirer/confirm
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
yarn add @inquirer/confirm
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
# Usage
|
||||
|
||||
```js
|
||||
import { confirm } from '@inquirer/prompts';
|
||||
// Or
|
||||
// import confirm from '@inquirer/confirm';
|
||||
|
||||
const answer = await confirm({ message: 'Continue?' });
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Property | Type | Required | Description |
|
||||
| ----------- | ----------------------- | -------- | ------------------------------------------------------- |
|
||||
| message | `string` | yes | The question to ask |
|
||||
| default | `boolean` | no | Default answer (true or false) |
|
||||
| transformer | `(boolean) => string` | no | Transform the prompt printed message to a custom string |
|
||||
| theme | [See Theming](#Theming) | no | Customize look of the prompt. |
|
||||
|
||||
## Theming
|
||||
|
||||
You can theme a prompt by passing a `theme` object option. The theme object only need to includes the keys you wish to modify, we'll fallback on the defaults for the rest.
|
||||
|
||||
```ts
|
||||
type Theme = {
|
||||
prefix: string;
|
||||
spinner: {
|
||||
interval: number;
|
||||
frames: string[];
|
||||
};
|
||||
style: {
|
||||
answer: (text: string) => string;
|
||||
message: (text: string) => string;
|
||||
defaultAnswer: (text: string) => string;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
Copyright (c) 2023 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart))<br/>
|
||||
Licensed under the MIT license.
|
35
node_modules/@inquirer/confirm/dist/cjs/index.js
generated
vendored
Normal file
35
node_modules/@inquirer/confirm/dist/cjs/index.js
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core_1 = require("@inquirer/core");
|
||||
exports.default = (0, core_1.createPrompt)((config, done) => {
|
||||
const { transformer = (answer) => (answer ? 'yes' : 'no') } = config;
|
||||
const [status, setStatus] = (0, core_1.useState)('pending');
|
||||
const [value, setValue] = (0, core_1.useState)('');
|
||||
const theme = (0, core_1.makeTheme)(config.theme);
|
||||
const prefix = (0, core_1.usePrefix)({ theme });
|
||||
(0, core_1.useKeypress)((key, rl) => {
|
||||
if ((0, core_1.isEnterKey)(key)) {
|
||||
let answer = config.default !== false;
|
||||
if (/^(y|yes)/i.test(value))
|
||||
answer = true;
|
||||
else if (/^(n|no)/i.test(value))
|
||||
answer = false;
|
||||
setValue(transformer(answer));
|
||||
setStatus('done');
|
||||
done(answer);
|
||||
}
|
||||
else {
|
||||
setValue(rl.line);
|
||||
}
|
||||
});
|
||||
let formattedValue = value;
|
||||
let defaultValue = '';
|
||||
if (status === 'done') {
|
||||
formattedValue = theme.style.answer(value);
|
||||
}
|
||||
else {
|
||||
defaultValue = ` ${theme.style.defaultAnswer(config.default === false ? 'y/N' : 'Y/n')}`;
|
||||
}
|
||||
const message = theme.style.message(config.message);
|
||||
return `${prefix} ${message}${defaultValue} ${formattedValue}`;
|
||||
});
|
10
node_modules/@inquirer/confirm/dist/cjs/types/index.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/confirm/dist/cjs/types/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { type Theme } from '@inquirer/core';
|
||||
import type { PartialDeep } from '@inquirer/type';
|
||||
type ConfirmConfig = {
|
||||
message: string;
|
||||
default?: boolean;
|
||||
transformer?: (value: boolean) => string;
|
||||
theme?: PartialDeep<Theme>;
|
||||
};
|
||||
declare const _default: import("@inquirer/type").Prompt<boolean, ConfirmConfig>;
|
||||
export default _default;
|
33
node_modules/@inquirer/confirm/dist/esm/index.mjs
generated
vendored
Normal file
33
node_modules/@inquirer/confirm/dist/esm/index.mjs
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { createPrompt, useState, useKeypress, isEnterKey, usePrefix, makeTheme, } from '@inquirer/core';
|
||||
export default createPrompt((config, done) => {
|
||||
const { transformer = (answer) => (answer ? 'yes' : 'no') } = config;
|
||||
const [status, setStatus] = useState('pending');
|
||||
const [value, setValue] = useState('');
|
||||
const theme = makeTheme(config.theme);
|
||||
const prefix = usePrefix({ theme });
|
||||
useKeypress((key, rl) => {
|
||||
if (isEnterKey(key)) {
|
||||
let answer = config.default !== false;
|
||||
if (/^(y|yes)/i.test(value))
|
||||
answer = true;
|
||||
else if (/^(n|no)/i.test(value))
|
||||
answer = false;
|
||||
setValue(transformer(answer));
|
||||
setStatus('done');
|
||||
done(answer);
|
||||
}
|
||||
else {
|
||||
setValue(rl.line);
|
||||
}
|
||||
});
|
||||
let formattedValue = value;
|
||||
let defaultValue = '';
|
||||
if (status === 'done') {
|
||||
formattedValue = theme.style.answer(value);
|
||||
}
|
||||
else {
|
||||
defaultValue = ` ${theme.style.defaultAnswer(config.default === false ? 'y/N' : 'Y/n')}`;
|
||||
}
|
||||
const message = theme.style.message(config.message);
|
||||
return `${prefix} ${message}${defaultValue} ${formattedValue}`;
|
||||
});
|
10
node_modules/@inquirer/confirm/dist/esm/types/index.d.mts
generated
vendored
Normal file
10
node_modules/@inquirer/confirm/dist/esm/types/index.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { type Theme } from '@inquirer/core';
|
||||
import type { PartialDeep } from '@inquirer/type';
|
||||
type ConfirmConfig = {
|
||||
message: string;
|
||||
default?: boolean;
|
||||
transformer?: (value: boolean) => string;
|
||||
theme?: PartialDeep<Theme>;
|
||||
};
|
||||
declare const _default: import("@inquirer/type").Prompt<boolean, ConfirmConfig>;
|
||||
export default _default;
|
10
node_modules/@inquirer/confirm/dist/types/index.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/confirm/dist/types/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { type Theme } from '@inquirer/core';
|
||||
import type { PartialDeep } from '@inquirer/type';
|
||||
type ConfirmConfig = {
|
||||
message: string;
|
||||
default?: boolean;
|
||||
transformer?: (value: boolean) => string;
|
||||
theme?: PartialDeep<Theme>;
|
||||
};
|
||||
declare const _default: import("@inquirer/type").Prompt<boolean, ConfirmConfig>;
|
||||
export default _default;
|
89
node_modules/@inquirer/confirm/package.json
generated
vendored
Normal file
89
node_modules/@inquirer/confirm/package.json
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
"name": "@inquirer/confirm",
|
||||
"version": "3.2.0",
|
||||
"description": "Inquirer confirm prompt",
|
||||
"main": "./dist/cjs/index.js",
|
||||
"typings": "./dist/cjs/types/index.d.ts",
|
||||
"files": [
|
||||
"dist/**/*"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SBoudrias/Inquirer.js.git"
|
||||
},
|
||||
"keywords": [
|
||||
"answer",
|
||||
"answers",
|
||||
"ask",
|
||||
"base",
|
||||
"cli",
|
||||
"command",
|
||||
"command-line",
|
||||
"confirm",
|
||||
"enquirer",
|
||||
"generate",
|
||||
"generator",
|
||||
"hyper",
|
||||
"input",
|
||||
"inquire",
|
||||
"inquirer",
|
||||
"interface",
|
||||
"iterm",
|
||||
"javascript",
|
||||
"menu",
|
||||
"node",
|
||||
"nodejs",
|
||||
"prompt",
|
||||
"promptly",
|
||||
"prompts",
|
||||
"question",
|
||||
"readline",
|
||||
"scaffold",
|
||||
"scaffolder",
|
||||
"scaffolding",
|
||||
"stdin",
|
||||
"stdout",
|
||||
"terminal",
|
||||
"tty",
|
||||
"ui",
|
||||
"yeoman",
|
||||
"yo",
|
||||
"zsh"
|
||||
],
|
||||
"author": "Simon Boudrias <admin@simonboudrias.com>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/SBoudrias/Inquirer.js/blob/main/packages/confirm/README.md",
|
||||
"dependencies": {
|
||||
"@inquirer/core": "^9.1.0",
|
||||
"@inquirer/type": "^1.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@inquirer/testing": "^2.1.32"
|
||||
},
|
||||
"scripts": {
|
||||
"tsc": "yarn run tsc:esm && yarn run tsc:cjs",
|
||||
"tsc:esm": "rm -rf dist/esm && tsc -p ./tsconfig.json",
|
||||
"tsc:cjs": "rm -rf dist/cjs && tsc -p ./tsconfig.cjs.json && node ../../tools/fix-ext.mjs",
|
||||
"attw": "attw --pack"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/esm/types/index.d.mts",
|
||||
"default": "./dist/esm/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/cjs/types/index.d.ts",
|
||||
"default": "./dist/cjs/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sideEffects": false,
|
||||
"gitHead": "0c039599ef88fe9eb804fe083ee386ec906a856f"
|
||||
}
|
22
node_modules/@inquirer/core/LICENSE
generated
vendored
Normal file
22
node_modules/@inquirer/core/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2023 Simon Boudrias
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
383
node_modules/@inquirer/core/README.md
generated
vendored
Normal file
383
node_modules/@inquirer/core/README.md
generated
vendored
Normal file
|
@ -0,0 +1,383 @@
|
|||
# `@inquirer/core`
|
||||
|
||||
The `@inquirer/core` package is the library enabling the creation of Inquirer prompts.
|
||||
|
||||
It aims to implements a lightweight API similar to React hooks - but without JSX.
|
||||
|
||||
# Installation
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>npm</th>
|
||||
<th>yarn</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
npm install @inquirer/core
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```sh
|
||||
yarn add @inquirer/core
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
# Usage
|
||||
|
||||
## Basic concept
|
||||
|
||||
Visual terminal apps are at their core strings rendered onto the terminal.
|
||||
|
||||
The most basic prompt is a function returning a string that'll be rendered in the terminal. This function will run every time the prompt state change, and the new returned string will replace the previously rendered one. The prompt cursor appears after the string.
|
||||
|
||||
Wrapping the rendering function with `createPrompt()` will setup the rendering layer, inject the state management utilities, and wait until the `done` callback is called.
|
||||
|
||||
```ts
|
||||
import { createPrompt } from '@inquirer/core';
|
||||
|
||||
const input = createPrompt((config, done) => {
|
||||
// Implement logic
|
||||
|
||||
return '? My question';
|
||||
});
|
||||
|
||||
// And it is then called as
|
||||
const answer = await input({
|
||||
/* config */
|
||||
});
|
||||
```
|
||||
|
||||
## Hooks
|
||||
|
||||
State management and user interactions are handled through hooks. Hooks are common [within the React ecosystem](https://react.dev/reference/react/hooks), and Inquirer reimplement the common ones.
|
||||
|
||||
### State hook
|
||||
|
||||
State lets a component “remember” information like user input. For example, an input prompt can use state to store the input value, while a list prompt can use state to track the cursor index.
|
||||
|
||||
`useState` declares a state variable that you can update directly.
|
||||
|
||||
```ts
|
||||
import { createPrompt, useState } from '@inquirer/core';
|
||||
|
||||
const input = createPrompt((config, done) => {
|
||||
const [index, setIndex] = useState(0);
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
### Keypress hook
|
||||
|
||||
Almost all prompts need to react to user actions. In a terminal, this is done through typing.
|
||||
|
||||
`useKeypress` allows you to react to keypress events, and access the prompt line.
|
||||
|
||||
```ts
|
||||
const input = createPrompt((config, done) => {
|
||||
useKeypress((key) => {
|
||||
if (key.name === 'enter') {
|
||||
done(answer);
|
||||
}
|
||||
});
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
Behind the scenes, Inquirer prompts are wrappers around [readlines](https://nodejs.org/api/readline.html). Aside the keypress event object, the hook also pass the active readline instance to the event handler.
|
||||
|
||||
```ts
|
||||
const input = createPrompt((config, done) => {
|
||||
useKeypress((key, readline) => {
|
||||
setValue(readline.line);
|
||||
});
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
### Ref hook
|
||||
|
||||
Refs let a prompt hold some information that isn’t used for rendering, like a class instance or a timeout ID. Unlike with state, updating a ref does not re-render your prompt. Refs are an “escape hatch” from the rendering paradigm.
|
||||
|
||||
`useRef` declares a ref. You can hold any value in it, but most often it’s used to hold a timeout ID.
|
||||
|
||||
```ts
|
||||
const input = createPrompt((config, done) => {
|
||||
const timeout = useRef(null);
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
### Effect Hook
|
||||
|
||||
Effects let a prompt connect to and synchronize with external systems. This includes dealing with network or animations.
|
||||
|
||||
`useEffect` connects a component to an external system.
|
||||
|
||||
```ts
|
||||
const chat = createPrompt((config, done) => {
|
||||
useEffect(() => {
|
||||
const connection = createConnection(roomId);
|
||||
connection.connect();
|
||||
return () => connection.disconnect();
|
||||
}, [roomId]);
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
### Performance hook
|
||||
|
||||
A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell Inquirer to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.
|
||||
|
||||
`useMemo` lets you cache the result of an expensive calculation.
|
||||
|
||||
```ts
|
||||
const todoSelect = createPrompt((config, done) => {
|
||||
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
### Rendering hooks
|
||||
|
||||
#### Prefix / loading
|
||||
|
||||
All default prompts, and most custom ones, uses a prefix at the beginning of the prompt line. This helps visually delineate different questions, and provides a convenient area to render a loading spinner.
|
||||
|
||||
`usePrefix` is a built-in hook to do this.
|
||||
|
||||
```ts
|
||||
const input = createPrompt((config, done) => {
|
||||
const prefix = usePrefix({ status });
|
||||
|
||||
return `${prefix} My question`;
|
||||
});
|
||||
```
|
||||
|
||||
#### Pagination
|
||||
|
||||
When looping through a long list of options (like in the `select` prompt), paginating the results appearing on the screen at once can be necessary. The `usePagination` hook is the utility used within the `select` and `checkbox` prompts to cycle through the list of options.
|
||||
|
||||
Pagination works by taking in the list of options and returning a subset of the rendered items that fit within the page. The hook takes in a few options. It needs a list of options (`items`), and a `pageSize` which is the number of lines to be rendered. The `active` index is the index of the currently selected/selectable item. The `loop` option is a boolean that indicates if the list should loop around when reaching the end: this is the default behavior. The pagination hook renders items only as necessary, so it takes a function that can render an item at an index, including an `active` state, called `renderItem`.
|
||||
|
||||
```js
|
||||
export default createPrompt((config, done) => {
|
||||
const [active, setActive] = useState(0);
|
||||
|
||||
const allChoices = config.choices.map((choice) => choice.name);
|
||||
|
||||
const page = usePagination({
|
||||
items: allChoices,
|
||||
active: active,
|
||||
renderItem: ({ item, index, isActive }) => `${isActive ? ">" : " "}${index}. ${item.toString()}`
|
||||
pageSize: config.pageSize,
|
||||
loop: config.loop,
|
||||
});
|
||||
|
||||
return `... ${page}`;
|
||||
});
|
||||
```
|
||||
|
||||
## `createPrompt()` API
|
||||
|
||||
As we saw earlier, the rendering function should return a string, and eventually call `done` to close the prompt and return the answer.
|
||||
|
||||
```ts
|
||||
const input = createPrompt((config, done) => {
|
||||
const [value, setValue] = useState();
|
||||
|
||||
useKeypress((key, readline) => {
|
||||
if (key.name === 'enter') {
|
||||
done(answer);
|
||||
} else {
|
||||
setValue(readline.line);
|
||||
}
|
||||
});
|
||||
|
||||
return `? ${config.message} ${value}`;
|
||||
});
|
||||
```
|
||||
|
||||
The rendering function can also return a tuple of 2 string (`[string, string]`.) The first string represents the prompt. The second one is content to render under the prompt, like an error message. The text input cursor will appear after the first string.
|
||||
|
||||
```ts
|
||||
const number = createPrompt((config, done) => {
|
||||
// Add some logic here
|
||||
|
||||
return [`? My question ${input}`, `! The input must be a number`];
|
||||
});
|
||||
```
|
||||
|
||||
### Typescript
|
||||
|
||||
If using typescript, `createPrompt` takes 2 generic arguments.
|
||||
|
||||
```ts
|
||||
// createPrompt<Value, Config>
|
||||
const input = createPrompt<string, { message: string }>(// ...
|
||||
```
|
||||
|
||||
The first one is the type of the resolved value
|
||||
|
||||
```ts
|
||||
const answer: string = await input();
|
||||
```
|
||||
|
||||
The second one is the type of the prompt config; in other words the interface the created prompt will provide to users.
|
||||
|
||||
```ts
|
||||
const answer = await input({
|
||||
message: 'My question',
|
||||
});
|
||||
```
|
||||
|
||||
## Key utilities
|
||||
|
||||
Listening for keypress events inside an inquirer prompt is a very common pattern. To ease this, we export a few utility functions taking in the keypress event object and return a boolean:
|
||||
|
||||
- `isEnterKey()`
|
||||
- `isBackspaceKey()`
|
||||
- `isSpaceKey()`
|
||||
- `isUpKey()` - Note: this utility will handle vim and emacs keybindings (up, `k`, and `ctrl+p`)
|
||||
- `isDownKey()` - Note: this utility will handle vim and emacs keybindings (down, `j`, and `ctrl+n`)
|
||||
- `isNumberKey()` one of 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
|
||||
|
||||
## Theming
|
||||
|
||||
Theming utilities will allow you to expose customization of the prompt style. Inquirer also has a few standard theme values shared across all the official prompts.
|
||||
|
||||
To allow standard customization:
|
||||
|
||||
```ts
|
||||
import { createPrompt, usePrefix, makeTheme, type Theme } from '@inquirer/core';
|
||||
import type { PartialDeep } from '@inquirer/type';
|
||||
|
||||
type PromptConfig = {
|
||||
theme?: PartialDeep<Theme>;
|
||||
};
|
||||
|
||||
export default createPrompt<string, PromptConfig>((config, done) => {
|
||||
const theme = makeTheme(config.theme);
|
||||
|
||||
const prefix = usePrefix({ status, theme });
|
||||
|
||||
return `${prefix} ${theme.style.highlight('hello')}`;
|
||||
});
|
||||
```
|
||||
|
||||
To setup a custom theme:
|
||||
|
||||
```ts
|
||||
import { createPrompt, makeTheme, type Theme } from '@inquirer/core';
|
||||
import type { PartialDeep } from '@inquirer/type';
|
||||
|
||||
type PromptTheme = {};
|
||||
|
||||
const promptTheme: PromptTheme = {
|
||||
icon: '!',
|
||||
};
|
||||
|
||||
type PromptConfig = {
|
||||
theme?: PartialDeep<Theme<PromptTheme>>;
|
||||
};
|
||||
|
||||
export default createPrompt<string, PromptConfig>((config, done) => {
|
||||
const theme = makeTheme(promptTheme, config.theme);
|
||||
|
||||
const prefix = usePrefix({ status, theme });
|
||||
|
||||
return `${prefix} ${theme.icon}`;
|
||||
});
|
||||
```
|
||||
|
||||
The [default theme keys cover](https://github.com/SBoudrias/Inquirer.js/blob/theme/packages/core/src/lib/theme.mts):
|
||||
|
||||
```ts
|
||||
type DefaultTheme = {
|
||||
prefix: string | { idle: string; done: string };
|
||||
spinner: {
|
||||
interval: number;
|
||||
frames: string[];
|
||||
};
|
||||
style: {
|
||||
answer: (text: string) => string;
|
||||
message: (text: string, status: 'idle' | 'done' | 'loading') => string;
|
||||
error: (text: string) => string;
|
||||
defaultAnswer: (text: string) => string;
|
||||
help: (text: string) => string;
|
||||
highlight: (text: string) => string;
|
||||
key: (text: string) => string;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
# Examples
|
||||
|
||||
You can refer to any `@inquirer/prompts` prompts for real examples:
|
||||
|
||||
- [Confirm Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/confirm/src/index.mts)
|
||||
- [Input Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/input/src/index.mts)
|
||||
- [Password Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/password/src/index.mts)
|
||||
- [Editor Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/editor/src/index.mts)
|
||||
- [Select Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/select/src/index.mts)
|
||||
- [Checkbox Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/checkbox/src/index.mts)
|
||||
- [Rawlist Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/rawlist/src/index.mts)
|
||||
- [Expand Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/expand/src/index.mts)
|
||||
|
||||
```ts
|
||||
import colors from 'yoctocolors';
|
||||
import {
|
||||
createPrompt,
|
||||
useState,
|
||||
useKeypress,
|
||||
isEnterKey,
|
||||
usePrefix,
|
||||
type Status,
|
||||
} from '@inquirer/core';
|
||||
|
||||
const confirm = createPrompt<boolean, { message: string; default?: boolean }>(
|
||||
(config, done) => {
|
||||
const [status, setStatus] = useState<Status>('idle');
|
||||
const [value, setValue] = useState('');
|
||||
const prefix = usePrefix({});
|
||||
|
||||
useKeypress((key, rl) => {
|
||||
if (isEnterKey(key)) {
|
||||
const answer = value ? /^y(es)?/i.test(value) : config.default !== false;
|
||||
setValue(answer ? 'yes' : 'no');
|
||||
setStatus('done');
|
||||
done(answer);
|
||||
} else {
|
||||
setValue(rl.line);
|
||||
}
|
||||
});
|
||||
|
||||
let formattedValue = value;
|
||||
let defaultValue = '';
|
||||
if (status === 'done') {
|
||||
formattedValue = colors.cyan(value);
|
||||
} else {
|
||||
defaultValue = colors.dim(config.default === false ? ' (y/N)' : ' (Y/n)');
|
||||
}
|
||||
|
||||
const message = colors.bold(config.message);
|
||||
return `${prefix} ${message}${defaultValue} ${formattedValue}`;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Which then can be used like this:
|
||||
*/
|
||||
const answer = await confirm({ message: 'Do you want to continue?' });
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
Copyright (c) 2023 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart))<br/>
|
||||
Licensed under the MIT license.
|
39
node_modules/@inquirer/core/dist/cjs/index.js
generated
vendored
Normal file
39
node_modules/@inquirer/core/dist/cjs/index.js
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Separator = exports.createPrompt = exports.usePagination = exports.makeTheme = exports.useKeypress = exports.useRef = exports.useMemo = exports.useEffect = exports.useState = exports.usePrefix = void 0;
|
||||
__exportStar(require('./lib/key.js'), exports);
|
||||
__exportStar(require('./lib/errors.js'), exports);
|
||||
var use_prefix_mjs_1 = require('./lib/use-prefix.js');
|
||||
Object.defineProperty(exports, "usePrefix", { enumerable: true, get: function () { return use_prefix_mjs_1.usePrefix; } });
|
||||
var use_state_mjs_1 = require('./lib/use-state.js');
|
||||
Object.defineProperty(exports, "useState", { enumerable: true, get: function () { return use_state_mjs_1.useState; } });
|
||||
var use_effect_mjs_1 = require('./lib/use-effect.js');
|
||||
Object.defineProperty(exports, "useEffect", { enumerable: true, get: function () { return use_effect_mjs_1.useEffect; } });
|
||||
var use_memo_mjs_1 = require('./lib/use-memo.js');
|
||||
Object.defineProperty(exports, "useMemo", { enumerable: true, get: function () { return use_memo_mjs_1.useMemo; } });
|
||||
var use_ref_mjs_1 = require('./lib/use-ref.js');
|
||||
Object.defineProperty(exports, "useRef", { enumerable: true, get: function () { return use_ref_mjs_1.useRef; } });
|
||||
var use_keypress_mjs_1 = require('./lib/use-keypress.js');
|
||||
Object.defineProperty(exports, "useKeypress", { enumerable: true, get: function () { return use_keypress_mjs_1.useKeypress; } });
|
||||
var make_theme_mjs_1 = require('./lib/make-theme.js');
|
||||
Object.defineProperty(exports, "makeTheme", { enumerable: true, get: function () { return make_theme_mjs_1.makeTheme; } });
|
||||
var use_pagination_mjs_1 = require('./lib/pagination/use-pagination.js');
|
||||
Object.defineProperty(exports, "usePagination", { enumerable: true, get: function () { return use_pagination_mjs_1.usePagination; } });
|
||||
var create_prompt_mjs_1 = require('./lib/create-prompt.js');
|
||||
Object.defineProperty(exports, "createPrompt", { enumerable: true, get: function () { return create_prompt_mjs_1.createPrompt; } });
|
||||
var Separator_mjs_1 = require('./lib/Separator.js');
|
||||
Object.defineProperty(exports, "Separator", { enumerable: true, get: function () { return Separator_mjs_1.Separator; } });
|
38
node_modules/@inquirer/core/dist/cjs/lib/Separator.js
generated
vendored
Normal file
38
node_modules/@inquirer/core/dist/cjs/lib/Separator.js
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Separator = void 0;
|
||||
const yoctocolors_cjs_1 = __importDefault(require("yoctocolors-cjs"));
|
||||
const figures_1 = __importDefault(require("@inquirer/figures"));
|
||||
/**
|
||||
* Separator object
|
||||
* Used to space/separate choices group
|
||||
*/
|
||||
class Separator {
|
||||
constructor(separator) {
|
||||
Object.defineProperty(this, "separator", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: yoctocolors_cjs_1.default.dim(Array.from({ length: 15 }).join(figures_1.default.line))
|
||||
});
|
||||
Object.defineProperty(this, "type", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 'separator'
|
||||
});
|
||||
if (separator) {
|
||||
this.separator = separator;
|
||||
}
|
||||
}
|
||||
static isSeparator(choice) {
|
||||
return Boolean(choice &&
|
||||
typeof choice === 'object' &&
|
||||
'type' in choice &&
|
||||
choice.type === 'separator');
|
||||
}
|
||||
}
|
||||
exports.Separator = Separator;
|
114
node_modules/@inquirer/core/dist/cjs/lib/create-prompt.js
generated
vendored
Normal file
114
node_modules/@inquirer/core/dist/cjs/lib/create-prompt.js
generated
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createPrompt = createPrompt;
|
||||
const readline = __importStar(require("node:readline"));
|
||||
const node_async_hooks_1 = require("node:async_hooks");
|
||||
const mute_stream_1 = __importDefault(require("mute-stream"));
|
||||
const signal_exit_1 = require("signal-exit");
|
||||
const screen_manager_mjs_1 = __importDefault(require('./screen-manager.js'));
|
||||
const promise_polyfill_mjs_1 = require('./promise-polyfill.js');
|
||||
const hook_engine_mjs_1 = require('./hook-engine.js');
|
||||
const errors_mjs_1 = require('./errors.js');
|
||||
function createPrompt(view) {
|
||||
const prompt = (config, context = {}) => {
|
||||
var _a;
|
||||
// Default `input` to stdin
|
||||
const { input = process.stdin, signal } = context;
|
||||
const cleanups = new Set();
|
||||
// Add mute capabilities to the output
|
||||
const output = new mute_stream_1.default();
|
||||
output.pipe((_a = context.output) !== null && _a !== void 0 ? _a : process.stdout);
|
||||
const rl = readline.createInterface({
|
||||
terminal: true,
|
||||
input,
|
||||
output,
|
||||
});
|
||||
const screen = new screen_manager_mjs_1.default(rl);
|
||||
const { promise, resolve, reject } = promise_polyfill_mjs_1.PromisePolyfill.withResolver();
|
||||
/** @deprecated pass an AbortSignal in the context options instead. See {@link https://github.com/SBoudrias/Inquirer.js#canceling-prompt} */
|
||||
const cancel = () => reject(new errors_mjs_1.CancelPromptError());
|
||||
if (signal) {
|
||||
const abort = () => reject(new errors_mjs_1.AbortPromptError({ cause: signal.reason }));
|
||||
if (signal.aborted) {
|
||||
abort();
|
||||
return Object.assign(promise, { cancel });
|
||||
}
|
||||
signal.addEventListener('abort', abort);
|
||||
cleanups.add(() => signal.removeEventListener('abort', abort));
|
||||
}
|
||||
cleanups.add((0, signal_exit_1.onExit)((code, signal) => {
|
||||
reject(new errors_mjs_1.ExitPromptError(`User force closed the prompt with ${code} ${signal}`));
|
||||
}));
|
||||
// Re-renders only happen when the state change; but the readline cursor could change position
|
||||
// and that also requires a re-render (and a manual one because we mute the streams).
|
||||
// We set the listener after the initial workLoop to avoid a double render if render triggered
|
||||
// by a state change sets the cursor to the right position.
|
||||
const checkCursorPos = () => screen.checkCursorPos();
|
||||
rl.input.on('keypress', checkCursorPos);
|
||||
cleanups.add(() => rl.input.removeListener('keypress', checkCursorPos));
|
||||
return (0, hook_engine_mjs_1.withHooks)(rl, (cycle) => {
|
||||
// The close event triggers immediately when the user press ctrl+c. SignalExit on the other hand
|
||||
// triggers after the process is done (which happens after timeouts are done triggering.)
|
||||
// We triggers the hooks cleanup phase on rl `close` so active timeouts can be cleared.
|
||||
const hooksCleanup = node_async_hooks_1.AsyncResource.bind(() => hook_engine_mjs_1.effectScheduler.clearAll());
|
||||
rl.on('close', hooksCleanup);
|
||||
cleanups.add(() => rl.removeListener('close', hooksCleanup));
|
||||
cycle(() => {
|
||||
try {
|
||||
const nextView = view(config, (value) => {
|
||||
setImmediate(() => resolve(value));
|
||||
});
|
||||
const [content, bottomContent] = typeof nextView === 'string' ? [nextView] : nextView;
|
||||
screen.render(content, bottomContent);
|
||||
hook_engine_mjs_1.effectScheduler.run();
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return Object.assign(promise
|
||||
.then((answer) => {
|
||||
hook_engine_mjs_1.effectScheduler.clearAll();
|
||||
return answer;
|
||||
}, (error) => {
|
||||
hook_engine_mjs_1.effectScheduler.clearAll();
|
||||
throw error;
|
||||
})
|
||||
// Wait for the promise to settle, then cleanup.
|
||||
.finally(() => {
|
||||
cleanups.forEach((cleanup) => cleanup());
|
||||
screen.done({ clearContent: Boolean(context === null || context === void 0 ? void 0 : context.clearPromptOnDone) });
|
||||
output.end();
|
||||
})
|
||||
// Once cleanup is done, let the expose promise resolve/reject to the internal one.
|
||||
.then(() => promise), { cancel });
|
||||
});
|
||||
};
|
||||
return prompt;
|
||||
}
|
76
node_modules/@inquirer/core/dist/cjs/lib/errors.js
generated
vendored
Normal file
76
node_modules/@inquirer/core/dist/cjs/lib/errors.js
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ValidationError = exports.HookError = exports.ExitPromptError = exports.CancelPromptError = exports.AbortPromptError = void 0;
|
||||
class AbortPromptError extends Error {
|
||||
constructor(options) {
|
||||
super();
|
||||
Object.defineProperty(this, "name", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 'AbortPromptError'
|
||||
});
|
||||
Object.defineProperty(this, "message", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 'Prompt was aborted'
|
||||
});
|
||||
this.cause = options === null || options === void 0 ? void 0 : options.cause;
|
||||
}
|
||||
}
|
||||
exports.AbortPromptError = AbortPromptError;
|
||||
class CancelPromptError extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
Object.defineProperty(this, "name", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 'CancelPromptError'
|
||||
});
|
||||
Object.defineProperty(this, "message", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 'Prompt was canceled'
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.CancelPromptError = CancelPromptError;
|
||||
class ExitPromptError extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
Object.defineProperty(this, "name", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 'ExitPromptError'
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.ExitPromptError = ExitPromptError;
|
||||
class HookError extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
Object.defineProperty(this, "name", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 'HookError'
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.HookError = HookError;
|
||||
class ValidationError extends Error {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
Object.defineProperty(this, "name", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 'ValidationError'
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.ValidationError = ValidationError;
|
119
node_modules/@inquirer/core/dist/cjs/lib/hook-engine.js
generated
vendored
Normal file
119
node_modules/@inquirer/core/dist/cjs/lib/hook-engine.js
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
"use strict";
|
||||
/* eslint @typescript-eslint/no-explicit-any: ["off"] */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.effectScheduler = void 0;
|
||||
exports.withHooks = withHooks;
|
||||
exports.readline = readline;
|
||||
exports.withUpdates = withUpdates;
|
||||
exports.withPointer = withPointer;
|
||||
exports.handleChange = handleChange;
|
||||
const node_async_hooks_1 = require("node:async_hooks");
|
||||
const errors_mjs_1 = require('./errors.js');
|
||||
const hookStorage = new node_async_hooks_1.AsyncLocalStorage();
|
||||
function createStore(rl) {
|
||||
const store = {
|
||||
rl,
|
||||
hooks: [],
|
||||
hooksCleanup: [],
|
||||
hooksEffect: [],
|
||||
index: 0,
|
||||
handleChange() { },
|
||||
};
|
||||
return store;
|
||||
}
|
||||
// Run callback in with the hook engine setup.
|
||||
function withHooks(rl, cb) {
|
||||
const store = createStore(rl);
|
||||
return hookStorage.run(store, () => {
|
||||
function cycle(render) {
|
||||
store.handleChange = () => {
|
||||
store.index = 0;
|
||||
render();
|
||||
};
|
||||
store.handleChange();
|
||||
}
|
||||
return cb(cycle);
|
||||
});
|
||||
}
|
||||
// Safe getStore utility that'll return the store or throw if undefined.
|
||||
function getStore() {
|
||||
const store = hookStorage.getStore();
|
||||
if (!store) {
|
||||
throw new errors_mjs_1.HookError('[Inquirer] Hook functions can only be called from within a prompt');
|
||||
}
|
||||
return store;
|
||||
}
|
||||
function readline() {
|
||||
return getStore().rl;
|
||||
}
|
||||
// Merge state updates happening within the callback function to avoid multiple renders.
|
||||
function withUpdates(fn) {
|
||||
const wrapped = (...args) => {
|
||||
const store = getStore();
|
||||
let shouldUpdate = false;
|
||||
const oldHandleChange = store.handleChange;
|
||||
store.handleChange = () => {
|
||||
shouldUpdate = true;
|
||||
};
|
||||
const returnValue = fn(...args);
|
||||
if (shouldUpdate) {
|
||||
oldHandleChange();
|
||||
}
|
||||
store.handleChange = oldHandleChange;
|
||||
return returnValue;
|
||||
};
|
||||
return node_async_hooks_1.AsyncResource.bind(wrapped);
|
||||
}
|
||||
function withPointer(cb) {
|
||||
const store = getStore();
|
||||
const { index } = store;
|
||||
const pointer = {
|
||||
get() {
|
||||
return store.hooks[index];
|
||||
},
|
||||
set(value) {
|
||||
store.hooks[index] = value;
|
||||
},
|
||||
initialized: index in store.hooks,
|
||||
};
|
||||
const returnValue = cb(pointer);
|
||||
store.index++;
|
||||
return returnValue;
|
||||
}
|
||||
function handleChange() {
|
||||
getStore().handleChange();
|
||||
}
|
||||
exports.effectScheduler = {
|
||||
queue(cb) {
|
||||
const store = getStore();
|
||||
const { index } = store;
|
||||
store.hooksEffect.push(() => {
|
||||
var _a, _b;
|
||||
(_b = (_a = store.hooksCleanup)[index]) === null || _b === void 0 ? void 0 : _b.call(_a);
|
||||
const cleanFn = cb(readline());
|
||||
if (cleanFn != null && typeof cleanFn !== 'function') {
|
||||
throw new errors_mjs_1.ValidationError('useEffect return value must be a cleanup function or nothing.');
|
||||
}
|
||||
store.hooksCleanup[index] = cleanFn;
|
||||
});
|
||||
},
|
||||
run() {
|
||||
const store = getStore();
|
||||
withUpdates(() => {
|
||||
store.hooksEffect.forEach((effect) => {
|
||||
effect();
|
||||
});
|
||||
// Warning: Clean the hooks before exiting the `withUpdates` block.
|
||||
// Failure to do so means an updates would hit the same effects again.
|
||||
store.hooksEffect.length = 0;
|
||||
})();
|
||||
},
|
||||
clearAll() {
|
||||
const store = getStore();
|
||||
store.hooksCleanup.forEach((cleanFn) => {
|
||||
cleanFn === null || cleanFn === void 0 ? void 0 : cleanFn();
|
||||
});
|
||||
store.hooksEffect.length = 0;
|
||||
store.hooksCleanup.length = 0;
|
||||
},
|
||||
};
|
27
node_modules/@inquirer/core/dist/cjs/lib/key.js
generated
vendored
Normal file
27
node_modules/@inquirer/core/dist/cjs/lib/key.js
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isEnterKey = exports.isNumberKey = exports.isBackspaceKey = exports.isSpaceKey = exports.isDownKey = exports.isUpKey = void 0;
|
||||
const isUpKey = (key) =>
|
||||
// The up key
|
||||
key.name === 'up' ||
|
||||
// Vim keybinding
|
||||
key.name === 'k' ||
|
||||
// Emacs keybinding
|
||||
(key.ctrl && key.name === 'p');
|
||||
exports.isUpKey = isUpKey;
|
||||
const isDownKey = (key) =>
|
||||
// The down key
|
||||
key.name === 'down' ||
|
||||
// Vim keybinding
|
||||
key.name === 'j' ||
|
||||
// Emacs keybinding
|
||||
(key.ctrl && key.name === 'n');
|
||||
exports.isDownKey = isDownKey;
|
||||
const isSpaceKey = (key) => key.name === 'space';
|
||||
exports.isSpaceKey = isSpaceKey;
|
||||
const isBackspaceKey = (key) => key.name === 'backspace';
|
||||
exports.isBackspaceKey = isBackspaceKey;
|
||||
const isNumberKey = (key) => '123456789'.includes(key.name);
|
||||
exports.isNumberKey = isNumberKey;
|
||||
const isEnterKey = (key) => key.name === 'enter' || key.name === 'return';
|
||||
exports.isEnterKey = isEnterKey;
|
33
node_modules/@inquirer/core/dist/cjs/lib/make-theme.js
generated
vendored
Normal file
33
node_modules/@inquirer/core/dist/cjs/lib/make-theme.js
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.makeTheme = makeTheme;
|
||||
const theme_mjs_1 = require('./theme.js');
|
||||
function isPlainObject(value) {
|
||||
if (typeof value !== 'object' || value === null)
|
||||
return false;
|
||||
let proto = value;
|
||||
while (Object.getPrototypeOf(proto) !== null) {
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
return Object.getPrototypeOf(value) === proto;
|
||||
}
|
||||
function deepMerge(...objects) {
|
||||
const output = {};
|
||||
for (const obj of objects) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
const prevValue = output[key];
|
||||
output[key] =
|
||||
isPlainObject(prevValue) && isPlainObject(value)
|
||||
? deepMerge(prevValue, value)
|
||||
: value;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function makeTheme(...themes) {
|
||||
const themesToMerge = [
|
||||
theme_mjs_1.defaultTheme,
|
||||
...themes.filter((theme) => theme != null),
|
||||
];
|
||||
return deepMerge(...themesToMerge);
|
||||
}
|
62
node_modules/@inquirer/core/dist/cjs/lib/pagination/lines.js
generated
vendored
Normal file
62
node_modules/@inquirer/core/dist/cjs/lib/pagination/lines.js
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.lines = lines;
|
||||
const utils_mjs_1 = require('../utils.js');
|
||||
function split(content, width) {
|
||||
return (0, utils_mjs_1.breakLines)(content, width).split('\n');
|
||||
}
|
||||
/**
|
||||
* Rotates an array of items by an integer number of positions.
|
||||
* @param {number} count The number of positions to rotate by
|
||||
* @param {T[]} items The items to rotate
|
||||
*/
|
||||
function rotate(count, items) {
|
||||
const max = items.length;
|
||||
const offset = ((count % max) + max) % max;
|
||||
return [...items.slice(offset), ...items.slice(0, offset)];
|
||||
}
|
||||
/**
|
||||
* Renders a page of items as lines that fit within the given width ensuring
|
||||
* that the number of lines is not greater than the page size, and the active
|
||||
* item renders at the provided position, while prioritizing that as many lines
|
||||
* of the active item get rendered as possible.
|
||||
*/
|
||||
function lines({ items, width, renderItem, active, position: requested, pageSize, }) {
|
||||
const layouts = items.map((item, index) => ({
|
||||
item,
|
||||
index,
|
||||
isActive: index === active,
|
||||
}));
|
||||
const layoutsInPage = rotate(active - requested, layouts).slice(0, pageSize);
|
||||
const renderItemAt = (index) => layoutsInPage[index] == null ? [] : split(renderItem(layoutsInPage[index]), width);
|
||||
// Create a blank array of lines for the page
|
||||
const pageBuffer = Array.from({ length: pageSize });
|
||||
// Render the active item to decide the position
|
||||
const activeItem = renderItemAt(requested).slice(0, pageSize);
|
||||
const position = requested + activeItem.length <= pageSize ? requested : pageSize - activeItem.length;
|
||||
// Add the lines of the active item into the page
|
||||
pageBuffer.splice(position, activeItem.length, ...activeItem);
|
||||
// Fill the page under the active item
|
||||
let bufferPointer = position + activeItem.length;
|
||||
let layoutPointer = requested + 1;
|
||||
while (bufferPointer < pageSize && layoutPointer < layoutsInPage.length) {
|
||||
for (const line of renderItemAt(layoutPointer)) {
|
||||
pageBuffer[bufferPointer++] = line;
|
||||
if (bufferPointer >= pageSize)
|
||||
break;
|
||||
}
|
||||
layoutPointer++;
|
||||
}
|
||||
// Fill the page over the active item
|
||||
bufferPointer = position - 1;
|
||||
layoutPointer = requested - 1;
|
||||
while (bufferPointer >= 0 && layoutPointer >= 0) {
|
||||
for (const line of renderItemAt(layoutPointer).reverse()) {
|
||||
pageBuffer[bufferPointer--] = line;
|
||||
if (bufferPointer < 0)
|
||||
break;
|
||||
}
|
||||
layoutPointer--;
|
||||
}
|
||||
return pageBuffer.filter((line) => typeof line === 'string');
|
||||
}
|
31
node_modules/@inquirer/core/dist/cjs/lib/pagination/position.js
generated
vendored
Normal file
31
node_modules/@inquirer/core/dist/cjs/lib/pagination/position.js
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.finite = finite;
|
||||
exports.infinite = infinite;
|
||||
/**
|
||||
* Creates the next position for the active item considering a finite list of
|
||||
* items to be rendered on a page.
|
||||
*/
|
||||
function finite({ active, pageSize, total, }) {
|
||||
const middle = Math.floor(pageSize / 2);
|
||||
if (total <= pageSize || active < middle)
|
||||
return active;
|
||||
if (active >= total - middle)
|
||||
return active + pageSize - total;
|
||||
return middle;
|
||||
}
|
||||
/**
|
||||
* Creates the next position for the active item considering an infinitely
|
||||
* looping list of items to be rendered on the page.
|
||||
*/
|
||||
function infinite({ active, lastActive, total, pageSize, pointer, }) {
|
||||
if (total <= pageSize)
|
||||
return active;
|
||||
// Move the position only when the user moves down, and when the
|
||||
// navigation fits within a single page
|
||||
if (lastActive < active && active - lastActive < pageSize) {
|
||||
// Limit it to the middle of the list
|
||||
return Math.min(Math.floor(pageSize / 2), pointer + active - lastActive);
|
||||
}
|
||||
return pointer;
|
||||
}
|
33
node_modules/@inquirer/core/dist/cjs/lib/pagination/use-pagination.js
generated
vendored
Normal file
33
node_modules/@inquirer/core/dist/cjs/lib/pagination/use-pagination.js
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.usePagination = usePagination;
|
||||
const use_ref_mjs_1 = require('../use-ref.js');
|
||||
const utils_mjs_1 = require('../utils.js');
|
||||
const lines_mjs_1 = require('./lines.js');
|
||||
const position_mjs_1 = require('./position.js');
|
||||
function usePagination({ items, active, renderItem, pageSize, loop = true, }) {
|
||||
const state = (0, use_ref_mjs_1.useRef)({ position: 0, lastActive: 0 });
|
||||
const position = loop
|
||||
? (0, position_mjs_1.infinite)({
|
||||
active,
|
||||
lastActive: state.current.lastActive,
|
||||
total: items.length,
|
||||
pageSize,
|
||||
pointer: state.current.position,
|
||||
})
|
||||
: (0, position_mjs_1.finite)({
|
||||
active,
|
||||
total: items.length,
|
||||
pageSize,
|
||||
});
|
||||
state.current.position = position;
|
||||
state.current.lastActive = active;
|
||||
return (0, lines_mjs_1.lines)({
|
||||
items,
|
||||
width: (0, utils_mjs_1.readlineWidth)(),
|
||||
renderItem,
|
||||
active,
|
||||
position,
|
||||
pageSize,
|
||||
}).join('\n');
|
||||
}
|
18
node_modules/@inquirer/core/dist/cjs/lib/promise-polyfill.js
generated
vendored
Normal file
18
node_modules/@inquirer/core/dist/cjs/lib/promise-polyfill.js
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PromisePolyfill = void 0;
|
||||
// TODO: Remove this class once Node 22 becomes the minimum supported version.
|
||||
class PromisePolyfill extends Promise {
|
||||
// Available starting from Node 22
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
||||
static withResolver() {
|
||||
let resolve;
|
||||
let reject;
|
||||
const promise = new Promise((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
return { promise, resolve: resolve, reject: reject };
|
||||
}
|
||||
}
|
||||
exports.PromisePolyfill = PromisePolyfill;
|
110
node_modules/@inquirer/core/dist/cjs/lib/screen-manager.js
generated
vendored
Normal file
110
node_modules/@inquirer/core/dist/cjs/lib/screen-manager.js
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const strip_ansi_1 = __importDefault(require("strip-ansi"));
|
||||
const ansi_escapes_1 = __importDefault(require("ansi-escapes"));
|
||||
const utils_mjs_1 = require('./utils.js');
|
||||
const height = (content) => content.split('\n').length;
|
||||
const lastLine = (content) => { var _a; return (_a = content.split('\n').pop()) !== null && _a !== void 0 ? _a : ''; };
|
||||
function cursorDown(n) {
|
||||
return n > 0 ? ansi_escapes_1.default.cursorDown(n) : '';
|
||||
}
|
||||
class ScreenManager {
|
||||
constructor(rl) {
|
||||
Object.defineProperty(this, "rl", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: rl
|
||||
});
|
||||
// These variables are keeping information to allow correct prompt re-rendering
|
||||
Object.defineProperty(this, "height", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 0
|
||||
});
|
||||
Object.defineProperty(this, "extraLinesUnderPrompt", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 0
|
||||
});
|
||||
Object.defineProperty(this, "cursorPos", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: void 0
|
||||
});
|
||||
this.rl = rl;
|
||||
this.cursorPos = rl.getCursorPos();
|
||||
}
|
||||
write(content) {
|
||||
this.rl.output.unmute();
|
||||
this.rl.output.write(content);
|
||||
this.rl.output.mute();
|
||||
}
|
||||
render(content, bottomContent = '') {
|
||||
// Write message to screen and setPrompt to control backspace
|
||||
const promptLine = lastLine(content);
|
||||
const rawPromptLine = (0, strip_ansi_1.default)(promptLine);
|
||||
// Remove the rl.line from our prompt. We can't rely on the content of
|
||||
// rl.line (mainly because of the password prompt), so just rely on it's
|
||||
// length.
|
||||
let prompt = rawPromptLine;
|
||||
if (this.rl.line.length > 0) {
|
||||
prompt = prompt.slice(0, -this.rl.line.length);
|
||||
}
|
||||
this.rl.setPrompt(prompt);
|
||||
// SetPrompt will change cursor position, now we can get correct value
|
||||
this.cursorPos = this.rl.getCursorPos();
|
||||
const width = (0, utils_mjs_1.readlineWidth)();
|
||||
content = (0, utils_mjs_1.breakLines)(content, width);
|
||||
bottomContent = (0, utils_mjs_1.breakLines)(bottomContent, width);
|
||||
// Manually insert an extra line if we're at the end of the line.
|
||||
// This prevent the cursor from appearing at the beginning of the
|
||||
// current line.
|
||||
if (rawPromptLine.length % width === 0) {
|
||||
content += '\n';
|
||||
}
|
||||
let output = content + (bottomContent ? '\n' + bottomContent : '');
|
||||
/**
|
||||
* Re-adjust the cursor at the correct position.
|
||||
*/
|
||||
// We need to consider parts of the prompt under the cursor as part of the bottom
|
||||
// content in order to correctly cleanup and re-render.
|
||||
const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
|
||||
const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
|
||||
// Return cursor to the input position (on top of the bottomContent)
|
||||
if (bottomContentHeight > 0)
|
||||
output += ansi_escapes_1.default.cursorUp(bottomContentHeight);
|
||||
// Return cursor to the initial left offset.
|
||||
output += ansi_escapes_1.default.cursorTo(this.cursorPos.cols);
|
||||
/**
|
||||
* Render and store state for future re-rendering
|
||||
*/
|
||||
this.write(cursorDown(this.extraLinesUnderPrompt) +
|
||||
ansi_escapes_1.default.eraseLines(this.height) +
|
||||
output);
|
||||
this.extraLinesUnderPrompt = bottomContentHeight;
|
||||
this.height = height(output);
|
||||
}
|
||||
checkCursorPos() {
|
||||
const cursorPos = this.rl.getCursorPos();
|
||||
if (cursorPos.cols !== this.cursorPos.cols) {
|
||||
this.write(ansi_escapes_1.default.cursorTo(cursorPos.cols));
|
||||
this.cursorPos = cursorPos;
|
||||
}
|
||||
}
|
||||
done({ clearContent }) {
|
||||
this.rl.setPrompt('');
|
||||
let output = cursorDown(this.extraLinesUnderPrompt);
|
||||
output += clearContent ? ansi_escapes_1.default.eraseLines(this.height) : '\n';
|
||||
output += ansi_escapes_1.default.cursorShow;
|
||||
this.write(output);
|
||||
this.rl.close();
|
||||
}
|
||||
}
|
||||
exports.default = ScreenManager;
|
28
node_modules/@inquirer/core/dist/cjs/lib/theme.js
generated
vendored
Normal file
28
node_modules/@inquirer/core/dist/cjs/lib/theme.js
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.defaultTheme = void 0;
|
||||
const yoctocolors_cjs_1 = __importDefault(require("yoctocolors-cjs"));
|
||||
const figures_1 = __importDefault(require("@inquirer/figures"));
|
||||
exports.defaultTheme = {
|
||||
prefix: {
|
||||
idle: yoctocolors_cjs_1.default.blue('?'),
|
||||
// TODO: use figure
|
||||
done: yoctocolors_cjs_1.default.green(figures_1.default.tick),
|
||||
},
|
||||
spinner: {
|
||||
interval: 80,
|
||||
frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'].map((frame) => yoctocolors_cjs_1.default.yellow(frame)),
|
||||
},
|
||||
style: {
|
||||
answer: yoctocolors_cjs_1.default.cyan,
|
||||
message: yoctocolors_cjs_1.default.bold,
|
||||
error: (text) => yoctocolors_cjs_1.default.red(`> ${text}`),
|
||||
defaultAnswer: (text) => yoctocolors_cjs_1.default.dim(`(${text})`),
|
||||
help: yoctocolors_cjs_1.default.dim,
|
||||
highlight: yoctocolors_cjs_1.default.cyan,
|
||||
key: (text) => yoctocolors_cjs_1.default.cyan(yoctocolors_cjs_1.default.bold(`<${text}>`)),
|
||||
},
|
||||
};
|
14
node_modules/@inquirer/core/dist/cjs/lib/use-effect.js
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/cjs/lib/use-effect.js
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useEffect = useEffect;
|
||||
const hook_engine_mjs_1 = require('./hook-engine.js');
|
||||
function useEffect(cb, depArray) {
|
||||
(0, hook_engine_mjs_1.withPointer)((pointer) => {
|
||||
const oldDeps = pointer.get();
|
||||
const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
|
||||
if (hasChanged) {
|
||||
hook_engine_mjs_1.effectScheduler.queue(cb);
|
||||
}
|
||||
pointer.set(depArray);
|
||||
});
|
||||
}
|
23
node_modules/@inquirer/core/dist/cjs/lib/use-keypress.js
generated
vendored
Normal file
23
node_modules/@inquirer/core/dist/cjs/lib/use-keypress.js
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useKeypress = useKeypress;
|
||||
const use_ref_mjs_1 = require('./use-ref.js');
|
||||
const use_effect_mjs_1 = require('./use-effect.js');
|
||||
const hook_engine_mjs_1 = require('./hook-engine.js');
|
||||
function useKeypress(userHandler) {
|
||||
const signal = (0, use_ref_mjs_1.useRef)(userHandler);
|
||||
signal.current = userHandler;
|
||||
(0, use_effect_mjs_1.useEffect)((rl) => {
|
||||
let ignore = false;
|
||||
const handler = (0, hook_engine_mjs_1.withUpdates)((_input, event) => {
|
||||
if (ignore)
|
||||
return;
|
||||
void signal.current(event, rl);
|
||||
});
|
||||
rl.input.on('keypress', handler);
|
||||
return () => {
|
||||
ignore = true;
|
||||
rl.input.removeListener('keypress', handler);
|
||||
};
|
||||
}, []);
|
||||
}
|
17
node_modules/@inquirer/core/dist/cjs/lib/use-memo.js
generated
vendored
Normal file
17
node_modules/@inquirer/core/dist/cjs/lib/use-memo.js
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useMemo = useMemo;
|
||||
const hook_engine_mjs_1 = require('./hook-engine.js');
|
||||
function useMemo(fn, dependencies) {
|
||||
return (0, hook_engine_mjs_1.withPointer)((pointer) => {
|
||||
const prev = pointer.get();
|
||||
if (!prev ||
|
||||
prev.dependencies.length !== dependencies.length ||
|
||||
prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
|
||||
const value = fn();
|
||||
pointer.set({ value, dependencies });
|
||||
return value;
|
||||
}
|
||||
return prev.value;
|
||||
});
|
||||
}
|
39
node_modules/@inquirer/core/dist/cjs/lib/use-prefix.js
generated
vendored
Normal file
39
node_modules/@inquirer/core/dist/cjs/lib/use-prefix.js
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.usePrefix = usePrefix;
|
||||
const node_async_hooks_1 = require("node:async_hooks");
|
||||
const use_state_mjs_1 = require('./use-state.js');
|
||||
const use_effect_mjs_1 = require('./use-effect.js');
|
||||
const make_theme_mjs_1 = require('./make-theme.js');
|
||||
function usePrefix({ status = 'idle', theme, }) {
|
||||
const [showLoader, setShowLoader] = (0, use_state_mjs_1.useState)(false);
|
||||
const [tick, setTick] = (0, use_state_mjs_1.useState)(0);
|
||||
const { prefix, spinner } = (0, make_theme_mjs_1.makeTheme)(theme);
|
||||
(0, use_effect_mjs_1.useEffect)(() => {
|
||||
if (status === 'loading') {
|
||||
let tickInterval;
|
||||
let inc = -1;
|
||||
// Delay displaying spinner by 300ms, to avoid flickering
|
||||
const delayTimeout = setTimeout(node_async_hooks_1.AsyncResource.bind(() => {
|
||||
setShowLoader(true);
|
||||
tickInterval = setInterval(node_async_hooks_1.AsyncResource.bind(() => {
|
||||
inc = inc + 1;
|
||||
setTick(inc % spinner.frames.length);
|
||||
}), spinner.interval);
|
||||
}), 300);
|
||||
return () => {
|
||||
clearTimeout(delayTimeout);
|
||||
clearInterval(tickInterval);
|
||||
};
|
||||
}
|
||||
else {
|
||||
setShowLoader(false);
|
||||
}
|
||||
}, [status]);
|
||||
if (showLoader) {
|
||||
return spinner.frames[tick];
|
||||
}
|
||||
// There's a delay before we show the loader. So we want to ignore `loading` here, and pass idle instead.
|
||||
const iconName = status === 'loading' ? 'idle' : status;
|
||||
return typeof prefix === 'string' ? prefix : prefix[iconName];
|
||||
}
|
7
node_modules/@inquirer/core/dist/cjs/lib/use-ref.js
generated
vendored
Normal file
7
node_modules/@inquirer/core/dist/cjs/lib/use-ref.js
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useRef = useRef;
|
||||
const use_state_mjs_1 = require('./use-state.js');
|
||||
function useRef(val) {
|
||||
return (0, use_state_mjs_1.useState)({ current: val })[0];
|
||||
}
|
22
node_modules/@inquirer/core/dist/cjs/lib/use-state.js
generated
vendored
Normal file
22
node_modules/@inquirer/core/dist/cjs/lib/use-state.js
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useState = useState;
|
||||
const hook_engine_mjs_1 = require('./hook-engine.js');
|
||||
function useState(defaultValue) {
|
||||
return (0, hook_engine_mjs_1.withPointer)((pointer) => {
|
||||
const setFn = (newValue) => {
|
||||
// Noop if the value is still the same.
|
||||
if (pointer.get() !== newValue) {
|
||||
pointer.set(newValue);
|
||||
// Trigger re-render
|
||||
(0, hook_engine_mjs_1.handleChange)();
|
||||
}
|
||||
};
|
||||
if (pointer.initialized) {
|
||||
return [pointer.get(), setFn];
|
||||
}
|
||||
const value = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
||||
pointer.set(value);
|
||||
return [value, setFn];
|
||||
});
|
||||
}
|
32
node_modules/@inquirer/core/dist/cjs/lib/utils.js
generated
vendored
Normal file
32
node_modules/@inquirer/core/dist/cjs/lib/utils.js
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.breakLines = breakLines;
|
||||
exports.readlineWidth = readlineWidth;
|
||||
const cli_width_1 = __importDefault(require("cli-width"));
|
||||
const wrap_ansi_1 = __importDefault(require("wrap-ansi"));
|
||||
const hook_engine_mjs_1 = require('./hook-engine.js');
|
||||
/**
|
||||
* Force line returns at specific width. This function is ANSI code friendly and it'll
|
||||
* ignore invisible codes during width calculation.
|
||||
* @param {string} content
|
||||
* @param {number} width
|
||||
* @return {string}
|
||||
*/
|
||||
function breakLines(content, width) {
|
||||
return content
|
||||
.split('\n')
|
||||
.flatMap((line) => (0, wrap_ansi_1.default)(line, width, { trim: false, hard: true })
|
||||
.split('\n')
|
||||
.map((str) => str.trimEnd()))
|
||||
.join('\n');
|
||||
}
|
||||
/**
|
||||
* Returns the width of the active readline, or 80 as default value.
|
||||
* @returns {number}
|
||||
*/
|
||||
function readlineWidth() {
|
||||
return (0, cli_width_1.default)({ defaultWidth: 80, output: (0, hook_engine_mjs_1.readline)().output });
|
||||
}
|
13
node_modules/@inquirer/core/dist/cjs/types/index.d.ts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/cjs/types/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
export * from './lib/key.js';
|
||||
export * from './lib/errors.js';
|
||||
export { usePrefix } from './lib/use-prefix.js';
|
||||
export { useState } from './lib/use-state.js';
|
||||
export { useEffect } from './lib/use-effect.js';
|
||||
export { useMemo } from './lib/use-memo.js';
|
||||
export { useRef } from './lib/use-ref.js';
|
||||
export { useKeypress } from './lib/use-keypress.js';
|
||||
export { makeTheme } from './lib/make-theme.js';
|
||||
export type { Theme, Status } from './lib/theme.js';
|
||||
export { usePagination } from './lib/pagination/use-pagination.js';
|
||||
export { createPrompt } from './lib/create-prompt.js';
|
||||
export { Separator } from './lib/Separator.js';
|
10
node_modules/@inquirer/core/dist/cjs/types/lib/Separator.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/core/dist/cjs/types/lib/Separator.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* Separator object
|
||||
* Used to space/separate choices group
|
||||
*/
|
||||
export declare class Separator {
|
||||
readonly separator: string;
|
||||
readonly type = "separator";
|
||||
constructor(separator?: string);
|
||||
static isSeparator(choice: unknown): choice is Separator;
|
||||
}
|
4
node_modules/@inquirer/core/dist/cjs/types/lib/create-prompt.d.ts
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/cjs/types/lib/create-prompt.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { type Prompt, type Prettify } from '@inquirer/type';
|
||||
type ViewFunction<Value, Config> = (config: Prettify<Config>, done: (value: Value) => void) => string | [string, string | undefined];
|
||||
export declare function createPrompt<Value, Config>(view: ViewFunction<Value, Config>): Prompt<Value, Config>;
|
||||
export {};
|
20
node_modules/@inquirer/core/dist/cjs/types/lib/errors.d.ts
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/cjs/types/lib/errors.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
export declare class AbortPromptError extends Error {
|
||||
name: string;
|
||||
message: string;
|
||||
constructor(options?: {
|
||||
cause?: unknown;
|
||||
});
|
||||
}
|
||||
export declare class CancelPromptError extends Error {
|
||||
name: string;
|
||||
message: string;
|
||||
}
|
||||
export declare class ExitPromptError extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class HookError extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class ValidationError extends Error {
|
||||
name: string;
|
||||
}
|
23
node_modules/@inquirer/core/dist/cjs/types/lib/hook-engine.d.ts
generated
vendored
Normal file
23
node_modules/@inquirer/core/dist/cjs/types/lib/hook-engine.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
import type { InquirerReadline } from '@inquirer/type';
|
||||
export declare function withHooks<T>(rl: InquirerReadline, cb: (cycle: (render: () => void) => void) => T): T;
|
||||
export declare function readline(): InquirerReadline;
|
||||
export declare function withUpdates<R, T extends (...args: any[]) => R>(fn: T): (...args: Parameters<T>) => R;
|
||||
type SetPointer<Value> = {
|
||||
get(): Value;
|
||||
set(value: Value): void;
|
||||
initialized: true;
|
||||
};
|
||||
type UnsetPointer<Value> = {
|
||||
get(): void;
|
||||
set(value: Value): void;
|
||||
initialized: false;
|
||||
};
|
||||
type Pointer<Value> = SetPointer<Value> | UnsetPointer<Value>;
|
||||
export declare function withPointer<Value, ReturnValue>(cb: (pointer: Pointer<Value>) => ReturnValue): ReturnValue;
|
||||
export declare function handleChange(): void;
|
||||
export declare const effectScheduler: {
|
||||
queue(cb: (readline: InquirerReadline) => void): void;
|
||||
run(): void;
|
||||
clearAll(): void;
|
||||
};
|
||||
export {};
|
10
node_modules/@inquirer/core/dist/cjs/types/lib/key.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/core/dist/cjs/types/lib/key.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
export type KeypressEvent = {
|
||||
name: string;
|
||||
ctrl: boolean;
|
||||
};
|
||||
export declare const isUpKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isDownKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isSpaceKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isBackspaceKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isNumberKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isEnterKey: (key: KeypressEvent) => boolean;
|
3
node_modules/@inquirer/core/dist/cjs/types/lib/make-theme.d.ts
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/cjs/types/lib/make-theme.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
import type { Prettify, PartialDeep } from '@inquirer/type';
|
||||
import { type Theme } from './theme.js';
|
||||
export declare function makeTheme<SpecificTheme extends object>(...themes: ReadonlyArray<undefined | PartialDeep<Theme<SpecificTheme>>>): Prettify<Theme<SpecificTheme>>;
|
26
node_modules/@inquirer/core/dist/cjs/types/lib/pagination/lines.d.ts
generated
vendored
Normal file
26
node_modules/@inquirer/core/dist/cjs/types/lib/pagination/lines.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { type Prettify } from '@inquirer/type';
|
||||
/** Represents an item that's part of a layout, about to be rendered */
|
||||
export type Layout<T> = {
|
||||
item: T;
|
||||
index: number;
|
||||
isActive: boolean;
|
||||
};
|
||||
/**
|
||||
* Renders a page of items as lines that fit within the given width ensuring
|
||||
* that the number of lines is not greater than the page size, and the active
|
||||
* item renders at the provided position, while prioritizing that as many lines
|
||||
* of the active item get rendered as possible.
|
||||
*/
|
||||
export declare function lines<T>({ items, width, renderItem, active, position: requested, pageSize, }: {
|
||||
items: ReadonlyArray<T>;
|
||||
/** The width of a rendered line in characters. */
|
||||
width: number;
|
||||
/** Renders an item as part of a page. */
|
||||
renderItem: (layout: Prettify<Layout<T>>) => string;
|
||||
/** The index of the active item in the list of items. */
|
||||
active: number;
|
||||
/** The position on the page at which to render the active item. */
|
||||
position: number;
|
||||
/** The number of lines to render per page. */
|
||||
pageSize: number;
|
||||
}): string[];
|
20
node_modules/@inquirer/core/dist/cjs/types/lib/pagination/position.d.ts
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/cjs/types/lib/pagination/position.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Creates the next position for the active item considering a finite list of
|
||||
* items to be rendered on a page.
|
||||
*/
|
||||
export declare function finite({ active, pageSize, total, }: {
|
||||
active: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
}): number;
|
||||
/**
|
||||
* Creates the next position for the active item considering an infinitely
|
||||
* looping list of items to be rendered on the page.
|
||||
*/
|
||||
export declare function infinite({ active, lastActive, total, pageSize, pointer, }: {
|
||||
active: number;
|
||||
lastActive: number;
|
||||
total: number;
|
||||
pageSize: number;
|
||||
pointer: number;
|
||||
}): number;
|
15
node_modules/@inquirer/core/dist/cjs/types/lib/pagination/use-pagination.d.ts
generated
vendored
Normal file
15
node_modules/@inquirer/core/dist/cjs/types/lib/pagination/use-pagination.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
import type { Prettify } from '@inquirer/type';
|
||||
import { type Theme } from '../theme.js';
|
||||
import { type Layout } from './lines.js';
|
||||
export declare function usePagination<T>({ items, active, renderItem, pageSize, loop, }: {
|
||||
items: ReadonlyArray<T>;
|
||||
/** The index of the active item. */
|
||||
active: number;
|
||||
/** Renders an item as part of a page. */
|
||||
renderItem: (layout: Prettify<Layout<T>>) => string;
|
||||
/** The size of the page. */
|
||||
pageSize: number;
|
||||
/** Allows creating an infinitely looping list. `true` if unspecified. */
|
||||
loop?: boolean;
|
||||
theme?: Theme;
|
||||
}): string;
|
7
node_modules/@inquirer/core/dist/cjs/types/lib/promise-polyfill.d.ts
generated
vendored
Normal file
7
node_modules/@inquirer/core/dist/cjs/types/lib/promise-polyfill.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
export declare class PromisePolyfill<T> extends Promise<T> {
|
||||
static withResolver<T>(): {
|
||||
promise: Promise<T>;
|
||||
resolve: (value: T) => void;
|
||||
reject: (error: unknown) => void;
|
||||
};
|
||||
}
|
14
node_modules/@inquirer/core/dist/cjs/types/lib/screen-manager.d.ts
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/cjs/types/lib/screen-manager.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
import type { InquirerReadline } from '@inquirer/type';
|
||||
export default class ScreenManager {
|
||||
private readonly rl;
|
||||
private height;
|
||||
private extraLinesUnderPrompt;
|
||||
private cursorPos;
|
||||
constructor(rl: InquirerReadline);
|
||||
write(content: string): void;
|
||||
render(content: string, bottomContent?: string): void;
|
||||
checkCursorPos(): void;
|
||||
done({ clearContent }: {
|
||||
clearContent: boolean;
|
||||
}): void;
|
||||
}
|
154
node_modules/@inquirer/core/dist/cjs/types/lib/theme.d.ts
generated
vendored
Normal file
154
node_modules/@inquirer/core/dist/cjs/types/lib/theme.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
import type { Prettify } from '@inquirer/type';
|
||||
/**
|
||||
* Union type representing the possible statuses of a prompt.
|
||||
*
|
||||
* - `'loading'`: The prompt is currently loading.
|
||||
* - `'idle'`: The prompt is loaded and currently waiting for the user to
|
||||
* submit an answer.
|
||||
* - `'done'`: The user has submitted an answer and the prompt is finished.
|
||||
*/
|
||||
export type Status = 'loading' | 'idle' | 'done';
|
||||
type DefaultTheme = {
|
||||
/**
|
||||
* Prefix to prepend to the message. If a function is provided, it will be
|
||||
* called with the current status of the prompt, and the return value will be
|
||||
* used as the prefix.
|
||||
*
|
||||
* @remarks
|
||||
* If `status === 'loading'`, this property is ignored and the spinner (styled
|
||||
* by the `spinner` property) will be displayed instead.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (status) => status === 'done' ? colors.green('✔') : colors.blue('?')
|
||||
* ```
|
||||
*/
|
||||
prefix: string | Prettify<Omit<Record<Status, string>, 'loading'>>;
|
||||
/**
|
||||
* Configuration for the spinner that is displayed when the prompt is in the
|
||||
* `'loading'` state.
|
||||
*
|
||||
* We recommend the use of {@link https://github.com/sindresorhus/cli-spinners|cli-spinners} for a list of available spinners.
|
||||
*/
|
||||
spinner: {
|
||||
/**
|
||||
* The time interval between frames, in milliseconds.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* 80
|
||||
* ```
|
||||
*/
|
||||
interval: number;
|
||||
/**
|
||||
* A list of frames to show for the spinner.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
||||
* ```
|
||||
*/
|
||||
frames: string[];
|
||||
};
|
||||
/**
|
||||
* Object containing functions to style different parts of the prompt.
|
||||
*/
|
||||
style: {
|
||||
/**
|
||||
* Style to apply to the user's answer once it has been submitted.
|
||||
*
|
||||
* @param text - The user's answer.
|
||||
* @returns The styled answer.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.cyan(text)
|
||||
* ```
|
||||
*/
|
||||
answer: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to the message displayed to the user.
|
||||
*
|
||||
* @param text - The message to style.
|
||||
* @param status - The current status of the prompt.
|
||||
* @returns The styled message.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text, status) => colors.bold(text)
|
||||
* ```
|
||||
*/
|
||||
message: (text: string, status: Status) => string;
|
||||
/**
|
||||
* Style to apply to error messages.
|
||||
*
|
||||
* @param text - The error message.
|
||||
* @returns The styled error message.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.red(`> ${text}`)
|
||||
* ```
|
||||
*/
|
||||
error: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to the default answer when one is provided.
|
||||
*
|
||||
* @param text - The default answer.
|
||||
* @returns The styled default answer.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.dim(`(${text})`)
|
||||
* ```
|
||||
*/
|
||||
defaultAnswer: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to help text.
|
||||
*
|
||||
* @param text - The help text.
|
||||
* @returns The styled help text.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.dim(text)
|
||||
* ```
|
||||
*/
|
||||
help: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to highlighted text.
|
||||
*
|
||||
* @param text - The text to highlight.
|
||||
* @returns The highlighted text.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.cyan(text)
|
||||
* ```
|
||||
*/
|
||||
highlight: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to keyboard keys referred to in help texts.
|
||||
*
|
||||
* @param text - The key to style.
|
||||
* @returns The styled key.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.cyan(colors.bold(`<${text}>`))
|
||||
* ```
|
||||
*/
|
||||
key: (text: string) => string;
|
||||
};
|
||||
};
|
||||
export type Theme<Extension extends object = object> = Prettify<Extension & DefaultTheme>;
|
||||
export declare const defaultTheme: DefaultTheme;
|
||||
export {};
|
2
node_modules/@inquirer/core/dist/cjs/types/lib/use-effect.d.ts
generated
vendored
Normal file
2
node_modules/@inquirer/core/dist/cjs/types/lib/use-effect.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
import type { InquirerReadline } from '@inquirer/type';
|
||||
export declare function useEffect(cb: (rl: InquirerReadline) => void | (() => void), depArray: ReadonlyArray<unknown>): void;
|
3
node_modules/@inquirer/core/dist/cjs/types/lib/use-keypress.d.ts
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/cjs/types/lib/use-keypress.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
import { type InquirerReadline } from '@inquirer/type';
|
||||
import { type KeypressEvent } from './key.js';
|
||||
export declare function useKeypress(userHandler: (event: KeypressEvent, rl: InquirerReadline) => void | Promise<void>): void;
|
1
node_modules/@inquirer/core/dist/cjs/types/lib/use-memo.d.ts
generated
vendored
Normal file
1
node_modules/@inquirer/core/dist/cjs/types/lib/use-memo.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare function useMemo<Value>(fn: () => Value, dependencies: ReadonlyArray<unknown>): Value;
|
5
node_modules/@inquirer/core/dist/cjs/types/lib/use-prefix.d.ts
generated
vendored
Normal file
5
node_modules/@inquirer/core/dist/cjs/types/lib/use-prefix.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import type { Theme, Status } from './theme.js';
|
||||
export declare function usePrefix({ status, theme, }: {
|
||||
status?: Status;
|
||||
theme?: Theme;
|
||||
}): string;
|
6
node_modules/@inquirer/core/dist/cjs/types/lib/use-ref.d.ts
generated
vendored
Normal file
6
node_modules/@inquirer/core/dist/cjs/types/lib/use-ref.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
export declare function useRef<Value>(val: Value): {
|
||||
current: Value;
|
||||
};
|
||||
export declare function useRef<Value>(val?: Value): {
|
||||
current: Value | undefined;
|
||||
};
|
4
node_modules/@inquirer/core/dist/cjs/types/lib/use-state.d.ts
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/cjs/types/lib/use-state.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
type NotFunction<T> = T extends (...args: never) => unknown ? never : T;
|
||||
export declare function useState<Value>(defaultValue: NotFunction<Value> | (() => Value)): [Value, (newValue: Value) => void];
|
||||
export declare function useState<Value>(defaultValue?: NotFunction<Value> | (() => Value)): [Value | undefined, (newValue?: Value) => void];
|
||||
export {};
|
13
node_modules/@inquirer/core/dist/cjs/types/lib/utils.d.ts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/cjs/types/lib/utils.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* Force line returns at specific width. This function is ANSI code friendly and it'll
|
||||
* ignore invisible codes during width calculation.
|
||||
* @param {string} content
|
||||
* @param {number} width
|
||||
* @return {string}
|
||||
*/
|
||||
export declare function breakLines(content: string, width: number): string;
|
||||
/**
|
||||
* Returns the width of the active readline, or 80 as default value.
|
||||
* @returns {number}
|
||||
*/
|
||||
export declare function readlineWidth(): number;
|
12
node_modules/@inquirer/core/dist/esm/index.mjs
generated
vendored
Normal file
12
node_modules/@inquirer/core/dist/esm/index.mjs
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
export * from './lib/key.mjs';
|
||||
export * from './lib/errors.mjs';
|
||||
export { usePrefix } from './lib/use-prefix.mjs';
|
||||
export { useState } from './lib/use-state.mjs';
|
||||
export { useEffect } from './lib/use-effect.mjs';
|
||||
export { useMemo } from './lib/use-memo.mjs';
|
||||
export { useRef } from './lib/use-ref.mjs';
|
||||
export { useKeypress } from './lib/use-keypress.mjs';
|
||||
export { makeTheme } from './lib/make-theme.mjs';
|
||||
export { usePagination } from './lib/pagination/use-pagination.mjs';
|
||||
export { createPrompt } from './lib/create-prompt.mjs';
|
||||
export { Separator } from './lib/Separator.mjs';
|
21
node_modules/@inquirer/core/dist/esm/lib/Separator.mjs
generated
vendored
Normal file
21
node_modules/@inquirer/core/dist/esm/lib/Separator.mjs
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
import colors from 'yoctocolors-cjs';
|
||||
import figures from '@inquirer/figures';
|
||||
/**
|
||||
* Separator object
|
||||
* Used to space/separate choices group
|
||||
*/
|
||||
export class Separator {
|
||||
separator = colors.dim(Array.from({ length: 15 }).join(figures.line));
|
||||
type = 'separator';
|
||||
constructor(separator) {
|
||||
if (separator) {
|
||||
this.separator = separator;
|
||||
}
|
||||
}
|
||||
static isSeparator(choice) {
|
||||
return Boolean(choice &&
|
||||
typeof choice === 'object' &&
|
||||
'type' in choice &&
|
||||
choice.type === 'separator');
|
||||
}
|
||||
}
|
84
node_modules/@inquirer/core/dist/esm/lib/create-prompt.mjs
generated
vendored
Normal file
84
node_modules/@inquirer/core/dist/esm/lib/create-prompt.mjs
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
import * as readline from 'node:readline';
|
||||
import { AsyncResource } from 'node:async_hooks';
|
||||
import MuteStream from 'mute-stream';
|
||||
import { onExit as onSignalExit } from 'signal-exit';
|
||||
import ScreenManager from './screen-manager.mjs';
|
||||
import { PromisePolyfill } from './promise-polyfill.mjs';
|
||||
import { withHooks, effectScheduler } from './hook-engine.mjs';
|
||||
import { AbortPromptError, CancelPromptError, ExitPromptError } from './errors.mjs';
|
||||
export function createPrompt(view) {
|
||||
const prompt = (config, context = {}) => {
|
||||
// Default `input` to stdin
|
||||
const { input = process.stdin, signal } = context;
|
||||
const cleanups = new Set();
|
||||
// Add mute capabilities to the output
|
||||
const output = new MuteStream();
|
||||
output.pipe(context.output ?? process.stdout);
|
||||
const rl = readline.createInterface({
|
||||
terminal: true,
|
||||
input,
|
||||
output,
|
||||
});
|
||||
const screen = new ScreenManager(rl);
|
||||
const { promise, resolve, reject } = PromisePolyfill.withResolver();
|
||||
/** @deprecated pass an AbortSignal in the context options instead. See {@link https://github.com/SBoudrias/Inquirer.js#canceling-prompt} */
|
||||
const cancel = () => reject(new CancelPromptError());
|
||||
if (signal) {
|
||||
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
||||
if (signal.aborted) {
|
||||
abort();
|
||||
return Object.assign(promise, { cancel });
|
||||
}
|
||||
signal.addEventListener('abort', abort);
|
||||
cleanups.add(() => signal.removeEventListener('abort', abort));
|
||||
}
|
||||
cleanups.add(onSignalExit((code, signal) => {
|
||||
reject(new ExitPromptError(`User force closed the prompt with ${code} ${signal}`));
|
||||
}));
|
||||
// Re-renders only happen when the state change; but the readline cursor could change position
|
||||
// and that also requires a re-render (and a manual one because we mute the streams).
|
||||
// We set the listener after the initial workLoop to avoid a double render if render triggered
|
||||
// by a state change sets the cursor to the right position.
|
||||
const checkCursorPos = () => screen.checkCursorPos();
|
||||
rl.input.on('keypress', checkCursorPos);
|
||||
cleanups.add(() => rl.input.removeListener('keypress', checkCursorPos));
|
||||
return withHooks(rl, (cycle) => {
|
||||
// The close event triggers immediately when the user press ctrl+c. SignalExit on the other hand
|
||||
// triggers after the process is done (which happens after timeouts are done triggering.)
|
||||
// We triggers the hooks cleanup phase on rl `close` so active timeouts can be cleared.
|
||||
const hooksCleanup = AsyncResource.bind(() => effectScheduler.clearAll());
|
||||
rl.on('close', hooksCleanup);
|
||||
cleanups.add(() => rl.removeListener('close', hooksCleanup));
|
||||
cycle(() => {
|
||||
try {
|
||||
const nextView = view(config, (value) => {
|
||||
setImmediate(() => resolve(value));
|
||||
});
|
||||
const [content, bottomContent] = typeof nextView === 'string' ? [nextView] : nextView;
|
||||
screen.render(content, bottomContent);
|
||||
effectScheduler.run();
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return Object.assign(promise
|
||||
.then((answer) => {
|
||||
effectScheduler.clearAll();
|
||||
return answer;
|
||||
}, (error) => {
|
||||
effectScheduler.clearAll();
|
||||
throw error;
|
||||
})
|
||||
// Wait for the promise to settle, then cleanup.
|
||||
.finally(() => {
|
||||
cleanups.forEach((cleanup) => cleanup());
|
||||
screen.done({ clearContent: Boolean(context?.clearPromptOnDone) });
|
||||
output.end();
|
||||
})
|
||||
// Once cleanup is done, let the expose promise resolve/reject to the internal one.
|
||||
.then(() => promise), { cancel });
|
||||
});
|
||||
};
|
||||
return prompt;
|
||||
}
|
21
node_modules/@inquirer/core/dist/esm/lib/errors.mjs
generated
vendored
Normal file
21
node_modules/@inquirer/core/dist/esm/lib/errors.mjs
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
export class AbortPromptError extends Error {
|
||||
name = 'AbortPromptError';
|
||||
message = 'Prompt was aborted';
|
||||
constructor(options) {
|
||||
super();
|
||||
this.cause = options?.cause;
|
||||
}
|
||||
}
|
||||
export class CancelPromptError extends Error {
|
||||
name = 'CancelPromptError';
|
||||
message = 'Prompt was canceled';
|
||||
}
|
||||
export class ExitPromptError extends Error {
|
||||
name = 'ExitPromptError';
|
||||
}
|
||||
export class HookError extends Error {
|
||||
name = 'HookError';
|
||||
}
|
||||
export class ValidationError extends Error {
|
||||
name = 'ValidationError';
|
||||
}
|
110
node_modules/@inquirer/core/dist/esm/lib/hook-engine.mjs
generated
vendored
Normal file
110
node_modules/@inquirer/core/dist/esm/lib/hook-engine.mjs
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* eslint @typescript-eslint/no-explicit-any: ["off"] */
|
||||
import { AsyncLocalStorage, AsyncResource } from 'node:async_hooks';
|
||||
import { HookError, ValidationError } from './errors.mjs';
|
||||
const hookStorage = new AsyncLocalStorage();
|
||||
function createStore(rl) {
|
||||
const store = {
|
||||
rl,
|
||||
hooks: [],
|
||||
hooksCleanup: [],
|
||||
hooksEffect: [],
|
||||
index: 0,
|
||||
handleChange() { },
|
||||
};
|
||||
return store;
|
||||
}
|
||||
// Run callback in with the hook engine setup.
|
||||
export function withHooks(rl, cb) {
|
||||
const store = createStore(rl);
|
||||
return hookStorage.run(store, () => {
|
||||
function cycle(render) {
|
||||
store.handleChange = () => {
|
||||
store.index = 0;
|
||||
render();
|
||||
};
|
||||
store.handleChange();
|
||||
}
|
||||
return cb(cycle);
|
||||
});
|
||||
}
|
||||
// Safe getStore utility that'll return the store or throw if undefined.
|
||||
function getStore() {
|
||||
const store = hookStorage.getStore();
|
||||
if (!store) {
|
||||
throw new HookError('[Inquirer] Hook functions can only be called from within a prompt');
|
||||
}
|
||||
return store;
|
||||
}
|
||||
export function readline() {
|
||||
return getStore().rl;
|
||||
}
|
||||
// Merge state updates happening within the callback function to avoid multiple renders.
|
||||
export function withUpdates(fn) {
|
||||
const wrapped = (...args) => {
|
||||
const store = getStore();
|
||||
let shouldUpdate = false;
|
||||
const oldHandleChange = store.handleChange;
|
||||
store.handleChange = () => {
|
||||
shouldUpdate = true;
|
||||
};
|
||||
const returnValue = fn(...args);
|
||||
if (shouldUpdate) {
|
||||
oldHandleChange();
|
||||
}
|
||||
store.handleChange = oldHandleChange;
|
||||
return returnValue;
|
||||
};
|
||||
return AsyncResource.bind(wrapped);
|
||||
}
|
||||
export function withPointer(cb) {
|
||||
const store = getStore();
|
||||
const { index } = store;
|
||||
const pointer = {
|
||||
get() {
|
||||
return store.hooks[index];
|
||||
},
|
||||
set(value) {
|
||||
store.hooks[index] = value;
|
||||
},
|
||||
initialized: index in store.hooks,
|
||||
};
|
||||
const returnValue = cb(pointer);
|
||||
store.index++;
|
||||
return returnValue;
|
||||
}
|
||||
export function handleChange() {
|
||||
getStore().handleChange();
|
||||
}
|
||||
export const effectScheduler = {
|
||||
queue(cb) {
|
||||
const store = getStore();
|
||||
const { index } = store;
|
||||
store.hooksEffect.push(() => {
|
||||
store.hooksCleanup[index]?.();
|
||||
const cleanFn = cb(readline());
|
||||
if (cleanFn != null && typeof cleanFn !== 'function') {
|
||||
throw new ValidationError('useEffect return value must be a cleanup function or nothing.');
|
||||
}
|
||||
store.hooksCleanup[index] = cleanFn;
|
||||
});
|
||||
},
|
||||
run() {
|
||||
const store = getStore();
|
||||
withUpdates(() => {
|
||||
store.hooksEffect.forEach((effect) => {
|
||||
effect();
|
||||
});
|
||||
// Warning: Clean the hooks before exiting the `withUpdates` block.
|
||||
// Failure to do so means an updates would hit the same effects again.
|
||||
store.hooksEffect.length = 0;
|
||||
})();
|
||||
},
|
||||
clearAll() {
|
||||
const store = getStore();
|
||||
store.hooksCleanup.forEach((cleanFn) => {
|
||||
cleanFn?.();
|
||||
});
|
||||
store.hooksEffect.length = 0;
|
||||
store.hooksCleanup.length = 0;
|
||||
},
|
||||
};
|
18
node_modules/@inquirer/core/dist/esm/lib/key.mjs
generated
vendored
Normal file
18
node_modules/@inquirer/core/dist/esm/lib/key.mjs
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
export const isUpKey = (key) =>
|
||||
// The up key
|
||||
key.name === 'up' ||
|
||||
// Vim keybinding
|
||||
key.name === 'k' ||
|
||||
// Emacs keybinding
|
||||
(key.ctrl && key.name === 'p');
|
||||
export const isDownKey = (key) =>
|
||||
// The down key
|
||||
key.name === 'down' ||
|
||||
// Vim keybinding
|
||||
key.name === 'j' ||
|
||||
// Emacs keybinding
|
||||
(key.ctrl && key.name === 'n');
|
||||
export const isSpaceKey = (key) => key.name === 'space';
|
||||
export const isBackspaceKey = (key) => key.name === 'backspace';
|
||||
export const isNumberKey = (key) => '123456789'.includes(key.name);
|
||||
export const isEnterKey = (key) => key.name === 'enter' || key.name === 'return';
|
30
node_modules/@inquirer/core/dist/esm/lib/make-theme.mjs
generated
vendored
Normal file
30
node_modules/@inquirer/core/dist/esm/lib/make-theme.mjs
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { defaultTheme } from './theme.mjs';
|
||||
function isPlainObject(value) {
|
||||
if (typeof value !== 'object' || value === null)
|
||||
return false;
|
||||
let proto = value;
|
||||
while (Object.getPrototypeOf(proto) !== null) {
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
return Object.getPrototypeOf(value) === proto;
|
||||
}
|
||||
function deepMerge(...objects) {
|
||||
const output = {};
|
||||
for (const obj of objects) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
const prevValue = output[key];
|
||||
output[key] =
|
||||
isPlainObject(prevValue) && isPlainObject(value)
|
||||
? deepMerge(prevValue, value)
|
||||
: value;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
export function makeTheme(...themes) {
|
||||
const themesToMerge = [
|
||||
defaultTheme,
|
||||
...themes.filter((theme) => theme != null),
|
||||
];
|
||||
return deepMerge(...themesToMerge);
|
||||
}
|
59
node_modules/@inquirer/core/dist/esm/lib/pagination/lines.mjs
generated
vendored
Normal file
59
node_modules/@inquirer/core/dist/esm/lib/pagination/lines.mjs
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
import { breakLines } from '../utils.mjs';
|
||||
function split(content, width) {
|
||||
return breakLines(content, width).split('\n');
|
||||
}
|
||||
/**
|
||||
* Rotates an array of items by an integer number of positions.
|
||||
* @param {number} count The number of positions to rotate by
|
||||
* @param {T[]} items The items to rotate
|
||||
*/
|
||||
function rotate(count, items) {
|
||||
const max = items.length;
|
||||
const offset = ((count % max) + max) % max;
|
||||
return [...items.slice(offset), ...items.slice(0, offset)];
|
||||
}
|
||||
/**
|
||||
* Renders a page of items as lines that fit within the given width ensuring
|
||||
* that the number of lines is not greater than the page size, and the active
|
||||
* item renders at the provided position, while prioritizing that as many lines
|
||||
* of the active item get rendered as possible.
|
||||
*/
|
||||
export function lines({ items, width, renderItem, active, position: requested, pageSize, }) {
|
||||
const layouts = items.map((item, index) => ({
|
||||
item,
|
||||
index,
|
||||
isActive: index === active,
|
||||
}));
|
||||
const layoutsInPage = rotate(active - requested, layouts).slice(0, pageSize);
|
||||
const renderItemAt = (index) => layoutsInPage[index] == null ? [] : split(renderItem(layoutsInPage[index]), width);
|
||||
// Create a blank array of lines for the page
|
||||
const pageBuffer = Array.from({ length: pageSize });
|
||||
// Render the active item to decide the position
|
||||
const activeItem = renderItemAt(requested).slice(0, pageSize);
|
||||
const position = requested + activeItem.length <= pageSize ? requested : pageSize - activeItem.length;
|
||||
// Add the lines of the active item into the page
|
||||
pageBuffer.splice(position, activeItem.length, ...activeItem);
|
||||
// Fill the page under the active item
|
||||
let bufferPointer = position + activeItem.length;
|
||||
let layoutPointer = requested + 1;
|
||||
while (bufferPointer < pageSize && layoutPointer < layoutsInPage.length) {
|
||||
for (const line of renderItemAt(layoutPointer)) {
|
||||
pageBuffer[bufferPointer++] = line;
|
||||
if (bufferPointer >= pageSize)
|
||||
break;
|
||||
}
|
||||
layoutPointer++;
|
||||
}
|
||||
// Fill the page over the active item
|
||||
bufferPointer = position - 1;
|
||||
layoutPointer = requested - 1;
|
||||
while (bufferPointer >= 0 && layoutPointer >= 0) {
|
||||
for (const line of renderItemAt(layoutPointer).reverse()) {
|
||||
pageBuffer[bufferPointer--] = line;
|
||||
if (bufferPointer < 0)
|
||||
break;
|
||||
}
|
||||
layoutPointer--;
|
||||
}
|
||||
return pageBuffer.filter((line) => typeof line === 'string');
|
||||
}
|
27
node_modules/@inquirer/core/dist/esm/lib/pagination/position.mjs
generated
vendored
Normal file
27
node_modules/@inquirer/core/dist/esm/lib/pagination/position.mjs
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Creates the next position for the active item considering a finite list of
|
||||
* items to be rendered on a page.
|
||||
*/
|
||||
export function finite({ active, pageSize, total, }) {
|
||||
const middle = Math.floor(pageSize / 2);
|
||||
if (total <= pageSize || active < middle)
|
||||
return active;
|
||||
if (active >= total - middle)
|
||||
return active + pageSize - total;
|
||||
return middle;
|
||||
}
|
||||
/**
|
||||
* Creates the next position for the active item considering an infinitely
|
||||
* looping list of items to be rendered on the page.
|
||||
*/
|
||||
export function infinite({ active, lastActive, total, pageSize, pointer, }) {
|
||||
if (total <= pageSize)
|
||||
return active;
|
||||
// Move the position only when the user moves down, and when the
|
||||
// navigation fits within a single page
|
||||
if (lastActive < active && active - lastActive < pageSize) {
|
||||
// Limit it to the middle of the list
|
||||
return Math.min(Math.floor(pageSize / 2), pointer + active - lastActive);
|
||||
}
|
||||
return pointer;
|
||||
}
|
30
node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.mjs
generated
vendored
Normal file
30
node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.mjs
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { useRef } from '../use-ref.mjs';
|
||||
import { readlineWidth } from '../utils.mjs';
|
||||
import { lines } from './lines.mjs';
|
||||
import { finite, infinite } from './position.mjs';
|
||||
export function usePagination({ items, active, renderItem, pageSize, loop = true, }) {
|
||||
const state = useRef({ position: 0, lastActive: 0 });
|
||||
const position = loop
|
||||
? infinite({
|
||||
active,
|
||||
lastActive: state.current.lastActive,
|
||||
total: items.length,
|
||||
pageSize,
|
||||
pointer: state.current.position,
|
||||
})
|
||||
: finite({
|
||||
active,
|
||||
total: items.length,
|
||||
pageSize,
|
||||
});
|
||||
state.current.position = position;
|
||||
state.current.lastActive = active;
|
||||
return lines({
|
||||
items,
|
||||
width: readlineWidth(),
|
||||
renderItem,
|
||||
active,
|
||||
position,
|
||||
pageSize,
|
||||
}).join('\n');
|
||||
}
|
14
node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.mjs
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.mjs
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// TODO: Remove this class once Node 22 becomes the minimum supported version.
|
||||
export class PromisePolyfill extends Promise {
|
||||
// Available starting from Node 22
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
||||
static withResolver() {
|
||||
let resolve;
|
||||
let reject;
|
||||
const promise = new Promise((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
return { promise, resolve: resolve, reject: reject };
|
||||
}
|
||||
}
|
85
node_modules/@inquirer/core/dist/esm/lib/screen-manager.mjs
generated
vendored
Normal file
85
node_modules/@inquirer/core/dist/esm/lib/screen-manager.mjs
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
import stripAnsi from 'strip-ansi';
|
||||
import ansiEscapes from 'ansi-escapes';
|
||||
import { breakLines, readlineWidth } from './utils.mjs';
|
||||
const height = (content) => content.split('\n').length;
|
||||
const lastLine = (content) => content.split('\n').pop() ?? '';
|
||||
function cursorDown(n) {
|
||||
return n > 0 ? ansiEscapes.cursorDown(n) : '';
|
||||
}
|
||||
export default class ScreenManager {
|
||||
rl;
|
||||
// These variables are keeping information to allow correct prompt re-rendering
|
||||
height = 0;
|
||||
extraLinesUnderPrompt = 0;
|
||||
cursorPos;
|
||||
constructor(rl) {
|
||||
this.rl = rl;
|
||||
this.rl = rl;
|
||||
this.cursorPos = rl.getCursorPos();
|
||||
}
|
||||
write(content) {
|
||||
this.rl.output.unmute();
|
||||
this.rl.output.write(content);
|
||||
this.rl.output.mute();
|
||||
}
|
||||
render(content, bottomContent = '') {
|
||||
// Write message to screen and setPrompt to control backspace
|
||||
const promptLine = lastLine(content);
|
||||
const rawPromptLine = stripAnsi(promptLine);
|
||||
// Remove the rl.line from our prompt. We can't rely on the content of
|
||||
// rl.line (mainly because of the password prompt), so just rely on it's
|
||||
// length.
|
||||
let prompt = rawPromptLine;
|
||||
if (this.rl.line.length > 0) {
|
||||
prompt = prompt.slice(0, -this.rl.line.length);
|
||||
}
|
||||
this.rl.setPrompt(prompt);
|
||||
// SetPrompt will change cursor position, now we can get correct value
|
||||
this.cursorPos = this.rl.getCursorPos();
|
||||
const width = readlineWidth();
|
||||
content = breakLines(content, width);
|
||||
bottomContent = breakLines(bottomContent, width);
|
||||
// Manually insert an extra line if we're at the end of the line.
|
||||
// This prevent the cursor from appearing at the beginning of the
|
||||
// current line.
|
||||
if (rawPromptLine.length % width === 0) {
|
||||
content += '\n';
|
||||
}
|
||||
let output = content + (bottomContent ? '\n' + bottomContent : '');
|
||||
/**
|
||||
* Re-adjust the cursor at the correct position.
|
||||
*/
|
||||
// We need to consider parts of the prompt under the cursor as part of the bottom
|
||||
// content in order to correctly cleanup and re-render.
|
||||
const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
|
||||
const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
|
||||
// Return cursor to the input position (on top of the bottomContent)
|
||||
if (bottomContentHeight > 0)
|
||||
output += ansiEscapes.cursorUp(bottomContentHeight);
|
||||
// Return cursor to the initial left offset.
|
||||
output += ansiEscapes.cursorTo(this.cursorPos.cols);
|
||||
/**
|
||||
* Render and store state for future re-rendering
|
||||
*/
|
||||
this.write(cursorDown(this.extraLinesUnderPrompt) +
|
||||
ansiEscapes.eraseLines(this.height) +
|
||||
output);
|
||||
this.extraLinesUnderPrompt = bottomContentHeight;
|
||||
this.height = height(output);
|
||||
}
|
||||
checkCursorPos() {
|
||||
const cursorPos = this.rl.getCursorPos();
|
||||
if (cursorPos.cols !== this.cursorPos.cols) {
|
||||
this.write(ansiEscapes.cursorTo(cursorPos.cols));
|
||||
this.cursorPos = cursorPos;
|
||||
}
|
||||
}
|
||||
done({ clearContent }) {
|
||||
this.rl.setPrompt('');
|
||||
let output = cursorDown(this.extraLinesUnderPrompt);
|
||||
output += clearContent ? ansiEscapes.eraseLines(this.height) : '\n';
|
||||
output += ansiEscapes.cursorShow;
|
||||
this.write(output);
|
||||
this.rl.close();
|
||||
}
|
||||
}
|
22
node_modules/@inquirer/core/dist/esm/lib/theme.mjs
generated
vendored
Normal file
22
node_modules/@inquirer/core/dist/esm/lib/theme.mjs
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
import colors from 'yoctocolors-cjs';
|
||||
import figures from '@inquirer/figures';
|
||||
export const defaultTheme = {
|
||||
prefix: {
|
||||
idle: colors.blue('?'),
|
||||
// TODO: use figure
|
||||
done: colors.green(figures.tick),
|
||||
},
|
||||
spinner: {
|
||||
interval: 80,
|
||||
frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'].map((frame) => colors.yellow(frame)),
|
||||
},
|
||||
style: {
|
||||
answer: colors.cyan,
|
||||
message: colors.bold,
|
||||
error: (text) => colors.red(`> ${text}`),
|
||||
defaultAnswer: (text) => colors.dim(`(${text})`),
|
||||
help: colors.dim,
|
||||
highlight: colors.cyan,
|
||||
key: (text) => colors.cyan(colors.bold(`<${text}>`)),
|
||||
},
|
||||
};
|
11
node_modules/@inquirer/core/dist/esm/lib/use-effect.mjs
generated
vendored
Normal file
11
node_modules/@inquirer/core/dist/esm/lib/use-effect.mjs
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { withPointer, effectScheduler } from './hook-engine.mjs';
|
||||
export function useEffect(cb, depArray) {
|
||||
withPointer((pointer) => {
|
||||
const oldDeps = pointer.get();
|
||||
const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
|
||||
if (hasChanged) {
|
||||
effectScheduler.queue(cb);
|
||||
}
|
||||
pointer.set(depArray);
|
||||
});
|
||||
}
|
20
node_modules/@inquirer/core/dist/esm/lib/use-keypress.mjs
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/esm/lib/use-keypress.mjs
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { useRef } from './use-ref.mjs';
|
||||
import { useEffect } from './use-effect.mjs';
|
||||
import { withUpdates } from './hook-engine.mjs';
|
||||
export function useKeypress(userHandler) {
|
||||
const signal = useRef(userHandler);
|
||||
signal.current = userHandler;
|
||||
useEffect((rl) => {
|
||||
let ignore = false;
|
||||
const handler = withUpdates((_input, event) => {
|
||||
if (ignore)
|
||||
return;
|
||||
void signal.current(event, rl);
|
||||
});
|
||||
rl.input.on('keypress', handler);
|
||||
return () => {
|
||||
ignore = true;
|
||||
rl.input.removeListener('keypress', handler);
|
||||
};
|
||||
}, []);
|
||||
}
|
14
node_modules/@inquirer/core/dist/esm/lib/use-memo.mjs
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/esm/lib/use-memo.mjs
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { withPointer } from './hook-engine.mjs';
|
||||
export function useMemo(fn, dependencies) {
|
||||
return withPointer((pointer) => {
|
||||
const prev = pointer.get();
|
||||
if (!prev ||
|
||||
prev.dependencies.length !== dependencies.length ||
|
||||
prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
|
||||
const value = fn();
|
||||
pointer.set({ value, dependencies });
|
||||
return value;
|
||||
}
|
||||
return prev.value;
|
||||
});
|
||||
}
|
36
node_modules/@inquirer/core/dist/esm/lib/use-prefix.mjs
generated
vendored
Normal file
36
node_modules/@inquirer/core/dist/esm/lib/use-prefix.mjs
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { AsyncResource } from 'node:async_hooks';
|
||||
import { useState } from './use-state.mjs';
|
||||
import { useEffect } from './use-effect.mjs';
|
||||
import { makeTheme } from './make-theme.mjs';
|
||||
export function usePrefix({ status = 'idle', theme, }) {
|
||||
const [showLoader, setShowLoader] = useState(false);
|
||||
const [tick, setTick] = useState(0);
|
||||
const { prefix, spinner } = makeTheme(theme);
|
||||
useEffect(() => {
|
||||
if (status === 'loading') {
|
||||
let tickInterval;
|
||||
let inc = -1;
|
||||
// Delay displaying spinner by 300ms, to avoid flickering
|
||||
const delayTimeout = setTimeout(AsyncResource.bind(() => {
|
||||
setShowLoader(true);
|
||||
tickInterval = setInterval(AsyncResource.bind(() => {
|
||||
inc = inc + 1;
|
||||
setTick(inc % spinner.frames.length);
|
||||
}), spinner.interval);
|
||||
}), 300);
|
||||
return () => {
|
||||
clearTimeout(delayTimeout);
|
||||
clearInterval(tickInterval);
|
||||
};
|
||||
}
|
||||
else {
|
||||
setShowLoader(false);
|
||||
}
|
||||
}, [status]);
|
||||
if (showLoader) {
|
||||
return spinner.frames[tick];
|
||||
}
|
||||
// There's a delay before we show the loader. So we want to ignore `loading` here, and pass idle instead.
|
||||
const iconName = status === 'loading' ? 'idle' : status;
|
||||
return typeof prefix === 'string' ? prefix : prefix[iconName];
|
||||
}
|
4
node_modules/@inquirer/core/dist/esm/lib/use-ref.mjs
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/esm/lib/use-ref.mjs
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { useState } from './use-state.mjs';
|
||||
export function useRef(val) {
|
||||
return useState({ current: val })[0];
|
||||
}
|
19
node_modules/@inquirer/core/dist/esm/lib/use-state.mjs
generated
vendored
Normal file
19
node_modules/@inquirer/core/dist/esm/lib/use-state.mjs
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { withPointer, handleChange } from './hook-engine.mjs';
|
||||
export function useState(defaultValue) {
|
||||
return withPointer((pointer) => {
|
||||
const setFn = (newValue) => {
|
||||
// Noop if the value is still the same.
|
||||
if (pointer.get() !== newValue) {
|
||||
pointer.set(newValue);
|
||||
// Trigger re-render
|
||||
handleChange();
|
||||
}
|
||||
};
|
||||
if (pointer.initialized) {
|
||||
return [pointer.get(), setFn];
|
||||
}
|
||||
const value = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
||||
pointer.set(value);
|
||||
return [value, setFn];
|
||||
});
|
||||
}
|
25
node_modules/@inquirer/core/dist/esm/lib/utils.mjs
generated
vendored
Normal file
25
node_modules/@inquirer/core/dist/esm/lib/utils.mjs
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
import cliWidth from 'cli-width';
|
||||
import wrapAnsi from 'wrap-ansi';
|
||||
import { readline } from './hook-engine.mjs';
|
||||
/**
|
||||
* Force line returns at specific width. This function is ANSI code friendly and it'll
|
||||
* ignore invisible codes during width calculation.
|
||||
* @param {string} content
|
||||
* @param {number} width
|
||||
* @return {string}
|
||||
*/
|
||||
export function breakLines(content, width) {
|
||||
return content
|
||||
.split('\n')
|
||||
.flatMap((line) => wrapAnsi(line, width, { trim: false, hard: true })
|
||||
.split('\n')
|
||||
.map((str) => str.trimEnd()))
|
||||
.join('\n');
|
||||
}
|
||||
/**
|
||||
* Returns the width of the active readline, or 80 as default value.
|
||||
* @returns {number}
|
||||
*/
|
||||
export function readlineWidth() {
|
||||
return cliWidth({ defaultWidth: 80, output: readline().output });
|
||||
}
|
13
node_modules/@inquirer/core/dist/esm/types/index.d.mts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/esm/types/index.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
export * from './lib/key.mjs';
|
||||
export * from './lib/errors.mjs';
|
||||
export { usePrefix } from './lib/use-prefix.mjs';
|
||||
export { useState } from './lib/use-state.mjs';
|
||||
export { useEffect } from './lib/use-effect.mjs';
|
||||
export { useMemo } from './lib/use-memo.mjs';
|
||||
export { useRef } from './lib/use-ref.mjs';
|
||||
export { useKeypress } from './lib/use-keypress.mjs';
|
||||
export { makeTheme } from './lib/make-theme.mjs';
|
||||
export type { Theme, Status } from './lib/theme.mjs';
|
||||
export { usePagination } from './lib/pagination/use-pagination.mjs';
|
||||
export { createPrompt } from './lib/create-prompt.mjs';
|
||||
export { Separator } from './lib/Separator.mjs';
|
10
node_modules/@inquirer/core/dist/esm/types/lib/Separator.d.mts
generated
vendored
Normal file
10
node_modules/@inquirer/core/dist/esm/types/lib/Separator.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* Separator object
|
||||
* Used to space/separate choices group
|
||||
*/
|
||||
export declare class Separator {
|
||||
readonly separator: string;
|
||||
readonly type = "separator";
|
||||
constructor(separator?: string);
|
||||
static isSeparator(choice: unknown): choice is Separator;
|
||||
}
|
4
node_modules/@inquirer/core/dist/esm/types/lib/create-prompt.d.mts
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/esm/types/lib/create-prompt.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { type Prompt, type Prettify } from '@inquirer/type';
|
||||
type ViewFunction<Value, Config> = (config: Prettify<Config>, done: (value: Value) => void) => string | [string, string | undefined];
|
||||
export declare function createPrompt<Value, Config>(view: ViewFunction<Value, Config>): Prompt<Value, Config>;
|
||||
export {};
|
20
node_modules/@inquirer/core/dist/esm/types/lib/errors.d.mts
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/esm/types/lib/errors.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
export declare class AbortPromptError extends Error {
|
||||
name: string;
|
||||
message: string;
|
||||
constructor(options?: {
|
||||
cause?: unknown;
|
||||
});
|
||||
}
|
||||
export declare class CancelPromptError extends Error {
|
||||
name: string;
|
||||
message: string;
|
||||
}
|
||||
export declare class ExitPromptError extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class HookError extends Error {
|
||||
name: string;
|
||||
}
|
||||
export declare class ValidationError extends Error {
|
||||
name: string;
|
||||
}
|
23
node_modules/@inquirer/core/dist/esm/types/lib/hook-engine.d.mts
generated
vendored
Normal file
23
node_modules/@inquirer/core/dist/esm/types/lib/hook-engine.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
import type { InquirerReadline } from '@inquirer/type';
|
||||
export declare function withHooks<T>(rl: InquirerReadline, cb: (cycle: (render: () => void) => void) => T): T;
|
||||
export declare function readline(): InquirerReadline;
|
||||
export declare function withUpdates<R, T extends (...args: any[]) => R>(fn: T): (...args: Parameters<T>) => R;
|
||||
type SetPointer<Value> = {
|
||||
get(): Value;
|
||||
set(value: Value): void;
|
||||
initialized: true;
|
||||
};
|
||||
type UnsetPointer<Value> = {
|
||||
get(): void;
|
||||
set(value: Value): void;
|
||||
initialized: false;
|
||||
};
|
||||
type Pointer<Value> = SetPointer<Value> | UnsetPointer<Value>;
|
||||
export declare function withPointer<Value, ReturnValue>(cb: (pointer: Pointer<Value>) => ReturnValue): ReturnValue;
|
||||
export declare function handleChange(): void;
|
||||
export declare const effectScheduler: {
|
||||
queue(cb: (readline: InquirerReadline) => void): void;
|
||||
run(): void;
|
||||
clearAll(): void;
|
||||
};
|
||||
export {};
|
10
node_modules/@inquirer/core/dist/esm/types/lib/key.d.mts
generated
vendored
Normal file
10
node_modules/@inquirer/core/dist/esm/types/lib/key.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
export type KeypressEvent = {
|
||||
name: string;
|
||||
ctrl: boolean;
|
||||
};
|
||||
export declare const isUpKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isDownKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isSpaceKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isBackspaceKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isNumberKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isEnterKey: (key: KeypressEvent) => boolean;
|
3
node_modules/@inquirer/core/dist/esm/types/lib/make-theme.d.mts
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/esm/types/lib/make-theme.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
import type { Prettify, PartialDeep } from '@inquirer/type';
|
||||
import { type Theme } from './theme.mjs';
|
||||
export declare function makeTheme<SpecificTheme extends object>(...themes: ReadonlyArray<undefined | PartialDeep<Theme<SpecificTheme>>>): Prettify<Theme<SpecificTheme>>;
|
26
node_modules/@inquirer/core/dist/esm/types/lib/pagination/lines.d.mts
generated
vendored
Normal file
26
node_modules/@inquirer/core/dist/esm/types/lib/pagination/lines.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { type Prettify } from '@inquirer/type';
|
||||
/** Represents an item that's part of a layout, about to be rendered */
|
||||
export type Layout<T> = {
|
||||
item: T;
|
||||
index: number;
|
||||
isActive: boolean;
|
||||
};
|
||||
/**
|
||||
* Renders a page of items as lines that fit within the given width ensuring
|
||||
* that the number of lines is not greater than the page size, and the active
|
||||
* item renders at the provided position, while prioritizing that as many lines
|
||||
* of the active item get rendered as possible.
|
||||
*/
|
||||
export declare function lines<T>({ items, width, renderItem, active, position: requested, pageSize, }: {
|
||||
items: ReadonlyArray<T>;
|
||||
/** The width of a rendered line in characters. */
|
||||
width: number;
|
||||
/** Renders an item as part of a page. */
|
||||
renderItem: (layout: Prettify<Layout<T>>) => string;
|
||||
/** The index of the active item in the list of items. */
|
||||
active: number;
|
||||
/** The position on the page at which to render the active item. */
|
||||
position: number;
|
||||
/** The number of lines to render per page. */
|
||||
pageSize: number;
|
||||
}): string[];
|
20
node_modules/@inquirer/core/dist/esm/types/lib/pagination/position.d.mts
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/esm/types/lib/pagination/position.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Creates the next position for the active item considering a finite list of
|
||||
* items to be rendered on a page.
|
||||
*/
|
||||
export declare function finite({ active, pageSize, total, }: {
|
||||
active: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
}): number;
|
||||
/**
|
||||
* Creates the next position for the active item considering an infinitely
|
||||
* looping list of items to be rendered on the page.
|
||||
*/
|
||||
export declare function infinite({ active, lastActive, total, pageSize, pointer, }: {
|
||||
active: number;
|
||||
lastActive: number;
|
||||
total: number;
|
||||
pageSize: number;
|
||||
pointer: number;
|
||||
}): number;
|
15
node_modules/@inquirer/core/dist/esm/types/lib/pagination/use-pagination.d.mts
generated
vendored
Normal file
15
node_modules/@inquirer/core/dist/esm/types/lib/pagination/use-pagination.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
import type { Prettify } from '@inquirer/type';
|
||||
import { type Theme } from '../theme.mjs';
|
||||
import { type Layout } from './lines.mjs';
|
||||
export declare function usePagination<T>({ items, active, renderItem, pageSize, loop, }: {
|
||||
items: ReadonlyArray<T>;
|
||||
/** The index of the active item. */
|
||||
active: number;
|
||||
/** Renders an item as part of a page. */
|
||||
renderItem: (layout: Prettify<Layout<T>>) => string;
|
||||
/** The size of the page. */
|
||||
pageSize: number;
|
||||
/** Allows creating an infinitely looping list. `true` if unspecified. */
|
||||
loop?: boolean;
|
||||
theme?: Theme;
|
||||
}): string;
|
7
node_modules/@inquirer/core/dist/esm/types/lib/promise-polyfill.d.mts
generated
vendored
Normal file
7
node_modules/@inquirer/core/dist/esm/types/lib/promise-polyfill.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
export declare class PromisePolyfill<T> extends Promise<T> {
|
||||
static withResolver<T>(): {
|
||||
promise: Promise<T>;
|
||||
resolve: (value: T) => void;
|
||||
reject: (error: unknown) => void;
|
||||
};
|
||||
}
|
14
node_modules/@inquirer/core/dist/esm/types/lib/screen-manager.d.mts
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/esm/types/lib/screen-manager.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
import type { InquirerReadline } from '@inquirer/type';
|
||||
export default class ScreenManager {
|
||||
private readonly rl;
|
||||
private height;
|
||||
private extraLinesUnderPrompt;
|
||||
private cursorPos;
|
||||
constructor(rl: InquirerReadline);
|
||||
write(content: string): void;
|
||||
render(content: string, bottomContent?: string): void;
|
||||
checkCursorPos(): void;
|
||||
done({ clearContent }: {
|
||||
clearContent: boolean;
|
||||
}): void;
|
||||
}
|
154
node_modules/@inquirer/core/dist/esm/types/lib/theme.d.mts
generated
vendored
Normal file
154
node_modules/@inquirer/core/dist/esm/types/lib/theme.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
import type { Prettify } from '@inquirer/type';
|
||||
/**
|
||||
* Union type representing the possible statuses of a prompt.
|
||||
*
|
||||
* - `'loading'`: The prompt is currently loading.
|
||||
* - `'idle'`: The prompt is loaded and currently waiting for the user to
|
||||
* submit an answer.
|
||||
* - `'done'`: The user has submitted an answer and the prompt is finished.
|
||||
*/
|
||||
export type Status = 'loading' | 'idle' | 'done';
|
||||
type DefaultTheme = {
|
||||
/**
|
||||
* Prefix to prepend to the message. If a function is provided, it will be
|
||||
* called with the current status of the prompt, and the return value will be
|
||||
* used as the prefix.
|
||||
*
|
||||
* @remarks
|
||||
* If `status === 'loading'`, this property is ignored and the spinner (styled
|
||||
* by the `spinner` property) will be displayed instead.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (status) => status === 'done' ? colors.green('✔') : colors.blue('?')
|
||||
* ```
|
||||
*/
|
||||
prefix: string | Prettify<Omit<Record<Status, string>, 'loading'>>;
|
||||
/**
|
||||
* Configuration for the spinner that is displayed when the prompt is in the
|
||||
* `'loading'` state.
|
||||
*
|
||||
* We recommend the use of {@link https://github.com/sindresorhus/cli-spinners|cli-spinners} for a list of available spinners.
|
||||
*/
|
||||
spinner: {
|
||||
/**
|
||||
* The time interval between frames, in milliseconds.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* 80
|
||||
* ```
|
||||
*/
|
||||
interval: number;
|
||||
/**
|
||||
* A list of frames to show for the spinner.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
||||
* ```
|
||||
*/
|
||||
frames: string[];
|
||||
};
|
||||
/**
|
||||
* Object containing functions to style different parts of the prompt.
|
||||
*/
|
||||
style: {
|
||||
/**
|
||||
* Style to apply to the user's answer once it has been submitted.
|
||||
*
|
||||
* @param text - The user's answer.
|
||||
* @returns The styled answer.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.cyan(text)
|
||||
* ```
|
||||
*/
|
||||
answer: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to the message displayed to the user.
|
||||
*
|
||||
* @param text - The message to style.
|
||||
* @param status - The current status of the prompt.
|
||||
* @returns The styled message.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text, status) => colors.bold(text)
|
||||
* ```
|
||||
*/
|
||||
message: (text: string, status: Status) => string;
|
||||
/**
|
||||
* Style to apply to error messages.
|
||||
*
|
||||
* @param text - The error message.
|
||||
* @returns The styled error message.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.red(`> ${text}`)
|
||||
* ```
|
||||
*/
|
||||
error: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to the default answer when one is provided.
|
||||
*
|
||||
* @param text - The default answer.
|
||||
* @returns The styled default answer.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.dim(`(${text})`)
|
||||
* ```
|
||||
*/
|
||||
defaultAnswer: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to help text.
|
||||
*
|
||||
* @param text - The help text.
|
||||
* @returns The styled help text.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.dim(text)
|
||||
* ```
|
||||
*/
|
||||
help: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to highlighted text.
|
||||
*
|
||||
* @param text - The text to highlight.
|
||||
* @returns The highlighted text.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.cyan(text)
|
||||
* ```
|
||||
*/
|
||||
highlight: (text: string) => string;
|
||||
/**
|
||||
* Style to apply to keyboard keys referred to in help texts.
|
||||
*
|
||||
* @param text - The key to style.
|
||||
* @returns The styled key.
|
||||
*
|
||||
* @defaultValue
|
||||
* ```ts
|
||||
* // import colors from 'yoctocolors-cjs';
|
||||
* (text) => colors.cyan(colors.bold(`<${text}>`))
|
||||
* ```
|
||||
*/
|
||||
key: (text: string) => string;
|
||||
};
|
||||
};
|
||||
export type Theme<Extension extends object = object> = Prettify<Extension & DefaultTheme>;
|
||||
export declare const defaultTheme: DefaultTheme;
|
||||
export {};
|
2
node_modules/@inquirer/core/dist/esm/types/lib/use-effect.d.mts
generated
vendored
Normal file
2
node_modules/@inquirer/core/dist/esm/types/lib/use-effect.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
import type { InquirerReadline } from '@inquirer/type';
|
||||
export declare function useEffect(cb: (rl: InquirerReadline) => void | (() => void), depArray: ReadonlyArray<unknown>): void;
|
3
node_modules/@inquirer/core/dist/esm/types/lib/use-keypress.d.mts
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/esm/types/lib/use-keypress.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
import { type InquirerReadline } from '@inquirer/type';
|
||||
import { type KeypressEvent } from './key.mjs';
|
||||
export declare function useKeypress(userHandler: (event: KeypressEvent, rl: InquirerReadline) => void | Promise<void>): void;
|
1
node_modules/@inquirer/core/dist/esm/types/lib/use-memo.d.mts
generated
vendored
Normal file
1
node_modules/@inquirer/core/dist/esm/types/lib/use-memo.d.mts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export declare function useMemo<Value>(fn: () => Value, dependencies: ReadonlyArray<unknown>): Value;
|
5
node_modules/@inquirer/core/dist/esm/types/lib/use-prefix.d.mts
generated
vendored
Normal file
5
node_modules/@inquirer/core/dist/esm/types/lib/use-prefix.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import type { Theme, Status } from './theme.mjs';
|
||||
export declare function usePrefix({ status, theme, }: {
|
||||
status?: Status;
|
||||
theme?: Theme;
|
||||
}): string;
|
6
node_modules/@inquirer/core/dist/esm/types/lib/use-ref.d.mts
generated
vendored
Normal file
6
node_modules/@inquirer/core/dist/esm/types/lib/use-ref.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
export declare function useRef<Value>(val: Value): {
|
||||
current: Value;
|
||||
};
|
||||
export declare function useRef<Value>(val?: Value): {
|
||||
current: Value | undefined;
|
||||
};
|
4
node_modules/@inquirer/core/dist/esm/types/lib/use-state.d.mts
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/esm/types/lib/use-state.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
type NotFunction<T> = T extends (...args: never) => unknown ? never : T;
|
||||
export declare function useState<Value>(defaultValue: NotFunction<Value> | (() => Value)): [Value, (newValue: Value) => void];
|
||||
export declare function useState<Value>(defaultValue?: NotFunction<Value> | (() => Value)): [Value | undefined, (newValue?: Value) => void];
|
||||
export {};
|
13
node_modules/@inquirer/core/dist/esm/types/lib/utils.d.mts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/esm/types/lib/utils.d.mts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* Force line returns at specific width. This function is ANSI code friendly and it'll
|
||||
* ignore invisible codes during width calculation.
|
||||
* @param {string} content
|
||||
* @param {number} width
|
||||
* @return {string}
|
||||
*/
|
||||
export declare function breakLines(content: string, width: number): string;
|
||||
/**
|
||||
* Returns the width of the active readline, or 80 as default value.
|
||||
* @returns {number}
|
||||
*/
|
||||
export declare function readlineWidth(): number;
|
13
node_modules/@inquirer/core/dist/types/index.d.ts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/types/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
export * from './lib/key.js';
|
||||
export * from './lib/errors.js';
|
||||
export { usePrefix } from './lib/use-prefix.js';
|
||||
export { useState } from './lib/use-state.js';
|
||||
export { useEffect } from './lib/use-effect.js';
|
||||
export { useMemo } from './lib/use-memo.js';
|
||||
export { useRef } from './lib/use-ref.js';
|
||||
export { useKeypress } from './lib/use-keypress.js';
|
||||
export { makeTheme } from './lib/make-theme.js';
|
||||
export type { Theme } from './lib/theme.js';
|
||||
export { usePagination } from './lib/pagination/use-pagination.js';
|
||||
export { createPrompt } from './lib/create-prompt.js';
|
||||
export { Separator } from './lib/Separator.js';
|
10
node_modules/@inquirer/core/dist/types/lib/Separator.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/core/dist/types/lib/Separator.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* Separator object
|
||||
* Used to space/separate choices group
|
||||
*/
|
||||
export declare class Separator {
|
||||
readonly separator: string;
|
||||
readonly type = "separator";
|
||||
constructor(separator?: string);
|
||||
static isSeparator(choice: undefined | Separator | Record<string, unknown>): choice is Separator;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue