Compare commits

..

7 Commits

Author SHA1 Message Date
f372e1ea17 path selector 2020-06-16 12:52:41 +02:00
d477124973 more dynamic interactive source register 2020-06-16 09:40:12 +02:00
f7c03f82f1 split interactive source 2020-06-15 11:56:33 +02:00
089519844f complete documentation 2020-06-12 14:34:53 +02:00
bc960f632e update-scanner: automatic update
@sapphirecode/eslint-config-ts: 1.1.11 ==> 1.1.12 minor
@sapphirecode/modelling: 1.1.1 ==> 1.1.2 minor
@sapphirecode/utilities: 1.4.1 ==> 1.4.2 minor
2020-06-11 20:29:33 +02:00
88a35265d0 small improvement, changelog, start documentation for 2.0 2020-06-10 22:44:54 +02:00
3fa23c1697 init version 2 2020-06-09 21:33:48 +02:00
21 changed files with 306 additions and 177 deletions

View File

@ -20,14 +20,16 @@ const {
} = require ('./dist/lib/index.js'); } = require ('./dist/lib/index.js');
(async () => { (async () => {
const str = await new StringOption ({ name: 'str' }) /*
.parse (); * const str = await new StringOption ({ name: 'str' })
const bool = await new BooleanOption ({ name: 'bool' }) *.parse ();
.parse (); *const bool = await new BooleanOption ({ name: 'bool' })
const num = await new NumberOption ({ name: 'num' }) *.parse ();
.parse (); *const num = await new NumberOption ({ name: 'num' })
const arr = await new ArrayOption ({ name: 'arr' }) *.parse ();
.parse (); *const arr = await new ArrayOption ({ name: 'arr' })
*.parse ();
*/
const fld = await new FolderOption ({ name: 'fld' }) const fld = await new FolderOption ({ name: 'fld' })
.parse (); .parse ();

View File

@ -1,5 +1,17 @@
# Changelog # Changelog
## 2.0.0
Restructuring to split different Option types and keep specific parameters separate
### Breaking Changes
- new structure
- option 'required' has been removed
- automatic console parameters have been removed
- help page
- quiet switch (interactive prompts can be disabled using the sources option)
## 1.8.0 ## 1.8.0
callback in case an option could not be assigned instead of silently skipping callback in case an option could not be assigned instead of silently skipping

2
Jenkinsfile vendored
View File

@ -5,7 +5,7 @@ pipeline {
VERSION = VersionNumber([ VERSION = VersionNumber([
versionNumberString: versionNumberString:
'${BUILDS_ALL_TIME}', '${BUILDS_ALL_TIME}',
versionPrefix: '1.8.', versionPrefix: '2.0.',
worstResultForIncrement: 'SUCCESS' worstResultForIncrement: 'SUCCESS'
]) ])
} }

View File

@ -1,8 +1,8 @@
# @sapphirecode/console-app # @sapphirecode/console-app
version: 1.8.x version: 2.0.x
read parameters from env, console args or interactively read parameters from env, config files, console args or interactively
## Installation ## Installation
@ -17,46 +17,36 @@ yarn:
## Usage ## Usage
```js ```js
const {InteractiveOptions} = require('@sapphirecode/console-app'); const {
ArrayOption, // arrays made out of numbers, strings and booleans
BooleanOption,
FileOption, // paths that exist and are a file
FolderOption, // paths that exist and are a folder
NumberOption,
PathOption, // paths that exist in the file system
StringOption,
} = require('@sapphirecode/console-app');
const reader = new InteractiveOptions([ const input = await new BooleanOption({
{ name: 'foo', // option name used in configs and console arguments
name: 'foo', // name of the option
type: 'boolean', // data type // optional settings:
required: true, // require option to be specified (optional) default: false, // default value
default: false, // default value (optional) sources: {
alias: 'f', // shorthand alias in the console (optional) configs: [], // config files to read from. none by default
env: 'fooenv', // environment variable to read from (optional) interactive: true, // use interactive prompts
description: 'the switch foo', // description in the help page (optional) console: true // read from console arguments
message: 'should foo be true?', // message when asking interactively (optional) // environment is always on if the 'env' option below is specified
preset: [], // preset choices for string and path types (optional)
error: 'wrong input' // message to display when the user gives invalid input
}, },
]); alias: 'f', // shorthand console argument name
env: 'foo_env', // name of the environment variable to read from
const result = await reader.parse(); message: 'input foo', // message to display in interactive prompt
console.log(result.foo); error: 'failed to read foo', // message to display when input was invalid
error_callback: (opt, val, err)=>{...}, // function to call when an option value could not be read
exit_on_interrupt: true, // exit program when user cancels the interactive prompt
}).parse();
``` ```
available data types:
- string
- number
- boolean
- path: expects a path that exists
- file: expects a path that exists and is a file
- folder: expects a path that exists and is a folder
- array: arrays made out of strings, numbers and booleans
the console reader automatically adds the options --help (-h) and --quiet (-q)
- help: shows the yargs help screen
- quiet: prevents interactive queries and throws an error when not all required
parameters are specified
the reader can also be constructed with additional options that specify which
sources should be used. It reads from all, except config files by default
config files can import other config files with #include. example: config files can import other config files with #include. example:
```json ```json
@ -68,20 +58,6 @@ config files can import other config files with #include. example:
config files are parsed using [hjson](https://github.com/hjson/hjson-js) config files are parsed using [hjson](https://github.com/hjson/hjson-js)
the option exit_on_interrupt determines whether an error should be thrown or the
process should exit when the user presses control + c in an interactive prompt.
```js
const reader = new InteractiveOptions([], {
args: true,
env: true,
interactive: true,
configs: ['json files to search for options'],
exit_on_interrupt: true, // exit when user cancels prompt
error_callback: (opt, val, err)=>{...} // function to call when an option value could not be read
});
```
## License ## License
MIT © Timo Hocker <timo@scode.ovh> MIT © Timo Hocker <timo@scode.ovh>

View File

@ -6,23 +6,24 @@
*/ */
import { TypeValidation } from './TypeValidation/TypeValidation'; import { TypeValidation } from './TypeValidation/TypeValidation';
import { ErrorCallback } from './ErrorCallback';
interface SourceConfig { interface SourceConfig {
console?: boolean, console?: boolean,
configs?: string[], configs?: string[],
env?: boolean,
interactive?: boolean, interactive?: boolean,
} }
interface Option { interface Option {
name: string; name: string;
required?: boolean;
default?: unknown; default?: unknown;
sources?: SourceConfig; sources?: SourceConfig;
alias?: string; alias?: string;
env?: string; env?: string;
message?: string; message?: string;
error?: string; error?: string;
error_callback?: ErrorCallback;
exit_on_interrupt?: boolean;
} }
class OptionValue { class OptionValue {
@ -33,6 +34,20 @@ class OptionValue {
public constructor (type_validation: TypeValidation) { public constructor (type_validation: TypeValidation) {
this.type_validation = type_validation; this.type_validation = type_validation;
} }
public async assign_arg (
opt: Option,
value: unknown
): Promise<void> {
try {
this.value = await this.type_validation.to_type (value);
this.filled = true;
}
catch (e) {
if (typeof opt.error_callback !== 'undefined')
opt.error_callback (opt.name, value, e);
}
}
} }
export { Option, OptionValue }; export { Option, OptionValue };

View File

@ -1,7 +1,6 @@
import { OptionSource } from '../Sources/OptionSource'; import { OptionSource } from '../Sources/OptionSource';
import { Option, OptionValue } from '../Option'; import { Option, OptionValue } from '../Option';
import { EnvSource } from '../Sources/EnvSource'; import { EnvSource } from '../Sources/EnvSource';
import { ErrorCallback } from '../ErrorCallback';
import { ArgSource } from '../Sources/ArgSource'; import { ArgSource } from '../Sources/ArgSource';
import { ConfigSource } from '../Sources/ConfigSource'; import { ConfigSource } from '../Sources/ConfigSource';
import { TypeValidation } from '../TypeValidation/TypeValidation'; import { TypeValidation } from '../TypeValidation/TypeValidation';
@ -12,26 +11,29 @@ export abstract class BaseOption<T> {
private _config: Option; private _config: Option;
public constructor ( public constructor (
config: Option, config: Option
error_callback?: ErrorCallback,
exit_on_interrupt = true
) { ) {
this._config = config; this._config = config;
const sources = config.sources || {}; const sources = config.sources || {};
if (typeof sources.configs !== 'undefined') const exit_on_interrupt = config.exit_on_interrupt !== false;
this.sources.push (new ConfigSource (sources.configs, error_callback));
if (sources.env !== false) if (typeof sources.configs !== 'undefined') {
this.sources.push (new EnvSource (error_callback)); this.sources.push (new ConfigSource (
sources.configs,
config.error_callback
));
}
this.sources.push (new EnvSource (config.error_callback));
if (sources.console !== false) if (sources.console !== false)
this.sources.push (new ArgSource (error_callback)); this.sources.push (new ArgSource (config.error_callback));
if (sources.interactive !== false) { if (sources.interactive !== false) {
this.sources.push (new InteractiveSource ( this.sources.push (new InteractiveSource (
exit_on_interrupt, exit_on_interrupt,
error_callback config.error_callback
)); ));
} }
} }

View File

@ -45,6 +45,6 @@ export class ArgSource extends OptionSource {
) )
return; return;
await this.assign_arg (opt, val, argv[opt.name]); await val.assign_arg (opt, argv[opt.name]);
} }
} }

