Compare commits

..

No commits in common. "7574c250af7e1bf7098d56ead36f1213d5a04c75" and "229b916cd5b85fd9ba8ff94335e437dcb3859743" have entirely different histories.

25 changed files with 318 additions and 344 deletions

View File

@ -7,31 +7,23 @@
// @ts-nocheck
/* eslint-disable no-console */
/* eslint-disable id-match */
'use strict';
const {
StringOption,
BooleanOption,
NumberOption,
ArrayOption,
FolderOption
} = require ('./dist/lib/index.js');
// eslint-disable-next-line node/no-missing-require, id-match
const { InteractiveOptions } = require ('./dist/lib/index.js');
(async () => {
const str = await new StringOption ({ name: 'str' })
.parse ();
const bool = await new BooleanOption ({ name: 'bool' })
.parse ();
const num = await new NumberOption ({ name: 'num' })
.parse ();
const arr = await new ArrayOption ({ name: 'arr' })
.parse ();
const fld = await new FolderOption ({ name: 'fld' })
.parse ();
const data = { str, bool, num, arr, fld };
console.log (data);
const reader = new InteractiveOptions ([
{ name: 'str', type: 'string', env: 'TEST_STR' },
{ name: 'bool', type: 'boolean', env: 'TEST_BOOL' },
{ name: 'num', type: 'number', env: 'TEST_NUM' },
{ name: 'arr', type: 'array', env: 'TEST_ARR' },
{ name: 'fld', type: 'folder', env: 'TEST_FOLDER' }
], {
exit_on_interrupt: true,
configs: [ 'test.json' ],
error_callback: console.log
});
await reader.parse ();
console.log (reader.serialize (true));
}) ();

108
lib/InteractiveOptions.ts Normal file
View File

