first commit
This commit is contained in:
13
node_modules/@inquirer/core/dist/commonjs/index.d.ts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/commonjs/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
export { isUpKey, isDownKey, isSpaceKey, isBackspaceKey, isTabKey, isNumberKey, isEnterKey, type KeypressEvent, type Keybinding, } from './lib/key.ts';
|
||||
export * from './lib/errors.ts';
|
||||
export { usePrefix } from './lib/use-prefix.ts';
|
||||
export { useState } from './lib/use-state.ts';
|
||||
export { useEffect } from './lib/use-effect.ts';
|
||||
export { useMemo } from './lib/use-memo.ts';
|
||||
export { useRef } from './lib/use-ref.ts';
|
||||
export { useKeypress } from './lib/use-keypress.ts';
|
||||
export { makeTheme } from './lib/make-theme.ts';
|
||||
export type { Theme, Status } from './lib/theme.ts';
|
||||
export { usePagination } from './lib/pagination/use-pagination.ts';
|
||||
export { createPrompt } from './lib/create-prompt.ts';
|
||||
export { Separator } from './lib/Separator.ts';
|
||||
46
node_modules/@inquirer/core/dist/commonjs/index.js
generated
vendored
Normal file
46
node_modules/@inquirer/core/dist/commonjs/index.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
"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 = exports.isEnterKey = exports.isNumberKey = exports.isTabKey = exports.isBackspaceKey = exports.isSpaceKey = exports.isDownKey = exports.isUpKey = void 0;
|
||||
var key_ts_1 = require("./lib/key.js");
|
||||
Object.defineProperty(exports, "isUpKey", { enumerable: true, get: function () { return key_ts_1.isUpKey; } });
|
||||
Object.defineProperty(exports, "isDownKey", { enumerable: true, get: function () { return key_ts_1.isDownKey; } });
|
||||
Object.defineProperty(exports, "isSpaceKey", { enumerable: true, get: function () { return key_ts_1.isSpaceKey; } });
|
||||
Object.defineProperty(exports, "isBackspaceKey", { enumerable: true, get: function () { return key_ts_1.isBackspaceKey; } });
|
||||
Object.defineProperty(exports, "isTabKey", { enumerable: true, get: function () { return key_ts_1.isTabKey; } });
|
||||
Object.defineProperty(exports, "isNumberKey", { enumerable: true, get: function () { return key_ts_1.isNumberKey; } });
|
||||
Object.defineProperty(exports, "isEnterKey", { enumerable: true, get: function () { return key_ts_1.isEnterKey; } });
|
||||
__exportStar(require("./lib/errors.js"), exports);
|
||||
var use_prefix_ts_1 = require("./lib/use-prefix.js");
|
||||
Object.defineProperty(exports, "usePrefix", { enumerable: true, get: function () { return use_prefix_ts_1.usePrefix; } });
|
||||
var use_state_ts_1 = require("./lib/use-state.js");
|
||||
Object.defineProperty(exports, "useState", { enumerable: true, get: function () { return use_state_ts_1.useState; } });
|
||||
var use_effect_ts_1 = require("./lib/use-effect.js");
|
||||
Object.defineProperty(exports, "useEffect", { enumerable: true, get: function () { return use_effect_ts_1.useEffect; } });
|
||||
var use_memo_ts_1 = require("./lib/use-memo.js");
|
||||
Object.defineProperty(exports, "useMemo", { enumerable: true, get: function () { return use_memo_ts_1.useMemo; } });
|
||||
var use_ref_ts_1 = require("./lib/use-ref.js");
|
||||
Object.defineProperty(exports, "useRef", { enumerable: true, get: function () { return use_ref_ts_1.useRef; } });
|
||||
var use_keypress_ts_1 = require("./lib/use-keypress.js");
|
||||
Object.defineProperty(exports, "useKeypress", { enumerable: true, get: function () { return use_keypress_ts_1.useKeypress; } });
|
||||
var make_theme_ts_1 = require("./lib/make-theme.js");
|
||||
Object.defineProperty(exports, "makeTheme", { enumerable: true, get: function () { return make_theme_ts_1.makeTheme; } });
|
||||
var use_pagination_ts_1 = require("./lib/pagination/use-pagination.js");
|
||||
Object.defineProperty(exports, "usePagination", { enumerable: true, get: function () { return use_pagination_ts_1.usePagination; } });
|
||||
var create_prompt_ts_1 = require("./lib/create-prompt.js");
|
||||
Object.defineProperty(exports, "createPrompt", { enumerable: true, get: function () { return create_prompt_ts_1.createPrompt; } });
|
||||
var Separator_ts_1 = require("./lib/Separator.js");
|
||||
Object.defineProperty(exports, "Separator", { enumerable: true, get: function () { return Separator_ts_1.Separator; } });
|
||||
10
node_modules/@inquirer/core/dist/commonjs/lib/Separator.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/core/dist/commonjs/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: string;
|
||||
constructor(separator?: string);
|
||||
static isSeparator(choice: unknown): choice is Separator;
|
||||
}
|
||||
28
node_modules/@inquirer/core/dist/commonjs/lib/Separator.js
generated
vendored
Normal file
28
node_modules/@inquirer/core/dist/commonjs/lib/Separator.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.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 {
|
||||
separator = yoctocolors_cjs_1.default.dim(Array.from({ length: 15 }).join(figures_1.default.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');
|
||||
}
|
||||
}
|
||||
exports.Separator = Separator;
|
||||
4
node_modules/@inquirer/core/dist/commonjs/lib/create-prompt.d.ts
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/commonjs/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 {};
|
||||
156
node_modules/@inquirer/core/dist/commonjs/lib/create-prompt.js
generated
vendored
Normal file
156
node_modules/@inquirer/core/dist/commonjs/lib/create-prompt.js
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
"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 () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__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_ts_1 = __importDefault(require("./screen-manager.js"));
|
||||
const promise_polyfill_ts_1 = require("./promise-polyfill.js");
|
||||
const hook_engine_ts_1 = require("./hook-engine.js");
|
||||
const errors_ts_1 = require("./errors.js");
|
||||
function getCallSites() {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const _prepareStackTrace = Error.prepareStackTrace;
|
||||
let result = [];
|
||||
try {
|
||||
Error.prepareStackTrace = (_, callSites) => {
|
||||
const callSitesWithoutCurrent = callSites.slice(1);
|
||||
result = callSitesWithoutCurrent;
|
||||
return callSitesWithoutCurrent;
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
new Error().stack;
|
||||
}
|
||||
catch {
|
||||
// An error will occur if the Node flag --frozen-intrinsics is used.
|
||||
// https://nodejs.org/api/cli.html#--frozen-intrinsics
|
||||
return result;
|
||||
}
|
||||
Error.prepareStackTrace = _prepareStackTrace;
|
||||
return result;
|
||||
}
|
||||
function createPrompt(view) {
|
||||
const callSites = getCallSites();
|
||||
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 mute_stream_1.default();
|
||||
output.pipe(context.output ?? process.stdout);
|
||||
const rl = readline.createInterface({
|
||||
terminal: true,
|
||||
input,
|
||||
output,
|
||||
});
|
||||
const screen = new screen_manager_ts_1.default(rl);
|
||||
const { promise, resolve, reject } = promise_polyfill_ts_1.PromisePolyfill.withResolver();
|
||||
const cancel = () => reject(new errors_ts_1.CancelPromptError());
|
||||
if (signal) {
|
||||
const abort = () => reject(new errors_ts_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_ts_1.ExitPromptError(`User force closed the prompt with ${code} ${signal}`));
|
||||
}));
|
||||
// SIGINT must be explicitly handled by the prompt so the ExitPromptError can be handled.
|
||||
// Otherwise, the prompt will stop and in some scenarios never resolve.
|
||||
// Ref issue #1741
|
||||
const sigint = () => reject(new errors_ts_1.ExitPromptError(`User force closed the prompt with SIGINT`));
|
||||
rl.on('SIGINT', sigint);
|
||||
cleanups.add(() => rl.removeListener('SIGINT', sigint));
|
||||
// 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_ts_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_ts_1.effectScheduler.clearAll());
|
||||
rl.on('close', hooksCleanup);
|
||||
cleanups.add(() => rl.removeListener('close', hooksCleanup));
|
||||
cycle(() => {
|
||||
try {
|
||||
const nextView = view(config, (value) => {
|
||||
setImmediate(() => resolve(value));
|
||||
});
|
||||
// Typescript won't allow this, but not all users rely on typescript.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (nextView === undefined) {
|
||||
const callerFilename = callSites[1]?.getFileName();
|
||||
throw new Error(`Prompt functions must return a string.\n at ${callerFilename}`);
|
||||
}
|
||||
const [content, bottomContent] = typeof nextView === 'string' ? [nextView] : nextView;
|
||||
screen.render(content, bottomContent);
|
||||
hook_engine_ts_1.effectScheduler.run();
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return Object.assign(promise
|
||||
.then((answer) => {
|
||||
hook_engine_ts_1.effectScheduler.clearAll();
|
||||
return answer;
|
||||
}, (error) => {
|
||||
hook_engine_ts_1.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;
|
||||
}
|
||||
20
node_modules/@inquirer/core/dist/commonjs/lib/errors.d.ts
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/commonjs/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;
|
||||
}
|
||||
29
node_modules/@inquirer/core/dist/commonjs/lib/errors.js
generated
vendored
Normal file
29
node_modules/@inquirer/core/dist/commonjs/lib/errors.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ValidationError = exports.HookError = exports.ExitPromptError = exports.CancelPromptError = exports.AbortPromptError = void 0;
|
||||
class AbortPromptError extends Error {
|
||||
name = 'AbortPromptError';
|
||||
message = 'Prompt was aborted';
|
||||
constructor(options) {
|
||||
super();
|
||||
this.cause = options?.cause;
|
||||
}
|
||||
}
|
||||
exports.AbortPromptError = AbortPromptError;
|
||||
class CancelPromptError extends Error {
|
||||
name = 'CancelPromptError';
|
||||
message = 'Prompt was canceled';
|
||||
}
|
||||
exports.CancelPromptError = CancelPromptError;
|
||||
class ExitPromptError extends Error {
|
||||
name = 'ExitPromptError';
|
||||
}
|
||||
exports.ExitPromptError = ExitPromptError;
|
||||
class HookError extends Error {
|
||||
name = 'HookError';
|
||||
}
|
||||
exports.HookError = HookError;
|
||||
class ValidationError extends Error {
|
||||
name = 'ValidationError';
|
||||
}
|
||||
exports.ValidationError = ValidationError;
|
||||
23
node_modules/@inquirer/core/dist/commonjs/lib/hook-engine.d.ts
generated
vendored
Normal file
23
node_modules/@inquirer/core/dist/commonjs/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<Args extends unknown[], R>(fn: (...args: Args) => R): (...args: Args) => 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)): void;
|
||||
run(): void;
|
||||
clearAll(): void;
|
||||
};
|
||||
export {};
|
||||
118
node_modules/@inquirer/core/dist/commonjs/lib/hook-engine.js
generated
vendored
Normal file
118
node_modules/@inquirer/core/dist/commonjs/lib/hook-engine.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
"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_ts_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_ts_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(() => {
|
||||
store.hooksCleanup[index]?.();
|
||||
const cleanFn = cb(readline());
|
||||
if (cleanFn != null && typeof cleanFn !== 'function') {
|
||||
throw new errors_ts_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?.();
|
||||
});
|
||||
store.hooksEffect.length = 0;
|
||||
store.hooksCleanup.length = 0;
|
||||
},
|
||||
};
|
||||
12
node_modules/@inquirer/core/dist/commonjs/lib/key.d.ts
generated
vendored
Normal file
12
node_modules/@inquirer/core/dist/commonjs/lib/key.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export type KeypressEvent = {
|
||||
name: string;
|
||||
ctrl: boolean;
|
||||
};
|
||||
export type Keybinding = 'emacs' | 'vim';
|
||||
export declare const isUpKey: (key: KeypressEvent, keybindings?: ReadonlyArray<Keybinding>) => boolean;
|
||||
export declare const isDownKey: (key: KeypressEvent, keybindings?: ReadonlyArray<Keybinding>) => boolean;
|
||||
export declare const isSpaceKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isBackspaceKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isTabKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isNumberKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isEnterKey: (key: KeypressEvent) => boolean;
|
||||
29
node_modules/@inquirer/core/dist/commonjs/lib/key.js
generated
vendored
Normal file
29
node_modules/@inquirer/core/dist/commonjs/lib/key.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isEnterKey = exports.isNumberKey = exports.isTabKey = exports.isBackspaceKey = exports.isSpaceKey = exports.isDownKey = exports.isUpKey = void 0;
|
||||
const isUpKey = (key, keybindings = []) =>
|
||||
// The up key
|
||||
key.name === 'up' ||
|
||||
// Vim keybinding: hjkl keys map to left/down/up/right
|
||||
(keybindings.includes('vim') && key.name === 'k') ||
|
||||
// Emacs keybinding: Ctrl+P means "previous" in Emacs navigation conventions
|
||||
(keybindings.includes('emacs') && key.ctrl && key.name === 'p');
|
||||
exports.isUpKey = isUpKey;
|
||||
const isDownKey = (key, keybindings = []) =>
|
||||
// The down key
|
||||
key.name === 'down' ||
|
||||
// Vim keybinding: hjkl keys map to left/down/up/right
|
||||
(keybindings.includes('vim') && key.name === 'j') ||
|
||||
// Emacs keybinding: Ctrl+N means "next" in Emacs navigation conventions
|
||||
(keybindings.includes('emacs') && 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 isTabKey = (key) => key.name === 'tab';
|
||||
exports.isTabKey = isTabKey;
|
||||
const isNumberKey = (key) => '1234567890'.includes(key.name);
|
||||
exports.isNumberKey = isNumberKey;
|
||||
const isEnterKey = (key) => key.name === 'enter' || key.name === 'return';
|
||||
exports.isEnterKey = isEnterKey;
|
||||
3
node_modules/@inquirer/core/dist/commonjs/lib/make-theme.d.ts
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/commonjs/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.ts';
|
||||
export declare function makeTheme<SpecificTheme extends object>(...themes: ReadonlyArray<undefined | PartialDeep<Theme<SpecificTheme>>>): Prettify<Theme<SpecificTheme>>;
|
||||
33
node_modules/@inquirer/core/dist/commonjs/lib/make-theme.js
generated
vendored
Normal file
33
node_modules/@inquirer/core/dist/commonjs/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_ts_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_ts_1.defaultTheme,
|
||||
...themes.filter((theme) => theme != null),
|
||||
];
|
||||
return deepMerge(...themesToMerge);
|
||||
}
|
||||
16
node_modules/@inquirer/core/dist/commonjs/lib/pagination/use-pagination.d.ts
generated
vendored
Normal file
16
node_modules/@inquirer/core/dist/commonjs/lib/pagination/use-pagination.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { Prettify } from '@inquirer/type';
|
||||
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<{
|
||||
item: T;
|
||||
index: number;
|
||||
isActive: boolean;
|
||||
}>) => string;
|
||||
/** The size of the page. */
|
||||
pageSize: number;
|
||||
/** Allows creating an infinitely looping list. `true` if unspecified. */
|
||||
loop?: boolean;
|
||||
}): string;
|
||||
124
node_modules/@inquirer/core/dist/commonjs/lib/pagination/use-pagination.js
generated
vendored
Normal file
124
node_modules/@inquirer/core/dist/commonjs/lib/pagination/use-pagination.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.usePagination = usePagination;
|
||||
const use_ref_ts_1 = require("../use-ref.js");
|
||||
const utils_ts_1 = require("../utils.js");
|
||||
function usePointerPosition({ active, renderedItems, pageSize, loop, }) {
|
||||
const state = (0, use_ref_ts_1.useRef)({
|
||||
lastPointer: active,
|
||||
lastActive: undefined,
|
||||
});
|
||||
const { lastPointer, lastActive } = state.current;
|
||||
const middle = Math.floor(pageSize / 2);
|
||||
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
||||
const defaultPointerPosition = renderedItems
|
||||
.slice(0, active)
|
||||
.reduce((acc, item) => acc + item.length, 0);
|
||||
let pointer = defaultPointerPosition;
|
||||
if (renderedLength > pageSize) {
|
||||
if (loop) {
|
||||
/**
|
||||
* Creates the next position for the pointer considering an infinitely
|
||||
* looping list of items to be rendered on the page.
|
||||
*
|
||||
* The goal is to progressively move the cursor to the middle position as the user move down, and then keep
|
||||
* the cursor there. When the user move up, maintain the cursor position.
|
||||
*/
|
||||
// By default, keep the cursor position as-is.
|
||||
pointer = lastPointer;
|
||||
if (
|
||||
// First render, skip this logic.
|
||||
lastActive != null &&
|
||||
// Only move the pointer down when the user moves down.
|
||||
lastActive < active &&
|
||||
// Check user didn't move up across page boundary.
|
||||
active - lastActive < pageSize) {
|
||||
pointer = Math.min(
|
||||
// Furthest allowed position for the pointer is the middle of the list
|
||||
middle, Math.abs(active - lastActive) === 1
|
||||
? Math.min(
|
||||
// Move the pointer at most the height of the last active item.
|
||||
lastPointer + (renderedItems[lastActive]?.length ?? 0),
|
||||
// If the user moved by one item, move the pointer to the natural position of the active item as
|
||||
// long as it doesn't move the cursor up.
|
||||
Math.max(defaultPointerPosition, lastPointer))
|
||||
: // Otherwise, move the pointer down by the difference between the active and last active item.
|
||||
lastPointer + active - lastActive);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* Creates the next position for the pointer considering a finite list of
|
||||
* items to be rendered on a page.
|
||||
*
|
||||
* The goal is to keep the pointer in the middle of the page whenever possible, until
|
||||
* we reach the bounds of the list (top or bottom). In which case, the cursor moves progressively
|
||||
* to the bottom or top of the list.
|
||||
*/
|
||||
const spaceUnderActive = renderedItems
|
||||
.slice(active)
|
||||
.reduce((acc, item) => acc + item.length, 0);
|
||||
pointer =
|
||||
spaceUnderActive < pageSize - middle
|
||||
? // If the active item is near the end of the list, progressively move the cursor towards the end.
|
||||
pageSize - spaceUnderActive
|
||||
: // Otherwise, progressively move the pointer to the middle of the list.
|
||||
Math.min(defaultPointerPosition, middle);
|
||||
}
|
||||
}
|
||||
// Save state for the next render
|
||||
state.current.lastPointer = pointer;
|
||||
state.current.lastActive = active;
|
||||
return pointer;
|
||||
}
|
||||
function usePagination({ items, active, renderItem, pageSize, loop = true, }) {
|
||||
const width = (0, utils_ts_1.readlineWidth)();
|
||||
const bound = (num) => ((num % items.length) + items.length) % items.length;
|
||||
const renderedItems = items.map((item, index) => {
|
||||
if (item == null)
|
||||
return [];
|
||||
return (0, utils_ts_1.breakLines)(renderItem({ item, index, isActive: index === active }), width).split('\n');
|
||||
});
|
||||
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
||||
const renderItemAtIndex = (index) => renderedItems[index] ?? [];
|
||||
const pointer = usePointerPosition({ active, renderedItems, pageSize, loop });
|
||||
// Render the active item to decide the position.
|
||||
// If the active item fits under the pointer, we render it there.
|
||||
// Otherwise, we need to render it to fit at the bottom of the page; moving the pointer up.
|
||||
const activeItem = renderItemAtIndex(active).slice(0, pageSize);
|
||||
const activeItemPosition = pointer + activeItem.length <= pageSize ? pointer : pageSize - activeItem.length;
|
||||
// Create an array of lines for the page, and add the lines of the active item into the page
|
||||
const pageBuffer = Array.from({ length: pageSize });
|
||||
pageBuffer.splice(activeItemPosition, activeItem.length, ...activeItem);
|
||||
// Store to prevent rendering the same item twice
|
||||
const itemVisited = new Set([active]);
|
||||
// Fill the page under the active item
|
||||
let bufferPointer = activeItemPosition + activeItem.length;
|
||||
let itemPointer = bound(active + 1);
|
||||
while (bufferPointer < pageSize &&
|
||||
!itemVisited.has(itemPointer) &&
|
||||
(loop && renderedLength > pageSize ? itemPointer !== active : itemPointer > active)) {
|
||||
const lines = renderItemAtIndex(itemPointer);
|
||||
const linesToAdd = lines.slice(0, pageSize - bufferPointer);
|
||||
pageBuffer.splice(bufferPointer, linesToAdd.length, ...linesToAdd);
|
||||
// Move pointers for next iteration
|
||||
itemVisited.add(itemPointer);
|
||||
bufferPointer += linesToAdd.length;
|
||||
itemPointer = bound(itemPointer + 1);
|
||||
}
|
||||
// Fill the page over the active item
|
||||
bufferPointer = activeItemPosition - 1;
|
||||
itemPointer = bound(active - 1);
|
||||
while (bufferPointer >= 0 &&
|
||||
!itemVisited.has(itemPointer) &&
|
||||
(loop && renderedLength > pageSize ? itemPointer !== active : itemPointer < active)) {
|
||||
const lines = renderItemAtIndex(itemPointer);
|
||||
const linesToAdd = lines.slice(Math.max(0, lines.length - bufferPointer - 1));
|
||||
pageBuffer.splice(bufferPointer - linesToAdd.length + 1, linesToAdd.length, ...linesToAdd);
|
||||
// Move pointers for next iteration
|
||||
itemVisited.add(itemPointer);
|
||||
bufferPointer -= linesToAdd.length;
|
||||
itemPointer = bound(itemPointer - 1);
|
||||
}
|
||||
return pageBuffer.filter((line) => typeof line === 'string').join('\n');
|
||||
}
|
||||
7
node_modules/@inquirer/core/dist/commonjs/lib/promise-polyfill.d.ts
generated
vendored
Normal file
7
node_modules/@inquirer/core/dist/commonjs/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;
|
||||
};
|
||||
}
|
||||
18
node_modules/@inquirer/core/dist/commonjs/lib/promise-polyfill.js
generated
vendored
Normal file
18
node_modules/@inquirer/core/dist/commonjs/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;
|
||||
14
node_modules/@inquirer/core/dist/commonjs/lib/screen-manager.d.ts
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/commonjs/lib/screen-manager.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { InquirerReadline } from '@inquirer/type';
|
||||
export default class ScreenManager {
|
||||
private height;
|
||||
private extraLinesUnderPrompt;
|
||||
private cursorPos;
|
||||
private readonly rl;
|
||||
constructor(rl: InquirerReadline);
|
||||
write(content: string): void;
|
||||
render(content: string, bottomContent?: string): void;
|
||||
checkCursorPos(): void;
|
||||
done({ clearContent }: {
|
||||
clearContent: boolean;
|
||||
}): void;
|
||||
}
|
||||
82
node_modules/@inquirer/core/dist/commonjs/lib/screen-manager.js
generated
vendored
Normal file
82
node_modules/@inquirer/core/dist/commonjs/lib/screen-manager.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const node_util_1 = require("node:util");
|
||||
const utils_ts_1 = require("./utils.js");
|
||||
const ansi_1 = require("@inquirer/ansi");
|
||||
const height = (content) => content.split('\n').length;
|
||||
const lastLine = (content) => content.split('\n').pop() ?? '';
|
||||
class ScreenManager {
|
||||
// These variables are keeping information to allow correct prompt re-rendering
|
||||
height = 0;
|
||||
extraLinesUnderPrompt = 0;
|
||||
cursorPos;
|
||||
rl;
|
||||
constructor(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 = (0, node_util_1.stripVTControlCharacters)(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_ts_1.readlineWidth)();
|
||||
content = (0, utils_ts_1.breakLines)(content, width);
|
||||
bottomContent = (0, utils_ts_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 += (0, ansi_1.cursorUp)(bottomContentHeight);
|
||||
// Return cursor to the initial left offset.
|
||||
output += (0, ansi_1.cursorTo)(this.cursorPos.cols);
|
||||
/**
|
||||
* Render and store state for future re-rendering
|
||||
*/
|
||||
this.write((0, ansi_1.cursorDown)(this.extraLinesUnderPrompt) + (0, ansi_1.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((0, ansi_1.cursorTo)(cursorPos.cols));
|
||||
this.cursorPos = cursorPos;
|
||||
}
|
||||
}
|
||||
done({ clearContent }) {
|
||||
this.rl.setPrompt('');
|
||||
let output = (0, ansi_1.cursorDown)(this.extraLinesUnderPrompt);
|
||||
output += clearContent ? (0, ansi_1.eraseLines)(this.height) : '\n';
|
||||
output += ansi_1.cursorShow;
|
||||
this.write(output);
|
||||
this.rl.close();
|
||||
}
|
||||
}
|
||||
exports.default = ScreenManager;
|
||||
155
node_modules/@inquirer/core/dist/commonjs/lib/theme.d.ts
generated
vendored
Normal file
155
node_modules/@inquirer/core/dist/commonjs/lib/theme.d.ts
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
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.
|
||||
* - `string`: Any other string: The prompt is in a custom state.
|
||||
*/
|
||||
export type Status = 'loading' | 'idle' | 'done' | (string & {});
|
||||
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 {};
|
||||
28
node_modules/@inquirer/core/dist/commonjs/lib/theme.js
generated
vendored
Normal file
28
node_modules/@inquirer/core/dist/commonjs/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}>`)),
|
||||
},
|
||||
};
|
||||
2
node_modules/@inquirer/core/dist/commonjs/lib/use-effect.d.ts
generated
vendored
Normal file
2
node_modules/@inquirer/core/dist/commonjs/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;
|
||||
14
node_modules/@inquirer/core/dist/commonjs/lib/use-effect.js
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/commonjs/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_ts_1 = require("./hook-engine.js");
|
||||
function useEffect(cb, depArray) {
|
||||
(0, hook_engine_ts_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_ts_1.effectScheduler.queue(cb);
|
||||
}
|
||||
pointer.set(depArray);
|
||||
});
|
||||
}
|
||||
3
node_modules/@inquirer/core/dist/commonjs/lib/use-keypress.d.ts
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/commonjs/lib/use-keypress.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { type InquirerReadline } from '@inquirer/type';
|
||||
import { type KeypressEvent } from './key.ts';
|
||||
export declare function useKeypress(userHandler: (event: KeypressEvent, rl: InquirerReadline) => void | Promise<void>): void;
|
||||
23
node_modules/@inquirer/core/dist/commonjs/lib/use-keypress.js
generated
vendored
Normal file
23
node_modules/@inquirer/core/dist/commonjs/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_ts_1 = require("./use-ref.js");
|
||||
const use_effect_ts_1 = require("./use-effect.js");
|
||||
const hook_engine_ts_1 = require("./hook-engine.js");
|
||||
function useKeypress(userHandler) {
|
||||
const signal = (0, use_ref_ts_1.useRef)(userHandler);
|
||||
signal.current = userHandler;
|
||||
(0, use_effect_ts_1.useEffect)((rl) => {
|
||||
let ignore = false;
|
||||
const handler = (0, hook_engine_ts_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);
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
1
node_modules/@inquirer/core/dist/commonjs/lib/use-memo.d.ts
generated
vendored
Normal file
1
node_modules/@inquirer/core/dist/commonjs/lib/use-memo.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function useMemo<Value>(fn: () => Value, dependencies: ReadonlyArray<unknown>): Value;
|
||||
17
node_modules/@inquirer/core/dist/commonjs/lib/use-memo.js
generated
vendored
Normal file
17
node_modules/@inquirer/core/dist/commonjs/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_ts_1 = require("./hook-engine.js");
|
||||
function useMemo(fn, dependencies) {
|
||||
return (0, hook_engine_ts_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;
|
||||
});
|
||||
}
|
||||
5
node_modules/@inquirer/core/dist/commonjs/lib/use-prefix.d.ts
generated
vendored
Normal file
5
node_modules/@inquirer/core/dist/commonjs/lib/use-prefix.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { Theme, Status } from './theme.ts';
|
||||
export declare function usePrefix({ status, theme, }: {
|
||||
status?: Status;
|
||||
theme?: Theme;
|
||||
}): string;
|
||||
38
node_modules/@inquirer/core/dist/commonjs/lib/use-prefix.js
generated
vendored
Normal file
38
node_modules/@inquirer/core/dist/commonjs/lib/use-prefix.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.usePrefix = usePrefix;
|
||||
const use_state_ts_1 = require("./use-state.js");
|
||||
const use_effect_ts_1 = require("./use-effect.js");
|
||||
const make_theme_ts_1 = require("./make-theme.js");
|
||||
function usePrefix({ status = 'idle', theme, }) {
|
||||
const [showLoader, setShowLoader] = (0, use_state_ts_1.useState)(false);
|
||||
const [tick, setTick] = (0, use_state_ts_1.useState)(0);
|
||||
const { prefix, spinner } = (0, make_theme_ts_1.makeTheme)(theme);
|
||||
(0, use_effect_ts_1.useEffect)(() => {
|
||||
if (status === 'loading') {
|
||||
let tickInterval;
|
||||
let inc = -1;
|
||||
// Delay displaying spinner by 300ms, to avoid flickering
|
||||
const delayTimeout = setTimeout(() => {
|
||||
setShowLoader(true);
|
||||
tickInterval = setInterval(() => {
|
||||
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] ?? prefix['idle']);
|
||||
}
|
||||
6
node_modules/@inquirer/core/dist/commonjs/lib/use-ref.d.ts
generated
vendored
Normal file
6
node_modules/@inquirer/core/dist/commonjs/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;
|
||||
};
|
||||
7
node_modules/@inquirer/core/dist/commonjs/lib/use-ref.js
generated
vendored
Normal file
7
node_modules/@inquirer/core/dist/commonjs/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_ts_1 = require("./use-state.js");
|
||||
function useRef(val) {
|
||||
return (0, use_state_ts_1.useState)({ current: val })[0];
|
||||
}
|
||||
4
node_modules/@inquirer/core/dist/commonjs/lib/use-state.d.ts
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/commonjs/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 {};
|
||||
23
node_modules/@inquirer/core/dist/commonjs/lib/use-state.js
generated
vendored
Normal file
23
node_modules/@inquirer/core/dist/commonjs/lib/use-state.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.useState = useState;
|
||||
const node_async_hooks_1 = require("node:async_hooks");
|
||||
const hook_engine_ts_1 = require("./hook-engine.js");
|
||||
function useState(defaultValue) {
|
||||
return (0, hook_engine_ts_1.withPointer)((pointer) => {
|
||||
const setState = node_async_hooks_1.AsyncResource.bind(function setState(newValue) {
|
||||
// Noop if the value is still the same.
|
||||
if (pointer.get() !== newValue) {
|
||||
pointer.set(newValue);
|
||||
// Trigger re-render
|
||||
(0, hook_engine_ts_1.handleChange)();
|
||||
}
|
||||
});
|
||||
if (pointer.initialized) {
|
||||
return [pointer.get(), setState];
|
||||
}
|
||||
const value = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
||||
pointer.set(value);
|
||||
return [value, setState];
|
||||
});
|
||||
}
|
||||
13
node_modules/@inquirer/core/dist/commonjs/lib/utils.d.ts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/commonjs/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;
|
||||
32
node_modules/@inquirer/core/dist/commonjs/lib/utils.js
generated
vendored
Normal file
32
node_modules/@inquirer/core/dist/commonjs/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_ts_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_ts_1.readline)().output });
|
||||
}
|
||||
3
node_modules/@inquirer/core/dist/commonjs/package.json
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/commonjs/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
13
node_modules/@inquirer/core/dist/esm/index.d.ts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/esm/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
export { isUpKey, isDownKey, isSpaceKey, isBackspaceKey, isTabKey, isNumberKey, isEnterKey, type KeypressEvent, type Keybinding, } from './lib/key.ts';
|
||||
export * from './lib/errors.ts';
|
||||
export { usePrefix } from './lib/use-prefix.ts';
|
||||
export { useState } from './lib/use-state.ts';
|
||||
export { useEffect } from './lib/use-effect.ts';
|
||||
export { useMemo } from './lib/use-memo.ts';
|
||||
export { useRef } from './lib/use-ref.ts';
|
||||
export { useKeypress } from './lib/use-keypress.ts';
|
||||
export { makeTheme } from './lib/make-theme.ts';
|
||||
export type { Theme, Status } from './lib/theme.ts';
|
||||
export { usePagination } from './lib/pagination/use-pagination.ts';
|
||||
export { createPrompt } from './lib/create-prompt.ts';
|
||||
export { Separator } from './lib/Separator.ts';
|
||||
12
node_modules/@inquirer/core/dist/esm/index.js
generated
vendored
Normal file
12
node_modules/@inquirer/core/dist/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export { isUpKey, isDownKey, isSpaceKey, isBackspaceKey, isTabKey, isNumberKey, isEnterKey, } 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 { 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/esm/lib/Separator.d.ts
generated
vendored
Normal file
10
node_modules/@inquirer/core/dist/esm/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: string;
|
||||
constructor(separator?: string);
|
||||
static isSeparator(choice: unknown): choice is Separator;
|
||||
}
|
||||
21
node_modules/@inquirer/core/dist/esm/lib/Separator.js
generated
vendored
Normal file
21
node_modules/@inquirer/core/dist/esm/lib/Separator.js
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');
|
||||
}
|
||||
}
|
||||
4
node_modules/@inquirer/core/dist/esm/lib/create-prompt.d.ts
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/esm/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 {};
|
||||
117
node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
generated
vendored
Normal file
117
node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
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.js";
|
||||
import { PromisePolyfill } from "./promise-polyfill.js";
|
||||
import { withHooks, effectScheduler } from "./hook-engine.js";
|
||||
import { AbortPromptError, CancelPromptError, ExitPromptError } from "./errors.js";
|
||||
function getCallSites() {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const _prepareStackTrace = Error.prepareStackTrace;
|
||||
let result = [];
|
||||
try {
|
||||
Error.prepareStackTrace = (_, callSites) => {
|
||||
const callSitesWithoutCurrent = callSites.slice(1);
|
||||
result = callSitesWithoutCurrent;
|
||||
return callSitesWithoutCurrent;
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
new Error().stack;
|
||||
}
|
||||
catch {
|
||||
// An error will occur if the Node flag --frozen-intrinsics is used.
|
||||
// https://nodejs.org/api/cli.html#--frozen-intrinsics
|
||||
return result;
|
||||
}
|
||||
Error.prepareStackTrace = _prepareStackTrace;
|
||||
return result;
|
||||
}
|
||||
export function createPrompt(view) {
|
||||
const callSites = getCallSites();
|
||||
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();
|
||||
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}`));
|
||||
}));
|
||||
// SIGINT must be explicitly handled by the prompt so the ExitPromptError can be handled.
|
||||
// Otherwise, the prompt will stop and in some scenarios never resolve.
|
||||
// Ref issue #1741
|
||||
const sigint = () => reject(new ExitPromptError(`User force closed the prompt with SIGINT`));
|
||||
rl.on('SIGINT', sigint);
|
||||
cleanups.add(() => rl.removeListener('SIGINT', sigint));
|
||||
// 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));
|
||||
});
|
||||
// Typescript won't allow this, but not all users rely on typescript.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (nextView === undefined) {
|
||||
const callerFilename = callSites[1]?.getFileName();
|
||||
throw new Error(`Prompt functions must return a string.\n at ${callerFilename}`);
|
||||
}
|
||||
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;
|
||||
}
|
||||
20
node_modules/@inquirer/core/dist/esm/lib/errors.d.ts
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/esm/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;
|
||||
}
|
||||
21
node_modules/@inquirer/core/dist/esm/lib/errors.js
generated
vendored
Normal file
21
node_modules/@inquirer/core/dist/esm/lib/errors.js
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';
|
||||
}
|
||||
23
node_modules/@inquirer/core/dist/esm/lib/hook-engine.d.ts
generated
vendored
Normal file
23
node_modules/@inquirer/core/dist/esm/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<Args extends unknown[], R>(fn: (...args: Args) => R): (...args: Args) => 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)): void;
|
||||
run(): void;
|
||||
clearAll(): void;
|
||||
};
|
||||
export {};
|
||||
110
node_modules/@inquirer/core/dist/esm/lib/hook-engine.js
generated
vendored
Normal file
110
node_modules/@inquirer/core/dist/esm/lib/hook-engine.js
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.js";
|
||||
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;
|
||||
},
|
||||
};
|
||||
12
node_modules/@inquirer/core/dist/esm/lib/key.d.ts
generated
vendored
Normal file
12
node_modules/@inquirer/core/dist/esm/lib/key.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export type KeypressEvent = {
|
||||
name: string;
|
||||
ctrl: boolean;
|
||||
};
|
||||
export type Keybinding = 'emacs' | 'vim';
|
||||
export declare const isUpKey: (key: KeypressEvent, keybindings?: ReadonlyArray<Keybinding>) => boolean;
|
||||
export declare const isDownKey: (key: KeypressEvent, keybindings?: ReadonlyArray<Keybinding>) => boolean;
|
||||
export declare const isSpaceKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isBackspaceKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isTabKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isNumberKey: (key: KeypressEvent) => boolean;
|
||||
export declare const isEnterKey: (key: KeypressEvent) => boolean;
|
||||
19
node_modules/@inquirer/core/dist/esm/lib/key.js
generated
vendored
Normal file
19
node_modules/@inquirer/core/dist/esm/lib/key.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
export const isUpKey = (key, keybindings = []) =>
|
||||
// The up key
|
||||
key.name === 'up' ||
|
||||
// Vim keybinding: hjkl keys map to left/down/up/right
|
||||
(keybindings.includes('vim') && key.name === 'k') ||
|
||||
// Emacs keybinding: Ctrl+P means "previous" in Emacs navigation conventions
|
||||
(keybindings.includes('emacs') && key.ctrl && key.name === 'p');
|
||||
export const isDownKey = (key, keybindings = []) =>
|
||||
// The down key
|
||||
key.name === 'down' ||
|
||||
// Vim keybinding: hjkl keys map to left/down/up/right
|
||||
(keybindings.includes('vim') && key.name === 'j') ||
|
||||
// Emacs keybinding: Ctrl+N means "next" in Emacs navigation conventions
|
||||
(keybindings.includes('emacs') && key.ctrl && key.name === 'n');
|
||||
export const isSpaceKey = (key) => key.name === 'space';
|
||||
export const isBackspaceKey = (key) => key.name === 'backspace';
|
||||
export const isTabKey = (key) => key.name === 'tab';
|
||||
export const isNumberKey = (key) => '1234567890'.includes(key.name);
|
||||
export const isEnterKey = (key) => key.name === 'enter' || key.name === 'return';
|
||||
3
node_modules/@inquirer/core/dist/esm/lib/make-theme.d.ts
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/esm/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.ts';
|
||||
export declare function makeTheme<SpecificTheme extends object>(...themes: ReadonlyArray<undefined | PartialDeep<Theme<SpecificTheme>>>): Prettify<Theme<SpecificTheme>>;
|
||||
30
node_modules/@inquirer/core/dist/esm/lib/make-theme.js
generated
vendored
Normal file
30
node_modules/@inquirer/core/dist/esm/lib/make-theme.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { defaultTheme } from "./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;
|
||||
}
|
||||
export function makeTheme(...themes) {
|
||||
const themesToMerge = [
|
||||
defaultTheme,
|
||||
...themes.filter((theme) => theme != null),
|
||||
];
|
||||
return deepMerge(...themesToMerge);
|
||||
}
|
||||
16
node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.d.ts
generated
vendored
Normal file
16
node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { Prettify } from '@inquirer/type';
|
||||
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<{
|
||||
item: T;
|
||||
index: number;
|
||||
isActive: boolean;
|
||||
}>) => string;
|
||||
/** The size of the page. */
|
||||
pageSize: number;
|
||||
/** Allows creating an infinitely looping list. `true` if unspecified. */
|
||||
loop?: boolean;
|
||||
}): string;
|
||||
121
node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js
generated
vendored
Normal file
121
node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
import { useRef } from "../use-ref.js";
|
||||
import { readlineWidth, breakLines } from "../utils.js";
|
||||
function usePointerPosition({ active, renderedItems, pageSize, loop, }) {
|
||||
const state = useRef({
|
||||
lastPointer: active,
|
||||
lastActive: undefined,
|
||||
});
|
||||
const { lastPointer, lastActive } = state.current;
|
||||
const middle = Math.floor(pageSize / 2);
|
||||
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
||||
const defaultPointerPosition = renderedItems
|
||||
.slice(0, active)
|
||||
.reduce((acc, item) => acc + item.length, 0);
|
||||
let pointer = defaultPointerPosition;
|
||||
if (renderedLength > pageSize) {
|
||||
if (loop) {
|
||||
/**
|
||||
* Creates the next position for the pointer considering an infinitely
|
||||
* looping list of items to be rendered on the page.
|
||||
*
|
||||
* The goal is to progressively move the cursor to the middle position as the user move down, and then keep
|
||||
* the cursor there. When the user move up, maintain the cursor position.
|
||||
*/
|
||||
// By default, keep the cursor position as-is.
|
||||
pointer = lastPointer;
|
||||
if (
|
||||
// First render, skip this logic.
|
||||
lastActive != null &&
|
||||
// Only move the pointer down when the user moves down.
|
||||
lastActive < active &&
|
||||
// Check user didn't move up across page boundary.
|
||||
active - lastActive < pageSize) {
|
||||
pointer = Math.min(
|
||||
// Furthest allowed position for the pointer is the middle of the list
|
||||
middle, Math.abs(active - lastActive) === 1
|
||||
? Math.min(
|
||||
// Move the pointer at most the height of the last active item.
|
||||
lastPointer + (renderedItems[lastActive]?.length ?? 0),
|
||||
// If the user moved by one item, move the pointer to the natural position of the active item as
|
||||
// long as it doesn't move the cursor up.
|
||||
Math.max(defaultPointerPosition, lastPointer))
|
||||
: // Otherwise, move the pointer down by the difference between the active and last active item.
|
||||
lastPointer + active - lastActive);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* Creates the next position for the pointer considering a finite list of
|
||||
* items to be rendered on a page.
|
||||
*
|
||||
* The goal is to keep the pointer in the middle of the page whenever possible, until
|
||||
* we reach the bounds of the list (top or bottom). In which case, the cursor moves progressively
|
||||
* to the bottom or top of the list.
|
||||
*/
|
||||
const spaceUnderActive = renderedItems
|
||||
.slice(active)
|
||||
.reduce((acc, item) => acc + item.length, 0);
|
||||
pointer =
|
||||
spaceUnderActive < pageSize - middle
|
||||
? // If the active item is near the end of the list, progressively move the cursor towards the end.
|
||||
pageSize - spaceUnderActive
|
||||
: // Otherwise, progressively move the pointer to the middle of the list.
|
||||
Math.min(defaultPointerPosition, middle);
|
||||
}
|
||||
}
|
||||
// Save state for the next render
|
||||
state.current.lastPointer = pointer;
|
||||
state.current.lastActive = active;
|
||||
return pointer;
|
||||
}
|
||||
export function usePagination({ items, active, renderItem, pageSize, loop = true, }) {
|
||||
const width = readlineWidth();
|
||||
const bound = (num) => ((num % items.length) + items.length) % items.length;
|
||||
const renderedItems = items.map((item, index) => {
|
||||
if (item == null)
|
||||
return [];
|
||||
return breakLines(renderItem({ item, index, isActive: index === active }), width).split('\n');
|
||||
});
|
||||
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
||||
const renderItemAtIndex = (index) => renderedItems[index] ?? [];
|
||||
const pointer = usePointerPosition({ active, renderedItems, pageSize, loop });
|
||||
// Render the active item to decide the position.
|
||||
// If the active item fits under the pointer, we render it there.
|
||||
// Otherwise, we need to render it to fit at the bottom of the page; moving the pointer up.
|
||||
const activeItem = renderItemAtIndex(active).slice(0, pageSize);
|
||||
const activeItemPosition = pointer + activeItem.length <= pageSize ? pointer : pageSize - activeItem.length;
|
||||
// Create an array of lines for the page, and add the lines of the active item into the page
|
||||
const pageBuffer = Array.from({ length: pageSize });
|
||||
pageBuffer.splice(activeItemPosition, activeItem.length, ...activeItem);
|
||||
// Store to prevent rendering the same item twice
|
||||
const itemVisited = new Set([active]);
|
||||
// Fill the page under the active item
|
||||
let bufferPointer = activeItemPosition + activeItem.length;
|
||||
let itemPointer = bound(active + 1);
|
||||
while (bufferPointer < pageSize &&
|
||||
!itemVisited.has(itemPointer) &&
|
||||
(loop && renderedLength > pageSize ? itemPointer !== active : itemPointer > active)) {
|
||||
const lines = renderItemAtIndex(itemPointer);
|
||||
const linesToAdd = lines.slice(0, pageSize - bufferPointer);
|
||||
pageBuffer.splice(bufferPointer, linesToAdd.length, ...linesToAdd);
|
||||
// Move pointers for next iteration
|
||||
itemVisited.add(itemPointer);
|
||||
bufferPointer += linesToAdd.length;
|
||||
itemPointer = bound(itemPointer + 1);
|
||||
}
|
||||
// Fill the page over the active item
|
||||
bufferPointer = activeItemPosition - 1;
|
||||
itemPointer = bound(active - 1);
|
||||
while (bufferPointer >= 0 &&
|
||||
!itemVisited.has(itemPointer) &&
|
||||
(loop && renderedLength > pageSize ? itemPointer !== active : itemPointer < active)) {
|
||||
const lines = renderItemAtIndex(itemPointer);
|
||||
const linesToAdd = lines.slice(Math.max(0, lines.length - bufferPointer - 1));
|
||||
pageBuffer.splice(bufferPointer - linesToAdd.length + 1, linesToAdd.length, ...linesToAdd);
|
||||
// Move pointers for next iteration
|
||||
itemVisited.add(itemPointer);
|
||||
bufferPointer -= linesToAdd.length;
|
||||
itemPointer = bound(itemPointer - 1);
|
||||
}
|
||||
return pageBuffer.filter((line) => typeof line === 'string').join('\n');
|
||||
}
|
||||
7
node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.d.ts
generated
vendored
Normal file
7
node_modules/@inquirer/core/dist/esm/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/esm/lib/promise-polyfill.js
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.js
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 };
|
||||
}
|
||||
}
|
||||
14
node_modules/@inquirer/core/dist/esm/lib/screen-manager.d.ts
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/esm/lib/screen-manager.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { InquirerReadline } from '@inquirer/type';
|
||||
export default class ScreenManager {
|
||||
private height;
|
||||
private extraLinesUnderPrompt;
|
||||
private cursorPos;
|
||||
private readonly rl;
|
||||
constructor(rl: InquirerReadline);
|
||||
write(content: string): void;
|
||||
render(content: string, bottomContent?: string): void;
|
||||
checkCursorPos(): void;
|
||||
done({ clearContent }: {
|
||||
clearContent: boolean;
|
||||
}): void;
|
||||
}
|
||||
79
node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
generated
vendored
Normal file
79
node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
import { stripVTControlCharacters } from 'node:util';
|
||||
import { breakLines, readlineWidth } from "./utils.js";
|
||||
import { cursorDown, cursorUp, cursorTo, cursorShow, eraseLines } from '@inquirer/ansi';
|
||||
const height = (content) => content.split('\n').length;
|
||||
const lastLine = (content) => content.split('\n').pop() ?? '';
|
||||
export default class ScreenManager {
|
||||
// These variables are keeping information to allow correct prompt re-rendering
|
||||
height = 0;
|
||||
extraLinesUnderPrompt = 0;
|
||||
cursorPos;
|
||||
rl;
|
||||
constructor(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 = stripVTControlCharacters(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 += cursorUp(bottomContentHeight);
|
||||
// Return cursor to the initial left offset.
|
||||
output += cursorTo(this.cursorPos.cols);
|
||||
/**
|
||||
* Render and store state for future re-rendering
|
||||
*/
|
||||
this.write(cursorDown(this.extraLinesUnderPrompt) + 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(cursorTo(cursorPos.cols));
|
||||
this.cursorPos = cursorPos;
|
||||
}
|
||||
}
|
||||
done({ clearContent }) {
|
||||
this.rl.setPrompt('');
|
||||
let output = cursorDown(this.extraLinesUnderPrompt);
|
||||
output += clearContent ? eraseLines(this.height) : '\n';
|
||||
output += cursorShow;
|
||||
this.write(output);
|
||||
this.rl.close();
|
||||
}
|
||||
}
|
||||
155
node_modules/@inquirer/core/dist/esm/lib/theme.d.ts
generated
vendored
Normal file
155
node_modules/@inquirer/core/dist/esm/lib/theme.d.ts
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
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.
|
||||
* - `string`: Any other string: The prompt is in a custom state.
|
||||
*/
|
||||
export type Status = 'loading' | 'idle' | 'done' | (string & {});
|
||||
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 {};
|
||||
22
node_modules/@inquirer/core/dist/esm/lib/theme.js
generated
vendored
Normal file
22
node_modules/@inquirer/core/dist/esm/lib/theme.js
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}>`)),
|
||||
},
|
||||
};
|
||||
2
node_modules/@inquirer/core/dist/esm/lib/use-effect.d.ts
generated
vendored
Normal file
2
node_modules/@inquirer/core/dist/esm/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;
|
||||
11
node_modules/@inquirer/core/dist/esm/lib/use-effect.js
generated
vendored
Normal file
11
node_modules/@inquirer/core/dist/esm/lib/use-effect.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { withPointer, effectScheduler } from "./hook-engine.js";
|
||||
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);
|
||||
});
|
||||
}
|
||||
3
node_modules/@inquirer/core/dist/esm/lib/use-keypress.d.ts
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/esm/lib/use-keypress.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { type InquirerReadline } from '@inquirer/type';
|
||||
import { type KeypressEvent } from './key.ts';
|
||||
export declare function useKeypress(userHandler: (event: KeypressEvent, rl: InquirerReadline) => void | Promise<void>): void;
|
||||
20
node_modules/@inquirer/core/dist/esm/lib/use-keypress.js
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/esm/lib/use-keypress.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { useRef } from "./use-ref.js";
|
||||
import { useEffect } from "./use-effect.js";
|
||||
import { withUpdates } from "./hook-engine.js";
|
||||
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);
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
1
node_modules/@inquirer/core/dist/esm/lib/use-memo.d.ts
generated
vendored
Normal file
1
node_modules/@inquirer/core/dist/esm/lib/use-memo.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function useMemo<Value>(fn: () => Value, dependencies: ReadonlyArray<unknown>): Value;
|
||||
14
node_modules/@inquirer/core/dist/esm/lib/use-memo.js
generated
vendored
Normal file
14
node_modules/@inquirer/core/dist/esm/lib/use-memo.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import { withPointer } from "./hook-engine.js";
|
||||
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;
|
||||
});
|
||||
}
|
||||
5
node_modules/@inquirer/core/dist/esm/lib/use-prefix.d.ts
generated
vendored
Normal file
5
node_modules/@inquirer/core/dist/esm/lib/use-prefix.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { Theme, Status } from './theme.ts';
|
||||
export declare function usePrefix({ status, theme, }: {
|
||||
status?: Status;
|
||||
theme?: Theme;
|
||||
}): string;
|
||||
35
node_modules/@inquirer/core/dist/esm/lib/use-prefix.js
generated
vendored
Normal file
35
node_modules/@inquirer/core/dist/esm/lib/use-prefix.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useState } from "./use-state.js";
|
||||
import { useEffect } from "./use-effect.js";
|
||||
import { makeTheme } from "./make-theme.js";
|
||||
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(() => {
|
||||
setShowLoader(true);
|
||||
tickInterval = setInterval(() => {
|
||||
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] ?? prefix['idle']);
|
||||
}
|
||||
6
node_modules/@inquirer/core/dist/esm/lib/use-ref.d.ts
generated
vendored
Normal file
6
node_modules/@inquirer/core/dist/esm/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/esm/lib/use-ref.js
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/esm/lib/use-ref.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { useState } from "./use-state.js";
|
||||
export function useRef(val) {
|
||||
return useState({ current: val })[0];
|
||||
}
|
||||
4
node_modules/@inquirer/core/dist/esm/lib/use-state.d.ts
generated
vendored
Normal file
4
node_modules/@inquirer/core/dist/esm/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 {};
|
||||
20
node_modules/@inquirer/core/dist/esm/lib/use-state.js
generated
vendored
Normal file
20
node_modules/@inquirer/core/dist/esm/lib/use-state.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { AsyncResource } from 'node:async_hooks';
|
||||
import { withPointer, handleChange } from "./hook-engine.js";
|
||||
export function useState(defaultValue) {
|
||||
return withPointer((pointer) => {
|
||||
const setState = AsyncResource.bind(function setState(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(), setState];
|
||||
}
|
||||
const value = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
||||
pointer.set(value);
|
||||
return [value, setState];
|
||||
});
|
||||
}
|
||||
13
node_modules/@inquirer/core/dist/esm/lib/utils.d.ts
generated
vendored
Normal file
13
node_modules/@inquirer/core/dist/esm/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;
|
||||
25
node_modules/@inquirer/core/dist/esm/lib/utils.js
generated
vendored
Normal file
25
node_modules/@inquirer/core/dist/esm/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import cliWidth from 'cli-width';
|
||||
import wrapAnsi from 'wrap-ansi';
|
||||
import { readline } from "./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}
|
||||
*/
|
||||
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 });
|
||||
}
|
||||
3
node_modules/@inquirer/core/dist/esm/package.json
generated
vendored
Normal file
3
node_modules/@inquirer/core/dist/esm/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
Reference in New Issue
Block a user