View File

@ -64,6 +64,6 @@ export class ConfigSource extends OptionSource {
const keys = Object.keys (data); const keys = Object.keys (data);
if (keys.includes (opt.name)) if (keys.includes (opt.name))
await this.assign_arg (opt, val, data[opt.name]); await val.assign_arg (opt, data[opt.name]);
} }
} }

View File

@ -11,10 +11,20 @@ import { OptionSource } from './OptionSource';
export class EnvSource extends OptionSource { export class EnvSource extends OptionSource {
public async parse (opt: Option, val:OptionValue): Promise<void> { public async parse (opt: Option, val:OptionValue): Promise<void> {
if ( if (typeof opt.env === 'undefined')
typeof opt.env !== 'undefined' return;
&& typeof process.env[opt.env] !== 'undefined'
) if (typeof process.env[opt.env] === 'undefined') {
await this.assign_arg (opt, val, process.env[opt.env]); if (typeof this.error_callback !== 'undefined') {
this.error_callback (
opt.name,
null,
new Error ('environment variable does not exist')
);
}
return;
}
await val.assign_arg (opt, process.env[opt.env]);
} }
} }

View File

@ -0,0 +1,19 @@
import { List } from 'enquirer';
import { InteractiveSubSource } from './InteractiveSubSource';
export class ArraySubSource extends InteractiveSubSource {
protected condition ():boolean {
return this.val.type_validation.option_type === 'array';
}
protected async run ():Promise<void> {
await this.val.assign_arg (
this.opt,
await new List ({
message: this.get_message (),
default: this.opt.default
})
.run ()
);
}
}

