99 lines
2.6 KiB
TypeScript
99 lines
2.6 KiB
TypeScript
/*
|
|
* Copyright (C) Sapphirecode - All Rights Reserved
|
|
* This file is part of console-app which is released under MIT.
|
|
* See file 'LICENSE' for full license details.
|
|
* Created by Timo Hocker <timo@scode.ovh>, May 2020
|
|
*/
|
|
|
|
/* eslint-disable no-console */
|
|
/* eslint-disable no-process-exit */
|
|
import { Confirm, Input, List, AutoComplete } from 'enquirer';
|
|
import { ErrorCallback } from '../ErrorCallback';
|
|
import { Option, OptionValue } from '../Option';
|
|
import { StringOptionConfig } from '../SubConfigs';
|
|
import { OptionSource } from './OptionSource';
|
|
|
|
export class InteractiveSource extends OptionSource {
|
|
private _exit_on_interrupt: boolean;
|
|
|
|
public constructor (
|
|
exit_on_interrupt: boolean,
|
|
error_callback?:ErrorCallback
|
|
) {
|
|
super (error_callback);
|
|
this._exit_on_interrupt = exit_on_interrupt;
|
|
}
|
|
|
|
private get_message (opt: Option): string {
|
|
return typeof opt.message === 'undefined'
|
|
? `input ${opt.name}`
|
|
: opt.message;
|
|
}
|
|
|
|
private async prompt (opt: Option, val:OptionValue): Promise<void> {
|
|
if (val.filled)
|
|
return;
|
|
let value = null;
|
|
const { option_type } = val.type_validation;
|
|
const { preset } = opt as StringOptionConfig;
|
|
if (
|
|
option_type === 'string'
|
|
|| option_type === 'file'
|
|
|| option_type === 'folder'
|
|
|| option_type === 'path'
|
|
|| option_type === 'number'
|
|
) {
|
|
if (typeof preset === 'undefined') {
|
|
value = await new Input ({
|
|
message: this.get_message (opt),
|
|
default: opt.default
|
|
})
|
|
.run ();
|
|
}
|
|
else {
|
|
value = await new AutoComplete ({
|
|
message: this.get_message (opt),
|
|
default: opt.default,
|
|
choices: preset,
|
|
limit: 10
|
|
})
|
|
.run ();
|
|
}
|
|
}
|
|
if (
|
|
option_type === 'boolean'
|
|
) {
|
|
value = await new Confirm ({
|
|
message: this.get_message (opt),
|
|
default: opt.default
|
|
})
|
|
.run ();
|
|
}
|
|
if (option_type === 'array') {
|
|
value = await new List ({
|
|
message: this.get_message (opt),
|
|
default: opt.default
|
|
})
|
|
.run ();
|
|
}
|
|
if (value === null)
|
|
return;
|
|
|
|
await this.assign_arg (opt, val, value);
|
|
}
|
|
|
|
public async parse (opt: Option, val:OptionValue): Promise<void> {
|
|
while (!val.filled) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
await this.prompt (opt, val)
|
|
.catch ((e) => {
|
|
if (this._exit_on_interrupt)
|
|
process.exit (0);
|
|
throw e;
|
|
});
|
|
if (!val.filled)
|
|
console.log (opt.error || 'input was invalid');
|
|
}
|
|
}
|
|
}
|