@ -0,0 +1,108 @@
/*
* 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';
import { ErrorCallback } from './Types/ErrorCallback';
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;
error_callback?: ErrorCallback;
}
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,
source_config.error_callback
));
}
if (source_config.env !== false)
this.sources.push (new EnvSource (source_config.error_callback));
if (source_config.args !== false)
this.sources.push (new ArgSource (source_config.error_callback));
if (source_config.interactive !== false) {
this.sources.push (new InteractiveSource (
exit_on_interrupt,
source_config.error_callback
));
}
}
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) {
if (!opt.filled) {
opt.value = opt.default;
opt.filled = true;
}
this.set (opt.name, opt.value);
}
return this.to_object ();
}
}

View File

@ -5,34 +5,26 @@
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import { TypeValidation } from './TypeValidation/TypeValidation';
interface SourceConfig {
console?: boolean,
configs?: string[],
env?: boolean,
interactive?: boolean,
}
import { TypeValidation } from './Types/TypeValidation';
import { OptionType } from './OptionType';
interface Option {
name: string;
type: OptionType;
required?: boolean;
default?: unknown;
sources?: SourceConfig;
alias?: string;
env?: string;
description?: string;
message?: string;
preset?: unknown[];
error?: string;
}
class OptionValue {
public filled = false;
public value?: unknown;
public readonly type_validation: TypeValidation;
public constructor (type_validation: TypeValidation) {
this.type_validation = type_validation;
}
interface OptionProcess extends Option {
filled: boolean;
value?: unknown;
type_validation: TypeValidation;
}
export { Option, OptionValue };
export { Option, OptionProcess };

View File

@ -13,3 +13,4 @@ export type OptionType =
| 'folder'
| 'path'
| 'array';

View File

@ -1,8 +0,0 @@
import { TypeValidation } from '../TypeValidation/TypeValidation';
import { BaseOption } from './BaseOption';
export class ArrayOption extends BaseOption<(string|number|boolean)[]> {
protected get validation ():TypeValidation {
return new TypeValidation ('array');
}
}

View File

@ -1,52 +0,0 @@
import { OptionSource } from '../Sources/OptionSource';
import { Option, OptionValue } from '../Option';
import { EnvSource } from '../Sources/EnvSource';
import { ErrorCallback } from '../ErrorCallback';
import { ArgSource } from '../Sources/ArgSource';
import { ConfigSource } from '../Sources/ConfigSource';
import { TypeValidation } from '../TypeValidation/TypeValidation';
import { InteractiveSource } from '../Sources/InteractiveSource';
export abstract class BaseOption<T> {
protected readonly sources: OptionSource[] = [];
private _config: Option;
public constructor (
config: Option,
error_callback?: ErrorCallback,
exit_on_interrupt = true
) {
this._config = config;
const sources = config.sources || {};
if (typeof sources.configs !== 'undefined')
this.sources.push (new ConfigSource (sources.configs, error_callback));
if (sources.env !== false)
this.sources.push (new EnvSource (error_callback));
if (sources.console !== false)
this.sources.push (new ArgSource (error_callback));
if (sources.interactive !== false) {
this.sources.push (new InteractiveSource (
exit_on_interrupt,
error_callback
));
}
}
protected abstract get validation(): TypeValidation;
public async parse (): Promise<T> {
const val = new OptionValue (this.validation);
for (const source of this.sources)
// eslint-disable-next-line no-await-in-loop
await source.parse (this._config, val);
if (!val.filled)
return this._config.default as T;
return val.value as T;
}
}

View File

@ -1,8 +0,0 @@
import { TypeValidation } from '../TypeValidation/TypeValidation';
import { BaseOption } from './BaseOption';
export class BooleanOption extends BaseOption<boolean> {
protected get validation ():TypeValidation {
return new TypeValidation ('boolean');
}
}

View File

@ -1,9 +0,0 @@
import { PathType } from '../TypeValidation/PathType';
import { TypeValidation } from '../TypeValidation/TypeValidation';
import { StringOption } from './StringOption';
export class FileOption extends StringOption {
protected get validation ():TypeValidation {
return new PathType ('file');
}
}

View File

@ -1,9 +0,0 @@
import { PathType } from '../TypeValidation/PathType';
import { TypeValidation } from '../TypeValidation/TypeValidation';
import { StringOption } from './StringOption';
export class FolderOption extends StringOption {
protected get validation (): TypeValidation {
return new PathType ('folder');
}
}

View File

@ -1,8 +0,0 @@
import { TypeValidation } from '../TypeValidation/TypeValidation';
import { BaseOption } from './BaseOption';
export class NumberOption extends BaseOption<number> {
protected get validation ():TypeValidation {
return new TypeValidation ('number');
}
}

View File

@ -1,9 +0,0 @@
import { PathType } from '../TypeValidation/PathType';
import { TypeValidation } from '../TypeValidation/TypeValidation';
import { StringOption } from './StringOption';
export class PathOption extends StringOption {
protected get validation (): TypeValidation {
return new PathType ('path');
}
}

View File

@ -1,14 +0,0 @@
import { TypeValidation } from '../TypeValidation/TypeValidation';
import { StringOptionConfig } from '../SubConfigs';
import { BaseOption } from './BaseOption';
export class StringOption extends BaseOption<string> {
protected get validation ():TypeValidation {
return new TypeValidation ('string');
}
// eslint-disable-next-line no-useless-constructor
public constructor (config: StringOptionConfig) {
super (config);
}
}

View File

@ -8,43 +8,68 @@
/* eslint-disable no-console */
/* eslint-disable no-process-exit */
import yargs, { Options } from 'yargs';
import { Option, OptionValue } from '../Option';
import { OptionProcess } from '../Option';
import { OptionSource } from './OptionSource';
export class ArgSource extends OptionSource {
private create_config (
config: Option,
persistent_type: string
): Record<string, Options> {
return {
[config.name]: {
alias: config.alias,
// eslint-disable-next-line no-undefined
default: undefined,
type: persistent_type
private create_config (options: OptionProcess[]): Record<string, Options> {
const yargs_config: Record<string, Options> = {
quiet: {
alias: 'q',
default: false,
type: 'boolean',
describe: 'do not ask for options interactively'
},
help: {
alias: 'h',
default: false,
type: 'boolean',
describe: ''
}
} as Record<string, Options>;
};
for (const opt of options) {
const type = opt.type_validation.persistent_type;
yargs_config[opt.name] = {
alias: opt.alias,
// eslint-disable-next-line no-undefined
default: type === 'boolean' ? undefined : opt.default,
type,
describe: opt.description
};
}
return yargs_config;
}
public async parse (opt: Option, val: OptionValue): Promise<void> {
const yargs_config = this.create_config (
opt,
val.type_validation.persistent_type
);
public async parse (options: OptionProcess[]): Promise<void> {
const yargs_config = this.create_config (options);
const argv = yargs.options (yargs_config)
.parse ();
if (argv.help) {
yargs.options (yargs_config)
.showHelp ();
process.exit (0);
}
if (typeof argv[opt.name] === 'undefined')
return;
if (
val.type_validation.option_type === 'array'
await Promise.all (options.map ((opt) => {
if (typeof argv[opt.name] === 'undefined')
return Promise.resolve ();
if (
opt.type === 'array'
&& (argv[opt.name] as Array<unknown>)
.filter ((v) => typeof v !== 'undefined').length <= 0
)
return;
)
return Promise.resolve ();
return this.assign_arg (opt, argv[opt.name]);
}));
await this.assign_arg (opt, val, argv[opt.name]);
if (argv.quiet) {
const missing = options.filter ((o) => !o.filled && o.required)
.map ((o) => o.name);
if (missing.length > 0) {
console.error ('missing arguments:');
console.error (missing.join (', '));
process.exit (0);
}
}
}
}

View File

@ -10,8 +10,8 @@ import { dirname, join } from 'path';
import fs from 'fs-extra';
import { run_regex } from '@sapphirecode/utilities';
import hjson from 'hjson';
import { OptionValue, Option } from '../Option';
import { ErrorCallback } from '../ErrorCallback';
import { OptionProcess } from '../Option';
import { ErrorCallback } from '../Types/ErrorCallback';
import { OptionSource } from './OptionSource';
export class ConfigSource extends OptionSource {
@ -46,7 +46,7 @@ export class ConfigSource extends OptionSource {
return obj;
}
public async parse (opt: Option, val: OptionValue): Promise<void> {
public async parse (options: OptionProcess[]): Promise<void> {
const data: Record<string, unknown> = {};
for (const f of this._config_files) {
try {
@ -63,7 +63,9 @@ export class ConfigSource extends OptionSource {
const keys = Object.keys (data);
if (keys.includes (opt.name))
await this.assign_arg (opt, val, data[opt.name]);
for (const opt of options) {
if (keys.includes (opt.name))
await this.assign_arg (opt, data[opt.name]);
}
}
}

View File

@ -6,15 +6,18 @@
*/
/* eslint-disable no-process-env */
import { Option, OptionValue } from '../Option';
import { OptionProcess } from '../Option';
import { OptionSource } from './OptionSource';
export class EnvSource extends OptionSource {
public async parse (opt: Option, val:OptionValue): Promise<void> {
if (
typeof opt.env !== 'undefined'
public async parse (options: OptionProcess[]): Promise<void> {
await Promise.all (options.map ((opt) => {
if (
typeof opt.env !== 'undefined'
&& typeof process.env[opt.env] !== 'undefined'
)
await this.assign_arg (opt, val, process.env[opt.env]);
)
return this.assign_arg (opt, process.env[opt.env]);
return Promise.resolve ();
}));
}
}

View File

@ -8,9 +8,8 @@
/* 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 { OptionProcess, Option } from '../Option';
import { ErrorCallback } from '../Types/ErrorCallback';
import { OptionSource } from './OptionSource';
export class InteractiveSource extends OptionSource {
@ -30,20 +29,18 @@ export class InteractiveSource extends OptionSource {
: opt.message;
}
private async prompt (opt: Option, val:OptionValue): Promise<void> {
if (val.filled)
private async prompt (opt: OptionProcess): Promise<void> {
if (opt.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'
opt.type === 'string'
|| opt.type === 'file'
|| opt.type === 'folder'
|| opt.type === 'path'
|| opt.type === 'number'
) {
if (typeof preset === 'undefined') {
if (typeof opt.preset === 'undefined') {
value = await new Input ({
message: this.get_message (opt),
default: opt.default
@ -54,14 +51,14 @@ export class InteractiveSource extends OptionSource {
value = await new AutoComplete ({
message: this.get_message (opt),
default: opt.default,
choices: preset,
choices: opt.preset,
limit: 10
})
.run ();
}
}
if (
option_type === 'boolean'
opt.type === 'boolean'
) {
value = await new Confirm ({
message: this.get_message (opt),
@ -69,7 +66,7 @@ export class InteractiveSource extends OptionSource {
})
.run ();
}
if (option_type === 'array') {
if (opt.type === 'array') {
value = await new List ({
message: this.get_message (opt),
default: opt.default
@ -79,20 +76,22 @@ export class InteractiveSource extends OptionSource {
if (value === null)
return;
await this.assign_arg (opt, val, value);
await this.assign_arg (opt, 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');
public async parse (options: OptionProcess[]): Promise<void> {
for (const opt of options) {
while (!opt.filled) {
// eslint-disable-next-line no-await-in-loop
await this.prompt (opt)
.catch ((e) => {
if (this._exit_on_interrupt)
process.exit (0);
throw e;
});
if (!opt.filled)
console.log (opt.error || 'input was invalid');
}
}
}
}

View File

@ -5,11 +5,11 @@
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
import { ErrorCallback } from '../ErrorCallback';
import { OptionValue, Option } from '../Option';
import { OptionProcess } from '../Option';
import { ErrorCallback } from '../Types/ErrorCallback';
export abstract class OptionSource {
public abstract async parse(opt: Option, value: OptionValue): Promise<void>;
public abstract async parse(opt: OptionProcess[]): Promise<void>;
protected error_callback?: ErrorCallback;
@ -18,13 +18,12 @@ export abstract class OptionSource {
}
protected async assign_arg (
opt: Option,
val: OptionValue,
opt: OptionProcess,
value: unknown
): Promise<void> {
try {
val.value = await val.type_validation.to_type (value);
val.filled = true;
opt.value = await opt.type_validation.to_type (value);
opt.filled = true;
}
catch (e) {
if (typeof this.error_callback !== 'undefined')

View File

@ -1,7 +0,0 @@
import { Option } from './Option';
interface StringOptionConfig extends Option {
preset?: string[];
}
export { StringOptionConfig };

View File

@ -5,10 +5,4 @@
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
export { ArrayOption } from './Options/ArrayOption';
export { BooleanOption } from './Options/BooleanOption';
export { FileOption } from './Options/FileOption';
export { FolderOption } from './Options/FolderOption';
export { NumberOption } from './Options/NumberOption';
export { PathOption } from './Options/PathOption';
export { StringOption } from './Options/StringOption';
export { InteractiveOptions } from './InteractiveOptions';

View File

@ -6,7 +6,7 @@
*/
import test from 'ava';
import { PathType } from '../lib/TypeValidation/PathType';
import { PathType } from '../lib/Types/PathType';
test ('no file', async (t) => {
const validator = new PathType ('file');

View File

@ -6,7 +6,7 @@
*/
import test from 'ava';
import { TypeValidation } from '../lib/TypeValidation/TypeValidation';
import { TypeValidation } from '../lib/Types/TypeValidation';
test ('string', async (t) => {
const validator = new TypeValidation ('string');

179
yarn.lock
View File

@ -270,16 +270,16 @@
eslint-plugin-sort-requires-by-path "^1.0.2"
"@sapphirecode/modelling@^1.0.35":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@sapphirecode/modelling/-/modelling-1.1.1.tgz#fa67779e3aa3fe267b64a3be7f2b6ee472bc3f1e"
integrity sha512-/8xbn8DuXiL4HbmOGzEs1ClApTEnbRgf9ZhUyrlLjHwR0CPelKGuEcyZh02Zmv3LY0fx/RoEvLcXHZay24modw==
version "1.0.40"
resolved "https://registry.yarnpkg.com/@sapphirecode/modelling/-/modelling-1.0.40.tgz#2118087f3ff5c2e7eedbe6dccfa42e906ec7b71e"
integrity sha512-7bXC09JfdoPvrPXHXiEwavPeNFleSA4g+AgJOBIE0IR0WMCU1n4yTh0xhXOaYhDXNUCMGZkY7PJkJyryUq5Vkw==
dependencies:
"@sapphirecode/utilities" "^1.3.2"
"@sapphirecode/utilities@^1.3.2", "@sapphirecode/utilities@^1.3.4":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@sapphirecode/utilities/-/utilities-1.4.1.tgz#3463136d2aa110f086317748fac7ad6a004d205e"
integrity sha512-KGUzrt1dnFJ3PzF/CGKQyxS6GD34E55Vap8qmDjTNw/JHRLX9hiJbBGTOfBdQEZ43n+3HIfKlNZgXV0T992OSg==
version "1.3.5"
resolved "https://registry.yarnpkg.com/@sapphirecode/utilities/-/utilities-1.3.5.tgz#2010304ac43bdc685b31f6816b5717d451e45b2a"
integrity sha512-blPObWTPCXaGkHFonIigDcuA3kEFkg8XqXyoLWFR6bGtHJvIA9z5IxYaV9ZGzGcMHEqUsH0+T0FaxOgwzxFk0w==
"@sindresorhus/is@^0.14.0":
version "0.14.0"
@ -303,6 +303,11 @@
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
"@types/events@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
"@types/fs-extra@^9.0.0":
version "9.0.1"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.1.tgz#91c8fc4c51f6d5dbe44c2ca9ab09310bd00c7918"
@ -311,10 +316,11 @@
"@types/node" "*"
"@types/glob@^7.1.1":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.2.tgz#06ca26521353a545d94a0adc74f38a59d232c987"
integrity sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==
version "7.1.1"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
dependencies:
"@types/events" "*"
"@types/minimatch" "*"
"@types/node" "*"
@ -328,20 +334,15 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/node@*":
version "14.0.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.12.tgz#9c1d8ffb8084e8936603a6122a7649e40e68e04b"
integrity sha512-/sjzehvjkkpvLpYtN6/2dv5kg41otMGuHQUt9T2aiAuIfleCQRQHXXzF1eAw/qkZTj5Kcf4JSTf7EIizHocy6Q==
version "14.0.10"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.10.tgz#dbfaa170bd9eafccccb6d7060743a761b0844afd"
integrity sha512-Bz23oN/5bi0rniKT24ExLf4cK0JdvN3dH/3k0whYkdN4eI4vS2ZW/2ENNn2uxHCzWcbdHIa/GRuWQytfzCjRYw==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
@ -361,40 +362,40 @@
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@^3.0.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.2.0.tgz#7fb997f391af32ae6ca1dbe56bcefe4dd30bda14"
integrity sha512-t9RTk/GyYilIXt6BmZurhBzuMT9kLKw3fQoJtK9ayv0tXTlznXEAnx07sCLXdkN3/tZDep1s1CEV95CWuARYWA==
version "3.1.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.1.0.tgz#4ac00ecca3bbea740c577f1843bc54fa69c3def2"
integrity sha512-D52KwdgkjYc+fmTZKW7CZpH5ZBJREJKZXRrveMiRCmlzZ+Rw9wRVJ1JAmHQ9b/+Ehy1ZeaylofDB9wwXUt83wg==
dependencies:
"@typescript-eslint/experimental-utils" "3.2.0"
"@typescript-eslint/experimental-utils" "3.1.0"
functional-red-black-tree "^1.0.1"
regexpp "^3.0.0"
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/experimental-utils@3.2.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.2.0.tgz#4dab8fc9f44f059ec073470a81bb4d7d7d51e6c5"
integrity sha512-UbJBsk+xO9dIFKtj16+m42EvUvsjZbbgQ2O5xSTSfVT1Z3yGkL90DVu0Hd3029FZ5/uBgl+F3Vo8FAcEcqc6aQ==
"@typescript-eslint/experimental-utils@3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz#2d5dba7c2ac2a3da3bfa3f461ff64de38587a872"
integrity sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==
dependencies:
"@types/json-schema" "^7.0.3"
"@typescript-eslint/typescript-estree" "3.2.0"
"@typescript-eslint/typescript-estree" "3.1.0"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"
"@typescript-eslint/parser@^3.0.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.2.0.tgz#d9d7867456b1b8ecae9e724269b0bc932f06cbca"
integrity sha512-Vhu+wwdevDLVDjK1lIcoD6ZbuOa93fzqszkaO3iCnmrScmKwyW/AGkzc2UvfE5TCoCXqq7Jyt6SOXjsIlpqF4A==
version "3.1.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.1.0.tgz#9c02ba5d88ad2355672f39e6cd4176f172dd47f8"
integrity sha512-NcDSJK8qTA2tPfyGiPes9HtVKLbksmuYjlgGAUs7Ld2K0swdWibnCq9IJx9kJN8JJdgUJSorFiGaPHBgH81F/Q==
dependencies:
"@types/eslint-visitor-keys" "^1.0.0"
"@typescript-eslint/experimental-utils" "3.2.0"
"@typescript-eslint/typescript-estree" "3.2.0"
"@typescript-eslint/experimental-utils" "3.1.0"
"@typescript-eslint/typescript-estree" "3.1.0"
eslint-visitor-keys "^1.1.0"
"@typescript-eslint/typescript-estree@3.2.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.2.0.tgz#c735f1ca6b4d3cd671f30de8c9bde30843e7ead8"
integrity sha512-uh+Y2QO7dxNrdLw7mVnjUqkwO/InxEqwN0wF+Za6eo3coxls9aH9kQ/5rSvW2GcNanebRTmsT5w1/92lAOb1bA==
"@typescript-eslint/typescript-estree@3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz#eaff52d31e615e05b894f8b9d2c3d8af152a5dd2"
integrity sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==
dependencies:
debug "^4.1.1"
eslint-visitor-keys "^1.1.0"
@ -414,7 +415,7 @@ acorn-walk@^7.1.1:
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e"
integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==
acorn@^7.1.1, acorn@^7.2.0:
acorn@^7.1.1:
version "7.2.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe"
integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==
@ -528,7 +529,7 @@ array-find-index@^1.0.1:
resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=
array-includes@^3.1.1:
array-includes@^3.0.3:
version "3.1.1"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348"
integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==
@ -542,7 +543,7 @@ array-union@^2.1.0:
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
array.prototype.flat@^1.2.3:
array.prototype.flat@^1.2.1:
version "1.2.3"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b"
integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==
@ -741,9 +742,9 @@ chalk@^3.0.0:
supports-color "^7.1.0"
chalk@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
version "4.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72"
integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
@ -1166,7 +1167,7 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-import-resolver-node@^0.3.3:
eslint-import-resolver-node@^0.3.2:
version "0.3.3"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404"
integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==
@ -1174,7 +1175,7 @@ eslint-import-resolver-node@^0.3.3:
debug "^2.6.9"
resolve "^1.13.1"
eslint-module-utils@^2.6.0:
eslint-module-utils@^2.4.1:
version "2.6.0"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6"
integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==
@ -1191,23 +1192,22 @@ eslint-plugin-es@^3.0.0:
regexpp "^3.0.0"
eslint-plugin-import@^2.20.2:
version "2.21.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.1.tgz#3398318e5e4abbd23395c4964ce61538705154c8"
integrity sha512-qYOOsgUv63vHof7BqbzuD+Ud34bXHxFJxntuAC1ZappFZXYbRIek3aJ7jc9i2dHDGDyZ/0zlO0cpioES265Lsw==
version "2.20.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d"
integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg==
dependencies:
array-includes "^3.1.1"
array.prototype.flat "^1.2.3"
array-includes "^3.0.3"
array.prototype.flat "^1.2.1"
contains-path "^0.1.0"
debug "^2.6.9"
doctrine "1.5.0"
eslint-import-resolver-node "^0.3.3"
eslint-module-utils "^2.6.0"
eslint-import-resolver-node "^0.3.2"
eslint-module-utils "^2.4.1"
has "^1.0.3"
minimatch "^3.0.4"
object.values "^1.1.1"
object.values "^1.1.0"
read-pkg-up "^2.0.0"
resolve "^1.17.0"
tsconfig-paths "^3.9.0"
resolve "^1.12.0"
eslint-plugin-node@^11.1.0:
version "11.1.0"
@ -1234,10 +1234,10 @@ eslint-plugin-tsdoc@^0.2.4:
"@microsoft/tsdoc" "0.12.20"
"@microsoft/tsdoc-config" "0.13.4"
eslint-scope@^5.0.0, eslint-scope@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5"
integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==
eslint-scope@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9"
integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==
dependencies:
esrecurse "^4.1.0"
estraverse "^4.1.1"
@ -1249,15 +1249,15 @@ eslint-utils@^2.0.0:
dependencies:
eslint-visitor-keys "^1.1.0"
eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz#74415ac884874495f78ec2a97349525344c981fa"
integrity sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==
eslint-visitor-keys@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
eslint@^7.0.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.2.0.tgz#d41b2e47804b30dbabb093a967fb283d560082e6"
integrity sha512-B3BtEyaDKC5MlfDa2Ha8/D6DsS4fju95zs0hjS3HdGazw+LNayai38A25qMppK37wWGWNYSPOR6oYzlz5MHsRQ==
version "7.1.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.1.0.tgz#d9a1df25e5b7859b0a3d86bb05f0940ab676a851"
integrity sha512-DfS3b8iHMK5z/YLSme8K5cge168I8j8o1uiVmFCgnnjxZQbCGyraF8bMl7Ju4yfBmCuxD7shOF7eqGkcuIHfsA==
dependencies:
"@babel/code-frame" "^7.0.0"
ajv "^6.10.0"
@ -1265,10 +1265,10 @@ eslint@^7.0.0:
cross-spawn "^7.0.2"
debug "^4.0.1"
doctrine "^3.0.0"
eslint-scope "^5.1.0"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"
eslint-visitor-keys "^1.2.0"
espree "^7.1.0"
eslint-visitor-keys "^1.1.0"
espree "^7.0.0"
esquery "^1.2.0"
esutils "^2.0.2"
file-entry-cache "^5.0.1"
@ -1296,14 +1296,14 @@ eslint@^7.0.0:
text-table "^0.2.0"
v8-compile-cache "^2.0.3"
espree@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-7.1.0.tgz#a9c7f18a752056735bf1ba14cb1b70adc3a5ce1c"
integrity sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==
espree@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-7.0.0.tgz#8a7a60f218e69f120a842dc24c5a88aa7748a74e"
integrity sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw==
dependencies:
acorn "^7.2.0"
acorn "^7.1.1"
acorn-jsx "^5.2.0"
eslint-visitor-keys "^1.2.0"
eslint-visitor-keys "^1.1.0"
esprima@^4.0.0:
version "4.0.1"
@ -1354,9 +1354,9 @@ fast-deep-equal@^2.0.1:
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
fast-deep-equal@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
version "3.1.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
fast-diff@^1.1.2:
version "1.2.0"
@ -2040,13 +2040,6 @@ json-stable-stringify-without-jsonify@^1.0.1:
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
dependencies:
minimist "^1.2.0"
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
@ -2371,7 +2364,7 @@ object.assign@^4.1.0:
has-symbols "^1.0.0"
object-keys "^1.0.11"
object.values@^1.1.1:
object.values@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e"
integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==
@ -2779,7 +2772,7 @@ resolve-from@^5.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2:
resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2:
version "1.17.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
@ -3185,16 +3178,6 @@ trim-off-newlines@^1.0.1:
resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3"
integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM=
tsconfig-paths@^3.9.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b"
integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==
dependencies:
"@types/json5" "^0.0.29"
json5 "^1.0.1"
minimist "^1.2.0"
strip-bom "^3.0.0"
tslib@^1.8.1, tslib@^1.9.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
@ -3242,9 +3225,9 @@ typedarray-to-buffer@^3.1.5:
is-typedarray "^1.0.0"
typescript@^3.9.2:
version "3.9.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36"
integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==
version "3.9.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.3.tgz#d3ac8883a97c26139e42df5e93eeece33d610b8a"
integrity sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==
unique-string@^2.0.0:
version "2.0.0"