View File

@ -0,0 +1,19 @@
import { Confirm } from 'enquirer';
import { InteractiveSubSource } from './InteractiveSubSource';
export class BooleanSubSource extends InteractiveSubSource {
protected condition ():boolean {
return this.val.type_validation.option_type === 'boolean';
}
protected async run ():Promise<void> {
await this.val.assign_arg (
this.opt,
await new Confirm ({
message: this.get_message (),
default: this.opt.default
})
.run ()
);
}
}

View File

@ -0,0 +1,34 @@
import { OptionValue, Option } from '../../Option';
export abstract class InteractiveSubSource {
protected val: OptionValue;
protected opt: Option;
protected abstract condition():boolean;
protected abstract async run():Promise<void>;
public constructor (
val:OptionValue,
opt:Option
) {
this.val = val;
this.opt = opt;
}
public async parse ():Promise<boolean> {
if (this.condition ()) {
await this.run ()
.catch ((e) => {
console.log (e);
});
return true;
}
return false;
}
protected get_message (): string {
return typeof this.opt.message === 'undefined'
? `input ${this.opt.name}`
: this.opt.message;
}
}

View File

@ -0,0 +1,25 @@
import { Prompt } from 'enquirer';
export class PathPrompt extends Prompt {
private _index = 0;
private _value = '';
public constructor (options:Record<string, unknown> = {}) {
super (options);
}
public up (): void {
this._index--;
this.render ();
}
public down (): void {
this._index++;
this.render ();
}
public render (): void {
this.clear ();
this.write (`${this.state.message}: ${this._value}`);
}
}

