154 lines
3.6 KiB
TypeScript
154 lines
3.6 KiB
TypeScript
import * as plugins from './smartinteract.plugins.js';
|
|
import { AnswerBucket } from './smartinteract.classes.answerbucket.js';
|
|
|
|
/**
|
|
* the availeable question types
|
|
*/
|
|
export type questionType =
|
|
| 'input'
|
|
| 'confirm'
|
|
| 'list'
|
|
| 'rawlist'
|
|
| 'expand'
|
|
| 'checkbox'
|
|
| 'password'
|
|
| 'editor';
|
|
|
|
/**
|
|
* a choice
|
|
*/
|
|
export interface IChoiceObject {
|
|
name: string;
|
|
value: any;
|
|
}
|
|
|
|
export interface IQuestionObject {
|
|
name: string;
|
|
type: questionType;
|
|
message: string;
|
|
default: any;
|
|
choices?: string[] | IChoiceObject[];
|
|
validate?: IValidateFunction;
|
|
}
|
|
|
|
export interface IAnswerObject {
|
|
name: string;
|
|
value: any;
|
|
}
|
|
|
|
export interface IValidateFunction {
|
|
(anyObject: any): boolean;
|
|
}
|
|
|
|
/**
|
|
* class SmartInteract - allows to specify an user interaction during runtime
|
|
*/
|
|
export class SmartInteract {
|
|
// STATIC
|
|
public static async getCliConfirmation(
|
|
questionArg: string,
|
|
defaultArg: boolean
|
|
): Promise<boolean> {
|
|
const smartinteractInstance = new SmartInteract();
|
|
const response = await smartinteractInstance.askQuestion({
|
|
default: defaultArg,
|
|
message: questionArg,
|
|
name: 'question',
|
|
type: 'confirm',
|
|
});
|
|
return response.value;
|
|
}
|
|
|
|
// INSTANCE
|
|
/**
|
|
* holds the qestion queue, that is emptied once you call
|
|
*/
|
|
private questionMap = new plugins.lik.ObjectMap<IQuestionObject>();
|
|
|
|
/**
|
|
* constructor of class SmartInteract
|
|
*/
|
|
constructor(questionArrayArg?: IQuestionObject[]) {
|
|
if (questionArrayArg) {
|
|
this.addQuestions(questionArrayArg);
|
|
}
|
|
}
|
|
/**
|
|
* allows you to ask a single question and returns the answer in a promise
|
|
* skips the queue
|
|
*/
|
|
askQuestion(optionsArg: IQuestionObject): Promise<IAnswerObject> {
|
|
const done = plugins.smartpromise.defer<IAnswerObject>();
|
|
if (this.isValidEnv()) {
|
|
plugins.inquirer.default
|
|
.prompt([
|
|
{
|
|
name: optionsArg.name,
|
|
type: optionsArg.type,
|
|
message: optionsArg.message,
|
|
default: optionsArg.default,
|
|
choices: optionsArg.choices,
|
|
validate: optionsArg.validate,
|
|
},
|
|
])
|
|
.then((answers) => {
|
|
// adjust to the fact that now dots define paths for inquirer
|
|
const answerValue = plugins.smartobject.smartGet(answers, optionsArg.name);
|
|
done.resolve({
|
|
name: optionsArg.name,
|
|
value: answerValue,
|
|
});
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
});
|
|
} else {
|
|
const answer: IAnswerObject = {
|
|
name: optionsArg.name,
|
|
value: optionsArg.default,
|
|
};
|
|
done.resolve(answer);
|
|
}
|
|
|
|
return done.promise;
|
|
}
|
|
|
|
/**
|
|
* add questions to queue
|
|
*/
|
|
addQuestions(questionArrayArg: IQuestionObject[]) {
|
|
this.questionMap.addArray(questionArrayArg);
|
|
}
|
|
|
|
/**
|
|
* run the question queue
|
|
*/
|
|
runQueue() {
|
|
const done = plugins.smartpromise.defer<AnswerBucket>();
|
|
const answerBucket = new AnswerBucket();
|
|
const handleQuestion = async () => {
|
|
if (!this.questionMap.isEmpty()) {
|
|
const oneQuestion = this.questionMap.getOneAndRemove();
|
|
const answer: IAnswerObject = await this.askQuestion(oneQuestion);
|
|
answerBucket.addAnswer(answer);
|
|
handleQuestion(); // recursion: as questions until empty
|
|
} else {
|
|
done.resolve(answerBucket); // when empty, then resolve promise
|
|
}
|
|
};
|
|
handleQuestion();
|
|
return done.promise;
|
|
}
|
|
|
|
/**
|
|
* checks if the current env is valid for userinput
|
|
*/
|
|
private isValidEnv(): boolean {
|
|
if (!process.env.CI) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|