Comparing version 10.2.1 to 10.2.2
@@ -13,3 +13,3 @@ "use strict"; | ||
const prompt_mjs_1 = __importDefault(require('./ui/prompt.js')); | ||
const defaultPrompts = { | ||
const builtInPrompts = { | ||
input: prompts_1.input, | ||
@@ -37,3 +37,3 @@ select: prompts_1.select, | ||
} | ||
promptModule.prompts = Object.assign({}, defaultPrompts); | ||
promptModule.prompts = Object.assign({}, builtInPrompts); | ||
/** | ||
@@ -50,3 +50,3 @@ * Register a prompt type | ||
promptModule.restoreDefaultPrompts = function () { | ||
promptModule.prompts = Object.assign({}, defaultPrompts); | ||
promptModule.prompts = Object.assign({}, builtInPrompts); | ||
}; | ||
@@ -53,0 +53,0 @@ return promptModule; |
@@ -6,3 +6,3 @@ import { checkbox, confirm, editor, expand, input, number, password, rawlist, search, select } from '@inquirer/prompts'; | ||
type AsyncCallbackFunction<R> = (...args: [error: null | undefined, value: R] | [error: Error, value: undefined]) => void; | ||
type AsyncGetterFunction<R, A extends Answers> = (this: { | ||
export type AsyncGetterFunction<R, A extends Answers> = (this: { | ||
async: () => AsyncCallbackFunction<R>; | ||
@@ -33,2 +33,6 @@ }, answers: Prettify<Partial<A>>) => void | R | Promise<R>; | ||
name: string; | ||
message: string | AsyncGetterFunction<string, A>; | ||
default?: any; | ||
choices?: any; | ||
filter?: (answer: any, answers: Partial<A>) => any; | ||
askAnswered?: boolean; | ||
@@ -50,3 +54,3 @@ when?: boolean | AsyncGetterFunction<boolean, A>; | ||
}[Extract<keyof Q, string>]; | ||
export type PromptSession<Q extends AnyQuestion<any>> = Q[] | Record<string, Omit<Q, 'name'>> | Observable<Q> | Q; | ||
export type PromptSession<A extends Answers> = AnyQuestion<A>[] | Record<string, Omit<AnyQuestion<A>, 'name'>> | Observable<AnyQuestion<A>> | AnyQuestion<A>; | ||
export type StreamOptions = Prettify<Context & { | ||
@@ -53,0 +57,0 @@ skipTTYChecks?: boolean; |
import { Observable } from 'rxjs'; | ||
import type { InquirerReadline } from '@inquirer/type'; | ||
import type { Answers, AnyQuestion, PromptSession, StreamOptions } from '../types.js'; | ||
import type { Answers, PromptSession, StreamOptions } from '../types.js'; | ||
export declare const _: { | ||
@@ -44,22 +44,16 @@ set: (obj: Record<string, unknown>, path: string | undefined, value: unknown) => void; | ||
export default class PromptsRunner<A extends Answers> { | ||
prompts: PromptCollection; | ||
private prompts; | ||
answers: Partial<A>; | ||
process: Observable<any>; | ||
onClose?: () => void; | ||
opt: StreamOptions; | ||
private abortController; | ||
private opt; | ||
rl?: InquirerReadline; | ||
constructor(prompts: PromptCollection, opt?: StreamOptions); | ||
run(questions: PromptSession<AnyQuestion<A>>, answers?: Partial<A>): Promise<A>; | ||
processQuestion(question: AnyQuestion<A>): Observable<{ | ||
name: string; | ||
answer: unknown; | ||
}>; | ||
fetchAnswer(question: AnyQuestion<A>): Observable<{ | ||
name: string; | ||
answer: unknown; | ||
}>; | ||
run(questions: PromptSession<A>, answers?: Partial<A>): Promise<A>; | ||
private prepareQuestion; | ||
private fetchAnswer; | ||
/** | ||
* Handle the ^C exit | ||
*/ | ||
onForceClose: () => void; | ||
private onForceClose; | ||
/** | ||
@@ -69,4 +63,3 @@ * Close the interface and cleanup listeners | ||
close: () => void; | ||
setDefaultType: (question: AnyQuestion<A>) => Observable<AnyQuestion<A>>; | ||
filterIfRunnable: (question: AnyQuestion<A>) => Observable<AnyQuestion<A>>; | ||
private shouldRun; | ||
} |
@@ -16,3 +16,3 @@ "use strict"; | ||
exports._ = void 0; | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment */ | ||
const node_readline_1 = __importDefault(require("node:readline")); | ||
@@ -22,2 +22,3 @@ const rxjs_1 = require("rxjs"); | ||
const mute_stream_1 = __importDefault(require("mute-stream")); | ||
const core_1 = require("@inquirer/core"); | ||
const ansi_escapes_1 = __importDefault(require("ansi-escapes")); | ||
@@ -45,3 +46,2 @@ exports._ = { | ||
// @ts-expect-error implicit any on res[key] | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return | ||
(res, key) => (res !== null && res !== undefined ? res[key] : res), obj); | ||
@@ -57,11 +57,9 @@ const result = travel(/[,[\]]+?/) || travel(/[,.[\]]+?/); | ||
function fetchAsyncQuestionProperty(question, prop, answers) { | ||
if (prop in question) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const propGetter = question[prop]; | ||
if (typeof propGetter === 'function') { | ||
return (0, rxjs_1.from)((0, run_async_1.default)(propGetter)(answers).then((value) => { | ||
return Object.assign(question, { [prop]: value }); | ||
})); | ||
return (0, run_async_1.default)(propGetter)(answers); | ||
} | ||
} | ||
return (0, rxjs_1.of)(question); | ||
return propGetter; | ||
}); | ||
} | ||
@@ -141,7 +139,7 @@ class TTYError extends Error { | ||
}); | ||
Object.defineProperty(this, "onClose", { | ||
Object.defineProperty(this, "abortController", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
value: new AbortController() | ||
}); | ||
@@ -160,2 +158,110 @@ Object.defineProperty(this, "opt", { | ||
}); | ||
Object.defineProperty(this, "prepareQuestion", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (question) => __awaiter(this, void 0, void 0, function* () { | ||
const [message, defaultValue, resolvedChoices] = yield Promise.all([ | ||
fetchAsyncQuestionProperty(question, 'message', this.answers), | ||
fetchAsyncQuestionProperty(question, 'default', this.answers), | ||
fetchAsyncQuestionProperty(question, 'choices', this.answers), | ||
]); | ||
let choices; | ||
if (Array.isArray(resolvedChoices)) { | ||
choices = resolvedChoices.map((choice) => { | ||
if (typeof choice === 'string' || typeof choice === 'number') { | ||
return { name: choice, value: choice }; | ||
} | ||
else if (typeof choice === 'object' && | ||
choice != null && | ||
!('value' in choice) && | ||
'name' in choice) { | ||
return Object.assign(Object.assign({}, choice), { value: choice.name }); | ||
} | ||
return choice; | ||
}); | ||
} | ||
return Object.assign({}, question, { | ||
message, | ||
default: defaultValue, | ||
choices, | ||
type: question.type in this.prompts ? question.type : 'input', | ||
}); | ||
}) | ||
}); | ||
Object.defineProperty(this, "fetchAnswer", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (rawQuestion) => __awaiter(this, void 0, void 0, function* () { | ||
const question = yield this.prepareQuestion(rawQuestion); | ||
const prompt = this.prompts[question.type]; | ||
if (prompt == null) { | ||
throw new Error(`Prompt for type ${question.type} not found`); | ||
} | ||
let cleanupSignal; | ||
const promptFn = isPromptConstructor(prompt) | ||
? (q, { signal } = {}) => new Promise((resolve, reject) => { | ||
const rl = node_readline_1.default.createInterface(setupReadlineOptions(this.opt)); | ||
rl.resume(); | ||
const onClose = () => { | ||
process.removeListener('exit', this.onForceClose); | ||
rl.removeListener('SIGINT', this.onForceClose); | ||
rl.setPrompt(''); | ||
rl.output.unmute(); | ||
rl.output.write(ansi_escapes_1.default.cursorShow); | ||
rl.output.end(); | ||
rl.close(); | ||
}; | ||
this.rl = rl; | ||
// Make sure new prompt start on a newline when closing | ||
process.on('exit', this.onForceClose); | ||
rl.on('SIGINT', this.onForceClose); | ||
const activePrompt = new prompt(q, rl, this.answers); | ||
const cleanup = () => { | ||
onClose(); | ||
this.rl = undefined; | ||
cleanupSignal === null || cleanupSignal === void 0 ? void 0 : cleanupSignal(); | ||
}; | ||
if (signal) { | ||
const abort = () => { | ||
reject(new core_1.AbortPromptError({ cause: signal.reason })); | ||
cleanup(); | ||
}; | ||
if (signal.aborted) { | ||
abort(); | ||
return; | ||
} | ||
signal.addEventListener('abort', abort); | ||
cleanupSignal = () => { | ||
signal.removeEventListener('abort', abort); | ||
cleanupSignal = undefined; | ||
}; | ||
} | ||
activePrompt.run().then(resolve, reject).finally(cleanup); | ||
}) | ||
: prompt; | ||
const { signal: moduleSignal } = this.opt; | ||
if (moduleSignal === null || moduleSignal === void 0 ? void 0 : moduleSignal.aborted) { | ||
this.abortController.abort(moduleSignal.reason); | ||
} | ||
else if (moduleSignal) { | ||
const abort = (reason) => { var _a; return (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort(reason); }; | ||
moduleSignal.addEventListener('abort', abort); | ||
cleanupSignal = () => { | ||
moduleSignal.removeEventListener('abort', abort); | ||
}; | ||
} | ||
const { filter = (value) => value } = question; | ||
const { signal } = this.abortController; | ||
return promptFn(question, Object.assign(Object.assign({}, this.opt), { signal })) | ||
.then((answer) => ({ | ||
name: question.name, | ||
answer: filter(answer, this.answers), | ||
})) | ||
.finally(() => { | ||
cleanupSignal === null || cleanupSignal === void 0 ? void 0 : cleanupSignal(); | ||
}); | ||
}) | ||
}); | ||
/** | ||
@@ -182,44 +288,22 @@ * Handle the ^C exit | ||
value: () => { | ||
// Remove events listeners | ||
process.removeListener('exit', this.onForceClose); | ||
if (typeof this.onClose === 'function') { | ||
this.onClose(); | ||
} | ||
var _a; | ||
(_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort(); | ||
} | ||
}); | ||
Object.defineProperty(this, "setDefaultType", { | ||
Object.defineProperty(this, "shouldRun", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (question) => { | ||
// Default type to input | ||
if (!this.prompts[question.type]) { | ||
question = Object.assign({}, question, { type: 'input' }); | ||
} | ||
return (0, rxjs_1.defer)(() => (0, rxjs_1.of)(question)); | ||
} | ||
}); | ||
Object.defineProperty(this, "filterIfRunnable", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (question) => { | ||
value: (question) => __awaiter(this, void 0, void 0, function* () { | ||
if (question.askAnswered !== true && | ||
exports._.get(this.answers, question.name) !== undefined) { | ||
return rxjs_1.EMPTY; | ||
return false; | ||
} | ||
const { when } = question; | ||
if (when === false) { | ||
return rxjs_1.EMPTY; | ||
if (typeof when === 'function') { | ||
const shouldRun = yield (0, run_async_1.default)(when)(this.answers); | ||
return shouldRun !== false; | ||
} | ||
if (typeof when !== 'function') { | ||
return (0, rxjs_1.of)(question); | ||
} | ||
return (0, rxjs_1.defer)(() => (0, rxjs_1.from)((0, run_async_1.default)(when)(this.answers).then((shouldRun) => { | ||
if (shouldRun) { | ||
return question; | ||
} | ||
return; | ||
})).pipe((0, rxjs_1.filter)((val) => val != null))); | ||
} | ||
return when !== false; | ||
}) | ||
}); | ||
@@ -231,2 +315,3 @@ this.opt = opt; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.abortController = new AbortController(); | ||
// Keep global reference to the answers | ||
@@ -251,3 +336,8 @@ this.answers = typeof answers === 'object' ? Object.assign({}, answers) : {}; | ||
} | ||
this.process = obs.pipe((0, rxjs_1.concatMap)((question) => this.processQuestion(question))); | ||
this.process = obs.pipe((0, rxjs_1.concatMap)((question) => (0, rxjs_1.of)(question).pipe((0, rxjs_1.concatMap)((question) => (0, rxjs_1.from)(this.shouldRun(question).then((shouldRun) => { | ||
if (shouldRun) { | ||
return question; | ||
} | ||
return; | ||
})).pipe((0, rxjs_1.filter)((val) => val != null))), (0, rxjs_1.concatMap)((question) => (0, rxjs_1.defer)(() => (0, rxjs_1.from)(this.fetchAnswer(question))))))); | ||
return (0, rxjs_1.lastValueFrom)(this.process.pipe((0, rxjs_1.reduce)((answersObj, answer) => { | ||
@@ -261,59 +351,3 @@ exports._.set(answersObj, answer.name, answer.answer); | ||
} | ||
processQuestion(question) { | ||
question = Object.assign({}, question); | ||
return (0, rxjs_1.defer)(() => { | ||
const obs = (0, rxjs_1.of)(question); | ||
return obs.pipe((0, rxjs_1.concatMap)(this.setDefaultType), (0, rxjs_1.concatMap)(this.filterIfRunnable), (0, rxjs_1.concatMap)((question) => fetchAsyncQuestionProperty(question, 'message', this.answers)), (0, rxjs_1.concatMap)((question) => fetchAsyncQuestionProperty(question, 'default', this.answers)), (0, rxjs_1.concatMap)((question) => fetchAsyncQuestionProperty(question, 'choices', this.answers)), (0, rxjs_1.concatMap)((question) => { | ||
if ('choices' in question && Array.isArray(question.choices)) { | ||
const choices = question.choices.map((choice) => { | ||
if (typeof choice === 'string' || typeof choice === 'number') { | ||
return { name: choice, value: choice }; | ||
} | ||
else if (!('value' in choice)) { | ||
return Object.assign(Object.assign({}, choice), { value: choice.name }); | ||
} | ||
return choice; | ||
}); | ||
return (0, rxjs_1.of)(Object.assign(Object.assign({}, question), { choices })); | ||
} | ||
return (0, rxjs_1.of)(question); | ||
}), (0, rxjs_1.concatMap)((question) => this.fetchAnswer(question))); | ||
}); | ||
} | ||
fetchAnswer(question) { | ||
const prompt = this.prompts[question.type]; | ||
if (prompt == null) { | ||
throw new Error(`Prompt for type ${question.type} not found`); | ||
} | ||
return isPromptConstructor(prompt) | ||
? (0, rxjs_1.defer)(() => { | ||
const rl = node_readline_1.default.createInterface(setupReadlineOptions(this.opt)); | ||
rl.resume(); | ||
const onClose = () => { | ||
rl.removeListener('SIGINT', this.onForceClose); | ||
rl.setPrompt(''); | ||
rl.output.unmute(); | ||
rl.output.write(ansi_escapes_1.default.cursorShow); | ||
rl.output.end(); | ||
rl.close(); | ||
}; | ||
this.onClose = onClose; | ||
this.rl = rl; | ||
// Make sure new prompt start on a newline when closing | ||
process.on('exit', this.onForceClose); | ||
rl.on('SIGINT', this.onForceClose); | ||
const activePrompt = new prompt(question, rl, this.answers); | ||
return (0, rxjs_1.from)(activePrompt.run().then((answer) => { | ||
onClose(); | ||
this.onClose = undefined; | ||
this.rl = undefined; | ||
return { name: question.name, answer }; | ||
})); | ||
}) | ||
: (0, rxjs_1.defer)(() => (0, rxjs_1.from)(prompt(question, this.opt).then((answer) => ({ | ||
name: question.name, | ||
answer, | ||
})))); | ||
} | ||
} | ||
exports.default = PromptsRunner; |
{ | ||
"name": "inquirer", | ||
"version": "10.2.1", | ||
"version": "10.2.2", | ||
"description": "A collection of common interactive command line user interfaces.", | ||
@@ -58,2 +58,3 @@ "author": "Simon Boudrias <admin@simonboudrias.com>", | ||
"dependencies": { | ||
"@inquirer/core": "^9.1.0", | ||
"@inquirer/prompts": "^5.5.0", | ||
@@ -88,3 +89,3 @@ "@inquirer/type": "^1.5.3", | ||
"typings": "./dist/cjs/types/index.d.ts", | ||
"gitHead": "4937ea3a74152b59bf4198dbaa803119ed4ef8e2" | ||
"gitHead": "b513027490c177e0af1f5dcf0572ea678bb7f07d" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
75337
944
8
+ Added@inquirer/core@^9.1.0