View File

@ -0,0 +1,23 @@
import { InteractiveSubSource } from './InteractiveSubSource';
import { PathPrompt } from './PathCustomPrompt';
export class PathSubSource extends InteractiveSubSource {
protected condition ():boolean {
return [
'path',
'file',
'folder'
].includes (this.val.type_validation.option_type);
}
protected async run (): Promise<void> {
await this.val.assign_arg (
this.opt,
await new PathPrompt ({
message: this.get_message (),
default: this.opt.default
})
.run ()
);
}
}

View File

@ -0,0 +1,22 @@
import { AutoComplete } from 'enquirer';
import { StringOptionConfig } from '../../SubConfigs';
import { InteractiveSubSource } from './InteractiveSubSource';
export class PresetSubSource extends InteractiveSubSource {
protected condition ():boolean {
return typeof (this.opt as StringOptionConfig).preset !== 'undefined';
}
protected async run ():Promise<void> {
await this.val.assign_arg (
this.opt,
await new AutoComplete ({
message: this.get_message (),
default: this.opt.default,
choices: (this.opt as StringOptionConfig).preset,
limit: 10
})
.run ()
);
}
}

View File

@ -0,0 +1,19 @@
import { Input } from 'enquirer';
import { InteractiveSubSource } from './InteractiveSubSource';
export class StringSubSource extends InteractiveSubSource {
protected condition ():boolean {
return true;
}
protected async run ():Promise<void> {
await this.val.assign_arg (
this.opt,
await new Input ({
message: this.get_message (),
default: this.opt.default
})
.run ()
);
}
}

View File

@ -0,0 +1,13 @@
import { ArraySubSource } from './ArraySubSource';
import { BooleanSubSource } from './BooleanSubSource';
import { PresetSubSource } from './PresetSubSource';
import { StringSubSource } from './StringSubSource';
import { PathSubSource } from './PathSubSource';
export const sources = [
ArraySubSource,
BooleanSubSource,
PresetSubSource,
PathSubSource,
StringSubSource
];

View File

