console-app/lib/InteractiveOptions.ts
2020-05-22 11:50:07 +02:00

95 lines
2.9 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
*/
import { Persistent } from '@sapphirecode/modelling';
import { TypeValidation } from './Types/TypeValidation';
import { PathType } from './Types/PathType';
import { OptionType } from './OptionType';
import { OptionSource } from './Sources/OptionSource';
import { EnvSource } from './Sources/EnvSource';
import { ArgSource } from './Sources/ArgSource';
import { ConfigSource } from './Sources/ConfigSource';
import { InteractiveSource } from './Sources/InteractiveSource';
import { Option, OptionProcess } from './Option';
const types: Record<OptionType, TypeValidation> = {
string: new TypeValidation ('string'),
number: new TypeValidation ('number'),
boolean: new TypeValidation ('boolean'),
file: new PathType ('file'),
folder: new PathType ('folder'),
path: new PathType ('path'),
array: new TypeValidation ('array')
};
interface SourceConfig {
env?: boolean;
args?: boolean;
interactive?: boolean;
configs?: string[];
exit_on_interrupt?: boolean;
}
export class InteractiveOptions extends Persistent {
protected options: Array<OptionProcess>;
protected quiet = false;
protected sources: OptionSource[] = [];
public constructor (
options: Array<Option>,
source_config: SourceConfig = {}
) {
super ();
this.options = options
.map ((v) => ({
filled: false,
type_validation: types[v.type],
...v
} as OptionProcess));
for (const option of this.options) {
if (
typeof option.default !== 'undefined'
&& typeof option.default !== option.type_validation.string_type
) {
throw new Error (
`default does not match option type on ${option.name}`
);
}
this.properties[option.name] = option.type_validation.persistent_type;
}
const exit_on_interrupt
= typeof source_config.exit_on_interrupt === 'boolean'
? source_config.exit_on_interrupt
: false;
if (
typeof source_config.configs !== 'undefined'
&& Array.isArray (source_config.configs)
)
this.sources.push (new ConfigSource (source_config.configs));
if (source_config.env !== false)
this.sources.push (new EnvSource);
if (source_config.args !== false)
this.sources.push (new ArgSource);
if (source_config.interactive !== false)
this.sources.push (new InteractiveSource (exit_on_interrupt));
}
public async parse (): Promise<Record<string, unknown>> {
for (const src of this.sources) {
// eslint-disable-next-line no-await-in-loop
await src.parse (this.options);
}
for (const opt of this.options)
this.set (opt.name, opt.value);
return this.to_object ();
}
}