console-app/lib/InteractiveOptions.ts
2020-05-09 19:51:43 +02:00

85 lines
2.6 KiB
TypeScript

/* eslint-disable no-process-exit */
/* eslint-disable no-console */
/*
* 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 max-lines-per-function */
/* eslint-disable complexity */
/* eslint-disable max-statements */
/* eslint-disable no-process-env */
import { Persistent } from '@sapphirecode/modelling';
import { TypeValidation } from './Types/TypeValidation';
import { PathType } from './Types/PathType';
import { Option, OptionProcess, OptionType } from './Types';
import { OptionSource } from './Sources/OptionSource';
import { EnvSource } from './Sources/EnvSource';
import { ArgSource } from './Sources/ArgSource';
import { InteractiveSource } from './Sources/InteractiveSource';
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')
};
interface SourceConfig {
env: boolean;
args: boolean;
interactive: boolean;
}
export class InteractiveOptions extends Persistent {
protected options: Array<OptionProcess>;
protected quiet = false;
protected sources: OptionSource[] = [];
public constructor (
options: Array<Option>,
source_config: SourceConfig = { args: true, env: true, interactive: true }
) {
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.string_type;
}
if (source_config.env)
this.sources.push (new EnvSource);
if (source_config.args)
this.sources.push (new ArgSource);
if (source_config.interactive)
this.sources.push (new InteractiveSource);
}
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 ();
}
}