@ -7,11 +7,10 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
/* eslint-disable no-process-exit */ /* eslint-disable no-process-exit */
import { Confirm, Input, List, AutoComplete } from 'enquirer';
import { ErrorCallback } from '../ErrorCallback'; import { ErrorCallback } from '../ErrorCallback';
import { Option, OptionValue } from '../Option'; import { Option, OptionValue } from '../Option';
import { StringOptionConfig } from '../SubConfigs';
import { OptionSource } from './OptionSource'; import { OptionSource } from './OptionSource';
import { sources } from './Interactive';
export class InteractiveSource extends OptionSource { export class InteractiveSource extends OptionSource {
private _exit_on_interrupt: boolean; private _exit_on_interrupt: boolean;
@ -24,62 +23,16 @@ export class InteractiveSource extends OptionSource {
this._exit_on_interrupt = exit_on_interrupt; 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> { private async prompt (opt: Option, val:OptionValue): Promise<void> {
if (val.filled) if (val.filled)
return; 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); for (const src of sources) {
// eslint-disable-next-line no-await-in-loop
if (await new src (val, opt)
.parse ())
break;
}
} }
public async parse (opt: Option, val:OptionValue): Promise<void> { public async parse (opt: Option, val:OptionValue): Promise<void> {

View File

@ -16,19 +16,4 @@ export abstract class OptionSource {
public constructor (error_callback?: ErrorCallback) { public constructor (error_callback?: ErrorCallback) {
this.error_callback = error_callback; this.error_callback = error_callback;
} }
protected async assign_arg (
opt: Option,
val: OptionValue,
value: unknown
): Promise<void> {
try {
val.value = await val.type_validation.to_type (value);
val.filled = true;
}
catch (e) {
if (typeof this.error_callback !== 'undefined')
this.error_callback (opt.name, value, e);
}
}
} }

View File

@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "es6",
"module": "commonjs", "module": "commonjs",
"outDir": "./dist", "outDir": "./dist",
"rootDir": "./", "rootDir": "./",

View File

@ -244,17 +244,17 @@
fastq "^1.6.0" fastq "^1.6.0"
"@sapphirecode/eslint-config-es6@^1.1.1": "@sapphirecode/eslint-config-es6@^1.1.1":
version "1.1.8" version "1.1.9"
resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config-es6/-/eslint-config-es6-1.1.8.tgz#87a92f4f20a3ee70ff8cd45a8d3c8ecf63b7e756" resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config-es6/-/eslint-config-es6-1.1.9.tgz#4bbd8350920d91fc201d28b15df72152e28d1c3e"
integrity sha512-75SFXxj+QMxHiE3oIpE19eqhHi1VKmKDyzb7WjaKFhnOmlsZGjfw19T3b59O3c2zGWznaDYpv2BzyPQYrFnqcQ== integrity sha512-ytJXXlXfIj+j75wjYqH5p+kymGr1UiqeQI3usSad+NXagspvlh7cdqcEmP9FH/+T84mNoISUhsU7rrHf1n+76g==
dependencies: dependencies:
"@sapphirecode/eslint-config" "^2.1.2" "@sapphirecode/eslint-config" "^2.1.2"
eslint-plugin-import "^2.20.2" eslint-plugin-import "^2.20.2"
"@sapphirecode/eslint-config-ts@^1.1.4": "@sapphirecode/eslint-config-ts@^1.1.4":
version "1.1.11" version "1.1.12"
resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config-ts/-/eslint-config-ts-1.1.11.tgz#d4346226904e48947dc61a846b8eb30940790842" resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config-ts/-/eslint-config-ts-1.1.12.tgz#6cedf13d638a55fd33e565b37a913ed042890687"
integrity sha512-dGSvxaR62AYUGFjdn9SS2WJaNQUdrWVH9tRGDLYjYSjK2PskFSuB4XwSVRoEz5ddPDB/mHfm/UDJ6ufqeXO+lw== integrity sha512-YXN4OwgBtGOalzURj6jwdWSdPBF5D6jFguJOKW2tx92h7iTwhcuR3N479L4E+42njfd9/ebTbmroLL55aME0Jg==
dependencies: dependencies:
"@sapphirecode/eslint-config-es6" "^1.1.1" "@sapphirecode/eslint-config-es6" "^1.1.1"
"@typescript-eslint/eslint-plugin" "^3.0.0" "@typescript-eslint/eslint-plugin" "^3.0.0"
@ -262,24 +262,24 @@
eslint-plugin-tsdoc "^0.2.4" eslint-plugin-tsdoc "^0.2.4"
"@sapphirecode/eslint-config@^2.1.2": "@sapphirecode/eslint-config@^2.1.2":
version "2.1.8" version "2.1.9"
resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config/-/eslint-config-2.1.8.tgz#b213fa1dcb8ac0deb0e7426627b1b75c7845864c" resolved "https://registry.yarnpkg.com/@sapphirecode/eslint-config/-/eslint-config-2.1.9.tgz#452b63609934a961fb2b6db4922766a88e282c56"
integrity sha512-Wv/91wep+JkZdPAV34iG56sTWtF+2K/Wx1rmz7hoXEbFPWQ5B9nQhv0WiU2PgppcPCySFdqijF459UeJCzxqJw== integrity sha512-VAg05Xwrmr4K2WIiJObXBKHVeaS47zHtsPK8AANHmqXJ8jHNn71d/Kerk5RjJ9mySiHvGOl0Z5n/HfFhXldGRQ==
dependencies: dependencies:
eslint-plugin-node "^11.1.0" eslint-plugin-node "^11.1.0"
eslint-plugin-sort-requires-by-path "^1.0.2" eslint-plugin-sort-requires-by-path "^1.0.2"
"@sapphirecode/modelling@^1.0.35": "@sapphirecode/modelling@^1.0.35":
version "1.1.1" version "1.1.2"
resolved "https://registry.yarnpkg.com/@sapphirecode/modelling/-/modelling-1.1.1.tgz#fa67779e3aa3fe267b64a3be7f2b6ee472bc3f1e" resolved "https://registry.yarnpkg.com/@sapphirecode/modelling/-/modelling-1.1.2.tgz#e352ace136928beac487bb4aa219fdb1bc65dcb6"
integrity sha512-/8xbn8DuXiL4HbmOGzEs1ClApTEnbRgf9ZhUyrlLjHwR0CPelKGuEcyZh02Zmv3LY0fx/RoEvLcXHZay24modw== integrity sha512-KSRAx6pHQnlFHu6EujuU+gawzD/9h/eeLcibra5uK4ME/elaQDNFudGx6OyKUPwJIwBmMyPCNsh5OVx3FVEucg==
dependencies: dependencies:
"@sapphirecode/utilities" "^1.3.2" "@sapphirecode/utilities" "^1.3.2"
"@sapphirecode/utilities@^1.3.2", "@sapphirecode/utilities@^1.3.4": "@sapphirecode/utilities@^1.3.2", "@sapphirecode/utilities@^1.3.4":
version "1.4.1" version "1.4.2"
resolved "https://registry.yarnpkg.com/@sapphirecode/utilities/-/utilities-1.4.1.tgz#3463136d2aa110f086317748fac7ad6a004d205e" resolved "https://registry.yarnpkg.com/@sapphirecode/utilities/-/utilities-1.4.2.tgz#4de5ecf469ced4c1aa74be3f5fe7cb276ee9e7a1"
integrity sha512-KGUzrt1dnFJ3PzF/CGKQyxS6GD34E55Vap8qmDjTNw/JHRLX9hiJbBGTOfBdQEZ43n+3HIfKlNZgXV0T992OSg== integrity sha512-igP6visCNNeFOQMleSqABqDeytsdlDA2gxHkIxD1dlISkKs21w/bnH1awiVIJcdVTSCgD2TQsUUPiz+Oo7caPA==
"@sindresorhus/is@^0.14.0": "@sindresorhus/is@^0.14.0":
version "0.14.0" version "0.14.0"
@ -324,9 +324,9 @@
integrity sha512-yXq/C73UHM8GQc6RYJnUXUgxudr2Q9227Iawhkp03YCnfJJTc+6LJnnVLx+UR/Dvw6imO5Q3vpGNmR9IRBI0JQ== integrity sha512-yXq/C73UHM8GQc6RYJnUXUgxudr2Q9227Iawhkp03YCnfJJTc+6LJnnVLx+UR/Dvw6imO5Q3vpGNmR9IRBI0JQ==
"@types/json-schema@^7.0.3": "@types/json-schema@^7.0.3":
version "7.0.4" version "7.0.5"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
"@types/json5@^0.0.29": "@types/json5@^0.0.29":
version "0.0.29" version "0.0.29"
@ -339,9 +339,9 @@
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/node@*": "@types/node@*":
version "14.0.12" version "14.0.13"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.12.tgz#9c1d8ffb8084e8936603a6122a7649e40e68e04b" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.13.tgz#ee1128e881b874c371374c1f72201893616417c9"
integrity sha512-/sjzehvjkkpvLpYtN6/2dv5kg41otMGuHQUt9T2aiAuIfleCQRQHXXzF1eAw/qkZTj5Kcf4JSTf7EIizHocy6Q== integrity sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.0" version "2.4.0"
@ -415,9 +415,9 @@ acorn-walk@^7.1.1:
integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ== integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==
acorn@^7.1.1, acorn@^7.2.0: acorn@^7.1.1, acorn@^7.2.0:
version "7.2.0" version "7.3.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd"
integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ== integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==
aggregate-error@^3.0.0: aggregate-error@^3.0.0:
version "3.0.1" version "3.0.1"
@ -1191,9 +1191,9 @@ eslint-plugin-es@^3.0.0:
regexpp "^3.0.0" regexpp "^3.0.0"
eslint-plugin-import@^2.20.2: eslint-plugin-import@^2.20.2:
version "2.21.1" version "2.21.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.1.tgz#3398318e5e4abbd23395c4964ce61538705154c8" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz#8fef77475cc5510801bedc95f84b932f7f334a7c"
integrity sha512-qYOOsgUv63vHof7BqbzuD+Ud34bXHxFJxntuAC1ZappFZXYbRIek3aJ7jc9i2dHDGDyZ/0zlO0cpioES265Lsw== integrity sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA==
dependencies: dependencies:
array-includes "^3.1.1" array-includes "^3.1.1"
array.prototype.flat "^1.2.3" array.prototype.flat "^1.2.3"