From 4b1ac53f54e24297d9c0c2f7049d765e7e4def8f Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 8 Nov 2022 12:55:12 -0600 Subject: [PATCH 1/7] [website] Add scroll-padding-top --- website/docs/src/styles/_global.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/docs/src/styles/_global.scss b/website/docs/src/styles/_global.scss index 1f194f0559d..c7370bd65a0 100644 --- a/website/docs/src/styles/_global.scss +++ b/website/docs/src/styles/_global.scss @@ -172,3 +172,11 @@ a, .link { fill: var(--font-color); } } + +html { + scroll-padding-top: 80px; + + @include mobile-only { + scroll-padding-top: 64px; + } +} From 3afc0955640b171720e2bdf4b67313723fcad23b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Tue, 8 Nov 2022 12:55:16 -0600 Subject: [PATCH 2/7] Remove dead styles --- website/docs/src/styles/_homepage.scss | 598 ------------------------- website/docs/src/styles/index.scss | 1 - 2 files changed, 599 deletions(-) delete mode 100644 website/docs/src/styles/_homepage.scss diff --git a/website/docs/src/styles/_homepage.scss b/website/docs/src/styles/_homepage.scss deleted file mode 100644 index 78e3f2022f8..00000000000 --- a/website/docs/src/styles/_homepage.scss +++ /dev/null @@ -1,598 +0,0 @@ -@import "_variables"; -@import "_mixins"; - -@keyframes homepage-hero-fade-out { - 0% { - opacity: 1; - line-height: 86px; - } - - 100% { - opacity: 0; - line-height: 100px; - } -} - -@keyframes homepage-hero-fade-in { - 0% { - opacity: 0; - line-height: 100px; - } - - 100% { - opacity: 1; - line-height: 86px; - } -} - -.homepage { - text-align: center; - width: 100%; - - .h1, h1, h2 { - font-weight: 700; - margin-bottom: 40px; - padding: 0 20px; - } - - .h1, h1 { - font-size: 96px; - line-height: 100%; - margin-top: 60px; - - @include small-screen-only { - font-size: 72px; - } - - @include mobile-only { - font-size: 64px; - } - - @include dark-mode { - color: #fff; - } - - li { - line-height: 86px; - opacity: 1; - } - - ul { - height: 86px; - } - - .fadeout { - animation: homepage-hero-fade-out 0.3s ease-out; - } - - .fadein { - animation: homepage-hero-fade-in 0.3s ease-in; - } - - .formatter { - color: #f4c649; - } - - .linter { - color: #51DBE4; - } - } - - h2 { - font-size: 48px; - line-height: 140%; - - @include mobile-only { - font-size: 42px; - } - } - - .founder-clout { - line-height: 30px; - margin-top: 20px; - margin-bottom: 40px; - - svg { - vertical-align: middle; - } - - .yarn svg { - height: 26px; - margin: 0 4px; - } - - .babel svg { - height: 30px; - } - - .meet-our-team { - opacity: 0.6; - } - } - - hr { - opacity: 0.1; - border: none; - border-top: 1px solid #0C0C0D; - max-width: 800px; - margin: 40px auto; - - @include dark-mode { - border-color: #fff; - opacity: 0.2; - } - - &.half { - margin-top: 20px; - } - - &.full { - max-width: 100%; - } - } - - a.button { - margin-bottom: 40px; - } - - p { - line-height: 150%; - font-size: 16px; - } - - section > p { - padding: 0 20px; - } - - ul.supported-languages { - margin-top: 50px; - font-size: 12px; - display: flex; - flex-direction: row; - justify-content: center; - flex-wrap: wrap; - - li { - display: inline-block; - margin: 0 26px; - margin-bottom: 20px; - - &.soon { - color: #ADB5BD; - } - } - - .icon { - display: flex; - align-items: center; - justify-content: center; - height: 30px; - margin-bottom: 30px; - } - - .soon-indicator { - margin: 0 auto; - margin-top: 6px; - } - } - - .soon-indicator { - display: inline-block; - color: #0C0C0D; - background: #F1F3F5; - border-radius: 20px; - padding: 1px 6px; - font-size: 12px; - line-height: 14px; - - @include dark-mode { - background: $gray-4; - color: #F1F3F5; - } - } - - .component-list { - display: flex; - flex-direction: row; - justify-content: center; - margin-bottom: 20px; - - li { - margin: 0 20px; - padding: 10px 0; - line-height: 140%; - - &.active { - border-bottom: 1px solid var(--font-color); - } - - &:not(.soon) { - cursor: pointer; - } - } - - .text { - display: inline-block; - margin-right: 4px; - } - - .soon { - color: #ADB5BD; - - @include mobile-only { - display: none; - } - } - } - - .features { - display: flex; - flex-wrap: wrap; - margin-top: 20px; - - li { - text-align: left; - width: 50%; - margin-bottom: 80px; - font-size: 16px; - line-height: 140%; - padding-left: 56px; - position: relative; - padding-right: 48px; - } - - svg { - position: absolute; - left: 0; - top: 0; - width: 24px; - height: 24px; - } - - h3 { - font-weight: 500; - font-size: 20px; - margin-bottom: 12px; - } - - @include mobile-only { - margin-left: 30px; - - li { - width: 100%; - } - } - } - - .supercharge .heading-tagline { - margin: 0 auto; - margin-bottom: 30px; - max-width: 600px; - } - - .try-rome { - background: #F8F9FA; - border-radius: 16px; - font-size: 16px; - line-height: 140%; - text-align: left; - padding: 70px 90px; - position: relative; - overflow: hidden; - - @include dark-mode { - background-color: var(--container-color); - } - - h2 { - font-weight: 700; - font-size: 48px; - margin-bottom: 20px; - padding: 0; - } - - p { - margin-bottom: 40px; - max-width: 400px; - padding: 0; - } - - .button { - width: auto; - } - - a { - text-decoration: none; - } - - .vscode-button.button { - margin-bottom: 20px; - } - - .install-button { - margin-bottom: 30px; - } - - .window { - position: absolute; - background-color: #FFFFFF; - box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.04), 0px 10px 50px rgba(17, 17, 17, 0.1); - border-radius: 12px; - width: 485px; - height: 410px; - border: 1px solid #D4D4D4; - - @include dark-mode { - background-color: #282c34; - border-color: #222; - } - } - - .console-window { - right: 135px; - bottom: -69px; - padding: 30px; - font-family: $code-font; - font-size: 14px; - - .shell-symbol { - color: #ADB5BD; - } - - .rome { - color: #E67700; - } - - .command { - margin-bottom: 20px; - } - } - - .vscode-window { - right: -145px; - bottom: -19px; - background-image: url("/img/homepage-vscode-screenshot-light.png"); - background-size: 215%; - background-repeat: no-repeat; - - @include dark-mode { - background-image: url("/img/homepage-vscode-screenshot-dark.png"); - } - } - - @media only screen and (max-width: 1120px) { - padding: 40px; - padding-bottom: 200px; - border-radius: 0; - margin: 0 -20px; - } - - @media only screen and (max-width: 960px) { - padding-bottom: 400px; - - .console-window { - border-radius: 0; - left: 0; - right: auto; - } - - .vscode-window { - left: 300px; - right: auto; - } - } - } - - .component-window { - display: flex; - flex-direction: row; - text-align: left; - line-height: 150%; - - overflow: hidden; - background: #FFFFFF; - width: 100%; - height: 480px; - margin-bottom: 65px; - box-shadow: 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 4px 20px rgba(0, 0, 0, 0.04), 0px 10px 50px rgba(17, 17, 17, 0.1); - - border-radius: 16px; - border: 1px solid #D4D4D4; - - @include mobile-only { - border-radius: 0; - flex-direction: column; - border-left: none; - border-right: none; - height: auto; - margin-bottom: 30px; - margin-left: -20px; - margin-right: -20px; - - pre.language-js { - height: 200px; - } - - .code, .output { - border-right: none; - border-bottom: 1px solid #E9ECEF; - } - } - - @include dark-mode { - background: darken(#282c34, 5%); - border-color: #222; - } - - pre { - padding: 0; - background: none; - font-size: 12px; - overflow: auto; - height: 100%; - } - - .code, .output, .performance { - width: 100%; - min-width: 100px; - padding: 22px 24px; - flex-basis: 0px; - flex-grow: 1; - display: flex; - flex-direction: column; - } - - .code, .output { - border-right: 1px solid #E9ECEF; - - @include dark-mode { - border-color: var(--soft-border-color); - } - } - - code { - color: #666; - - @include dark-mode { - color: rgb(171, 178, 191); - } - } - - h4 { - text-transform: uppercase; - margin-bottom: 16px; - font-family: $code-font; - font-weight: 500; - font-size: 12px; - } - - .code h4 { - color: #F03E3E; - } - - .output h4 { - color: #4263EB; - } - - .performance { - background: #F8F9FA; - font-family: $code-font; - - @include dark-mode { - background-color: var(--container-color); - } - - @include mobile-only { - padding-bottom: 40px; - } - - h4 { - color: #868E96; - margin-bottom: 40px; - } - - .progress { - margin-bottom: 50px; - height: 18px; - width: 100%; - background-color: #E9ECEF; - flex-shrink: 0; - - @include dark-mode { - background-color: rgba(255, 255, 255, 0.2); - } - - .progress-bar { - height: 100%; - } - } - - .spreader { - height: 100%; - } - - .multiplier { - font-size: 36px; - margin-bottom: 10px; - - @include mobile-only { - margin-top: 0; - } - } - - .progress-header { - color: #868E96; - margin-bottom: 12px; - } - - .tool-name { - color: #0C0C0D; - - @include dark-mode { - color: #fff; - } - } - - .progress-bar-good { - background-color: #40C057; - } - - .progress-bar-bad { - background-color: #F03E3E; - - &.transition { - transition: homepage-prettier-progress 9.8s linear; - transition-property: width; - } - } - - .timer-running { - opacity: 0.6; - } - - .time-bad-timer::after { - color: inherit; - content: " / "; - color: #868e96; - } - - .time-good { - color: #40C057; - } - - .time-bad { - color: #F03E3E; - } - - @include dark-mode { - .progress-bar-good { - background-color: saturate(#40C057, 10%); - } - - .progress-bar-bad { - background-color: saturate(#F03E3E, 10%); - } - - .time-good { - color: saturate(#40C057, 10%); - } - - .time-bad { - color: saturate(#F03E3E, 10%); - } - } - } - } - - .component-window-linter { - .code { - min-width: 350px; - flex-grow: 0; - } - - .output { - flex-grow: 1; - border-right: none; - } - } -} diff --git a/website/docs/src/styles/index.scss b/website/docs/src/styles/index.scss index 306750c16ae..600171e9560 100644 --- a/website/docs/src/styles/index.scss +++ b/website/docs/src/styles/index.scss @@ -6,7 +6,6 @@ @import "_prism"; @import "_grid"; @import "_content"; -@import "_homepage"; @import "_footer"; @import "_credits"; @import "_buttons"; From 903a3ed64755513f97a23d56f1bccad9c9face8e Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 9 Nov 2022 08:30:03 +0100 Subject: [PATCH 3/7] fix(rome_cli): Respect formatter/linter `enabled` from configuration (#3591) --- crates/rome_cli/src/commands/ci.rs | 8 +++- crates/rome_cli/tests/commands/ci.rs | 37 +++++++++++-------- .../ci_does_not_run_formatter.snap | 24 +----------- .../ci_does_not_run_formatter_via_cli.snap | 24 +----------- 4 files changed, 29 insertions(+), 64 deletions(-) diff --git a/crates/rome_cli/src/commands/ci.rs b/crates/rome_cli/src/commands/ci.rs index 1e34d52968d..93d6be235d7 100644 --- a/crates/rome_cli/src/commands/ci.rs +++ b/crates/rome_cli/src/commands/ci.rs @@ -31,13 +31,17 @@ pub(crate) fn ci(mut session: CliSession) -> Result<(), Termination> { .formatter .get_or_insert_with(FormatterConfiguration::default); - formatter.enabled = formatter_enabled.unwrap_or(true); + if let Some(formatter_enabled) = formatter_enabled { + formatter.enabled = formatter_enabled; + } let linter = configuration .linter .get_or_insert_with(LinterConfiguration::default); - linter.enabled = linter_enabled.unwrap_or(true); + if let Some(linter_enabled) = linter_enabled { + linter.enabled = linter_enabled; + } // no point in doing the traversal if all the checks have been disabled if configuration.is_formatter_disabled() && configuration.is_linter_disabled() { diff --git a/crates/rome_cli/tests/commands/ci.rs b/crates/rome_cli/tests/commands/ci.rs index 95c3c89dfa5..1f292481d60 100644 --- a/crates/rome_cli/tests/commands/ci.rs +++ b/crates/rome_cli/tests/commands/ci.rs @@ -160,29 +160,32 @@ fn ci_does_not_run_formatter() { let mut fs = MemoryFileSystem::default(); let mut console = BufferConsole::default(); - let file_path = Path::new("rome.json"); - fs.insert(file_path.into(), CONFIG_DISABLED_FORMATTER.as_bytes()); + fs.insert( + PathBuf::from("rome.json"), + CONFIG_DISABLED_FORMATTER.as_bytes(), + ); - let file_path = Path::new("file.js"); - fs.insert(file_path.into(), UNFORMATTED_AND_INCORRECT.as_bytes()); + let input_file = Path::new("file.js"); + + fs.insert(input_file.into(), UNFORMATTED.as_bytes()); let result = run_cli( DynRef::Borrowed(&mut fs), DynRef::Borrowed(&mut console), - Arguments::from_vec(vec![OsString::from("ci"), file_path.as_os_str().into()]), + Arguments::from_vec(vec![OsString::from("ci"), input_file.as_os_str().into()]), ); - assert!(result.is_err(), "run_cli returned {result:?}"); + assert!(result.is_ok(), "run_cli returned {result:?}"); let mut file = fs - .open(file_path) + .open(input_file) .expect("formatting target file was removed by the CLI"); let mut content = String::new(); file.read_to_string(&mut content) .expect("failed to read file from memory FS"); - assert_eq!(content, UNFORMATTED_AND_INCORRECT); + assert_eq!(content, UNFORMATTED); drop(file); assert_cli_snapshot(SnapshotPayload::new( @@ -199,8 +202,8 @@ fn ci_does_not_run_formatter_via_cli() { let mut fs = MemoryFileSystem::default(); let mut console = BufferConsole::default(); - let file_path = Path::new("file.js"); - fs.insert(file_path.into(), UNFORMATTED_AND_INCORRECT.as_bytes()); + let input_file = Path::new("file.js"); + fs.insert(input_file.into(), UNFORMATTED.as_bytes()); let result = run_cli( DynRef::Borrowed(&mut fs), @@ -208,21 +211,21 @@ fn ci_does_not_run_formatter_via_cli() { Arguments::from_vec(vec![ OsString::from("ci"), OsString::from("--formatter-enabled=false"), - file_path.as_os_str().into(), + input_file.as_os_str().into(), ]), ); - assert!(result.is_err(), "run_cli returned {result:?}"); + assert!(result.is_ok(), "run_cli returned {result:?}"); let mut file = fs - .open(file_path) + .open(input_file) .expect("formatting target file was removed by the CLI"); let mut content = String::new(); file.read_to_string(&mut content) .expect("failed to read file from memory FS"); - assert_eq!(content, UNFORMATTED_AND_INCORRECT); + assert_eq!(content, UNFORMATTED); drop(file); assert_cli_snapshot(SnapshotPayload::new( @@ -239,8 +242,10 @@ fn ci_does_not_run_linter() { let mut fs = MemoryFileSystem::default(); let mut console = BufferConsole::default(); - let file_path = Path::new("rome.json"); - fs.insert(file_path.into(), CONFIG_LINTER_DISABLED.as_bytes()); + fs.insert( + PathBuf::from("rome.json"), + CONFIG_LINTER_DISABLED.as_bytes(), + ); let file_path = Path::new("file.js"); fs.insert(file_path.into(), CUSTOM_FORMAT_BEFORE.as_bytes()); diff --git a/crates/rome_cli/tests/snapshots/main_commands_ci/ci_does_not_run_formatter.snap b/crates/rome_cli/tests/snapshots/main_commands_ci/ci_does_not_run_formatter.snap index 4439425e262..ad13a9742ad 100644 --- a/crates/rome_cli/tests/snapshots/main_commands_ci/ci_does_not_run_formatter.snap +++ b/crates/rome_cli/tests/snapshots/main_commands_ci/ci_does_not_run_formatter.snap @@ -16,31 +16,9 @@ expression: content ## `file.js` ```js -statement( ) ; let a = !b || !c; -``` - -# Termination Message - -```block -errors where emitted while running checks + statement( ) ``` # Emitted Messages -```block -file.js:1:27 lint/complexity/useSimplifiedLogicExpression FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × Logical expression contains unnecessary complexity. - - > 1 │ statement( ) ; let a = !b || !c; - │ ^^^^^^^^ - - i Suggested fix: Reduce the complexity of the logical expression. - - - statement(····)·;·let·a·=·!b·||·!c; - + statement(····)·;·let·a·=·!(b·&&·c); - - -``` - diff --git a/crates/rome_cli/tests/snapshots/main_commands_ci/ci_does_not_run_formatter_via_cli.snap b/crates/rome_cli/tests/snapshots/main_commands_ci/ci_does_not_run_formatter_via_cli.snap index b355bacab90..1d965d4d614 100644 --- a/crates/rome_cli/tests/snapshots/main_commands_ci/ci_does_not_run_formatter_via_cli.snap +++ b/crates/rome_cli/tests/snapshots/main_commands_ci/ci_does_not_run_formatter_via_cli.snap @@ -5,31 +5,9 @@ expression: content ## `file.js` ```js -statement( ) ; let a = !b || !c; -``` - -# Termination Message - -```block -errors where emitted while running checks + statement( ) ``` # Emitted Messages -```block -file.js:1:27 lint/complexity/useSimplifiedLogicExpression FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × Logical expression contains unnecessary complexity. - - > 1 │ statement( ) ; let a = !b || !c; - │ ^^^^^^^^ - - i Suggested fix: Reduce the complexity of the logical expression. - - - statement(····)·;·let·a·=·!b·||·!c; - + statement(····)·;·let·a·=·!(b·&&·c); - - -``` - From 50dbe6842635b4f422cc82be02e2d012e682c5fa Mon Sep 17 00:00:00 2001 From: l3ops Date: Wed, 9 Nov 2022 09:38:54 +0100 Subject: [PATCH 4/7] fix(rome_cli): correctly account for diff diagnostics in the printed diagnostics count (#3595) * fix(rome_cli): correctly account for diff diagnostics in the printed diagnostics count * add tests --- crates/rome_cli/src/commands/check.rs | 28 +------- crates/rome_cli/src/commands/help.rs | 6 +- crates/rome_cli/src/execute.rs | 49 +++++++++++--- crates/rome_cli/src/traversal.rs | 85 +++++++++++++++--------- crates/rome_cli/tests/commands/check.rs | 53 +++++++++++++++ crates/rome_cli/tests/commands/ci.rs | 53 +++++++++++++++ crates/rome_cli/tests/commands/format.rs | 47 +++++++++++++ 7 files changed, 248 insertions(+), 73 deletions(-) diff --git a/crates/rome_cli/src/commands/check.rs b/crates/rome_cli/src/commands/check.rs index 7dd60c9d8c9..ad8392c185a 100644 --- a/crates/rome_cli/src/commands/check.rs +++ b/crates/rome_cli/src/commands/check.rs @@ -1,35 +1,12 @@ use crate::commands::format::apply_format_settings_from_cli; use crate::configuration::load_configuration; use crate::{execute_mode, CliSession, Execution, Termination, TraversalMode}; -use rome_diagnostics::MAXIMUM_DISPLAYABLE_DIAGNOSTICS; use rome_service::workspace::{FixFileMode, UpdateSettingsParams}; /// Handler for the "check" command of the Rome CLI pub(crate) fn check(mut session: CliSession) -> Result<(), Termination> { let mut configuration = load_configuration(&mut session)?; - let max_diagnostics: Option = session - .args - .opt_value_from_str("--max-diagnostics") - .map_err(|source| Termination::ParseError { - argument: "--max-diagnostics", - source, - })?; - - let max_diagnostics = if let Some(max_diagnostics) = max_diagnostics { - if max_diagnostics > MAXIMUM_DISPLAYABLE_DIAGNOSTICS { - return Err(Termination::OverflowNumberArgument( - "--max-diagnostics", - MAXIMUM_DISPLAYABLE_DIAGNOSTICS, - )); - } - - max_diagnostics - } else { - // default value - 20 - }; - apply_format_settings_from_cli(&mut session, &mut configuration)?; session @@ -54,10 +31,7 @@ pub(crate) fn check(mut session: CliSession) -> Result<(), Termination> { }; execute_mode( - Execution::new(TraversalMode::Check { - max_diagnostics, - fix_file_mode, - }), + Execution::new(TraversalMode::Check { fix_file_mode }), session, ) } diff --git a/crates/rome_cli/src/commands/help.rs b/crates/rome_cli/src/commands/help.rs index 70b4f492895..70817f7da60 100644 --- a/crates/rome_cli/src/commands/help.rs +++ b/crates/rome_cli/src/commands/help.rs @@ -61,7 +61,8 @@ const CI: Markup = markup! { ""OPTIONS:"" ""--formatter-enabled"" Allow to enable or disable the formatter check. (default: true) - ""--linter-enabled"" Allow to enable or disable the linter check. (default: true)" + ""--linter-enabled"" Allow to enable or disable the linter check. (default: true) + ""--max-diagnostics"" Cap the amount of diagnostics displayed (default: 50)" {FORMAT_OPTIONS} }; @@ -75,7 +76,8 @@ const FORMAT: Markup = markup! { ""OPTIONS:"" ""--write"" Edit the files in place (beware!) instead of printing the diff to the console - ""--skip-errors"" Skip over files containing syntax errors instead of emitting an error diagnostic." + ""--skip-errors"" Skip over files containing syntax errors instead of emitting an error diagnostic. + ""--max-diagnostics"" Cap the amount of diagnostics displayed (default: 50)" {FORMAT_OPTIONS} """--stdin-file-path "" A file name with its extension to pass when reading from standard in, e.g. echo 'let a;' | rome format --stdin-file-path file.js " diff --git a/crates/rome_cli/src/execute.rs b/crates/rome_cli/src/execute.rs index e557b11ea8c..7937557dfcf 100644 --- a/crates/rome_cli/src/execute.rs +++ b/crates/rome_cli/src/execute.rs @@ -2,6 +2,7 @@ use crate::traversal::traverse; use crate::{CliSession, Termination}; use rome_console::{markup, ConsoleExt}; use rome_diagnostics::file::FileId; +use rome_diagnostics::MAXIMUM_DISPLAYABLE_DIAGNOSTICS; use rome_fs::RomePath; use rome_service::workspace::{ FeatureName, FixFileMode, FormatFileParams, Language, OpenFileParams, SupportsFeatureParams, @@ -15,14 +16,14 @@ pub(crate) struct Execution { /// The modality of execution of the traversal traversal_mode: TraversalMode, + + /// The maximum number of diagnostics that can be printed in console + max_diagnostics: u16, } pub(crate) enum TraversalMode { /// This mode is enabled when running the command `rome check` Check { - /// The maximum number of diagnostics that can be printed in console - max_diagnostics: u16, - /// The type of fixes that should be applied when analyzing a file. /// /// It's [None] if the `check` command is called without `--apply` or `--apply-suggested` @@ -59,6 +60,7 @@ impl Execution { Self { report_mode: ReportMode::default(), traversal_mode: mode, + max_diagnostics: MAXIMUM_DISPLAYABLE_DIAGNOSTICS, } } @@ -67,6 +69,7 @@ impl Execution { Self { traversal_mode, report_mode, + max_diagnostics: MAXIMUM_DISPLAYABLE_DIAGNOSTICS, } } @@ -79,13 +82,8 @@ impl Execution { &self.traversal_mode } - pub(crate) fn get_max_diagnostics(&self) -> Option { - match self.traversal_mode { - TraversalMode::Check { - max_diagnostics, .. - } => Some(max_diagnostics), - _ => None, - } + pub(crate) fn get_max_diagnostics(&self) -> u16 { + self.max_diagnostics } /// `true` only when running the traversal in [TraversalMode::Check] and `should_fix` is `true` @@ -128,7 +126,36 @@ impl Execution { /// Based on the [mode](ExecutionMode), the function might launch a traversal of the file system /// or handles the stdin file. -pub(crate) fn execute_mode(mode: Execution, mut session: CliSession) -> Result<(), Termination> { +pub(crate) fn execute_mode( + mut mode: Execution, + mut session: CliSession, +) -> Result<(), Termination> { + let max_diagnostics: Option = session + .args + .opt_value_from_str("--max-diagnostics") + .map_err(|source| Termination::ParseError { + argument: "--max-diagnostics", + source, + })?; + + mode.max_diagnostics = if let Some(max_diagnostics) = max_diagnostics { + if max_diagnostics > MAXIMUM_DISPLAYABLE_DIAGNOSTICS { + return Err(Termination::OverflowNumberArgument( + "--max-diagnostics", + MAXIMUM_DISPLAYABLE_DIAGNOSTICS, + )); + } + + max_diagnostics + } else { + // The command `rome check` gives a default value of 20. + // In case of other commands that pass here, we limit to 50 to avoid to delay the terminal. + match &mode.traversal_mode { + TraversalMode::Check { .. } => 20, + TraversalMode::CI | TraversalMode::Format { .. } => 50, + } + }; + // don't do any traversal if there's some content coming from stdin if let Some((path, content)) = mode.as_stdin_file() { let workspace = &*session.app.workspace; diff --git a/crates/rome_cli/src/traversal.rs b/crates/rome_cli/src/traversal.rs index 3ae79e915c1..822c4a4514b 100644 --- a/crates/rome_cli/src/traversal.rs +++ b/crates/rome_cli/src/traversal.rs @@ -15,7 +15,6 @@ use rome_diagnostics::{ category, Advices, Category, DiagnosticExt, Error, FilePath, PrintDescription, PrintDiagnostic, Severity, Visit, }, - MAXIMUM_DISPLAYABLE_DIAGNOSTICS, }; use rome_fs::{AtomicInterner, FileSystem, OpenOptions, PathInterner, RomePath}; use rome_fs::{TraversalContext, TraversalScope}; @@ -83,13 +82,7 @@ pub(crate) fn traverse(execution: Execution, mut session: CliSession) -> Result< let workspace = &*session.app.workspace; let console = &mut *session.app.console; - // The command `rome check` gives a default value of 20. - // In case of other commands that pass here, we limit to 50 to avoid to delay the terminal. - // Once `--max-diagnostics` will be a global argument, `unwrap_of_default` should be enough. - let max_diagnostics = execution - .get_max_diagnostics() - .unwrap_or(MAXIMUM_DISPLAYABLE_DIAGNOSTICS); - + let max_diagnostics = execution.get_max_diagnostics(); let remaining_diagnostics = AtomicU16::new(max_diagnostics); let mut has_errors = false; @@ -382,10 +375,23 @@ fn process_messages(options: ProcessMessagesOptions) { } } + let should_print = printed_diagnostics < max_diagnostics; + if should_print { + printed_diagnostics += 1; + remaining_diagnostics.store( + max_diagnostics.saturating_sub(printed_diagnostics), + Ordering::Relaxed, + ); + } else { + not_printed_diagnostics += 1; + } + if mode.should_report_to_terminal() { - console.error(markup! { - {PrintDiagnostic(&err)} - }); + if should_print { + console.error(markup! { + {PrintDiagnostic(&err)} + }); + } } else { let file_name = err .location() @@ -478,31 +484,44 @@ fn process_messages(options: ProcessMessagesOptions) { *has_errors = true; } + let should_print = printed_diagnostics < max_diagnostics; + if should_print { + printed_diagnostics += 1; + remaining_diagnostics.store( + max_diagnostics.saturating_sub(printed_diagnostics), + Ordering::Relaxed, + ); + } else { + not_printed_diagnostics += 1; + } + if mode.should_report_to_terminal() { - if mode.is_ci() { - let diag = CIDiffDiagnostic { - file_name: &file_name, - diff: FormatDiffAdvice { - old: &old, - new: &new, - }, - }; + if should_print { + if mode.is_ci() { + let diag = CIDiffDiagnostic { + file_name: &file_name, + diff: FormatDiffAdvice { + old: &old, + new: &new, + }, + }; - console.error(markup! { - {PrintDiagnostic(&diag)} - }); - } else { - let diag = FormatDiffDiagnostic { - file_name: &file_name, - diff: FormatDiffAdvice { - old: &old, - new: &new, - }, - }; + console.error(markup! { + {PrintDiagnostic(&diag)} + }); + } else { + let diag = FormatDiffDiagnostic { + file_name: &file_name, + diff: FormatDiffAdvice { + old: &old, + new: &new, + }, + }; - console.error(markup! { - {PrintDiagnostic(&diag)} - }); + console.error(markup! { + {PrintDiagnostic(&diag)} + }); + } } } else { report.push_detail_report(ReportKind::Error( diff --git a/crates/rome_cli/tests/commands/check.rs b/crates/rome_cli/tests/commands/check.rs index f8f504fe624..03ed983ae64 100644 --- a/crates/rome_cli/tests/commands/check.rs +++ b/crates/rome_cli/tests/commands/check.rs @@ -777,3 +777,56 @@ fn files_max_size_parse_error() { result, )); } + +#[test] +fn max_diagnostics_default() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + for i in 0..60 { + let file_path = PathBuf::from(format!("src/file_{i}.js")); + fs.insert(file_path, LINT_ERROR.as_bytes()); + } + + let result = run_cli( + DynRef::Borrowed(&mut fs), + DynRef::Borrowed(&mut console), + Arguments::from_vec(vec![OsString::from("check"), OsString::from("src")]), + ); + + match result { + Err(Termination::CheckError) => {} + _ => panic!("run_cli returned {result:?} for a failed CI check, expected an error"), + } + + assert_eq!(console.out_buffer.len(), 21); +} + +#[test] +fn max_diagnostics() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + for i in 0..60 { + let file_path = PathBuf::from(format!("src/file_{i}.js")); + fs.insert(file_path, LINT_ERROR.as_bytes()); + } + + let result = run_cli( + DynRef::Borrowed(&mut fs), + DynRef::Borrowed(&mut console), + Arguments::from_vec(vec![ + OsString::from("check"), + OsString::from("--max-diagnostics"), + OsString::from("10"), + Path::new("src").as_os_str().into(), + ]), + ); + + match result { + Err(Termination::CheckError) => {} + _ => panic!("run_cli returned {result:?} for a failed CI check, expected an error"), + } + + assert_eq!(console.out_buffer.len(), 11); +} diff --git a/crates/rome_cli/tests/commands/ci.rs b/crates/rome_cli/tests/commands/ci.rs index 1f292481d60..667caf5570e 100644 --- a/crates/rome_cli/tests/commands/ci.rs +++ b/crates/rome_cli/tests/commands/ci.rs @@ -516,3 +516,56 @@ fn ci_runs_linter_not_formatter_issue_3495() { result, )); } + +#[test] +fn max_diagnostics_default() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + for i in 0..60 { + let file_path = PathBuf::from(format!("src/file_{i}.js")); + fs.insert(file_path, UNFORMATTED.as_bytes()); + } + + let result = run_cli( + DynRef::Borrowed(&mut fs), + DynRef::Borrowed(&mut console), + Arguments::from_vec(vec![OsString::from("ci"), OsString::from("src")]), + ); + + match result { + Err(Termination::CheckError) => {} + _ => panic!("run_cli returned {result:?} for a failed CI check, expected an error"), + } + + assert_eq!(console.out_buffer.len(), 51); +} + +#[test] +fn max_diagnostics() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + for i in 0..60 { + let file_path = PathBuf::from(format!("src/file_{i}.js")); + fs.insert(file_path, UNFORMATTED.as_bytes()); + } + + let result = run_cli( + DynRef::Borrowed(&mut fs), + DynRef::Borrowed(&mut console), + Arguments::from_vec(vec![ + OsString::from("ci"), + OsString::from("--max-diagnostics"), + OsString::from("10"), + OsString::from("src"), + ]), + ); + + match result { + Err(Termination::CheckError) => {} + _ => panic!("run_cli returned {result:?} for a failed CI check, expected an error"), + } + + assert_eq!(console.out_buffer.len(), 11); +} diff --git a/crates/rome_cli/tests/commands/format.rs b/crates/rome_cli/tests/commands/format.rs index a5fc0359b3b..16fe0ffc88c 100644 --- a/crates/rome_cli/tests/commands/format.rs +++ b/crates/rome_cli/tests/commands/format.rs @@ -1153,3 +1153,50 @@ fn files_max_size_parse_error() { result, )); } + +#[test] +fn max_diagnostics_default() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + for i in 0..60 { + let file_path = PathBuf::from(format!("src/file_{i}.js")); + fs.insert(file_path, UNFORMATTED.as_bytes()); + } + + let result = run_cli( + DynRef::Borrowed(&mut fs), + DynRef::Borrowed(&mut console), + Arguments::from_vec(vec![OsString::from("format"), OsString::from("src")]), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_eq!(console.out_buffer.len(), 52); +} + +#[test] +fn max_diagnostics() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + for i in 0..60 { + let file_path = PathBuf::from(format!("src/file_{i}.js")); + fs.insert(file_path, UNFORMATTED.as_bytes()); + } + + let result = run_cli( + DynRef::Borrowed(&mut fs), + DynRef::Borrowed(&mut console), + Arguments::from_vec(vec![ + OsString::from("format"), + OsString::from("--max-diagnostics"), + OsString::from("10"), + OsString::from("src"), + ]), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_eq!(console.out_buffer.len(), 12); +} From 99f59bf7c2592390fdfd943f2f42aa65ee014859 Mon Sep 17 00:00:00 2001 From: l3ops Date: Wed, 9 Nov 2022 11:59:40 +0100 Subject: [PATCH 5/7] feat(vscode): display the version of the language server in the status bar (#3616) --- editors/vscode/package-lock.json | 4 +- editors/vscode/src/main.ts | 6 +- editors/vscode/src/statusBar.ts | 14 +++- editors/vscode/src/status_bar.ts | 115 ------------------------------- 4 files changed, 17 insertions(+), 122 deletions(-) delete mode 100644 editors/vscode/src/status_bar.ts diff --git a/editors/vscode/package-lock.json b/editors/vscode/package-lock.json index 1e44b46bf16..418eacec030 100644 --- a/editors/vscode/package-lock.json +++ b/editors/vscode/package-lock.json @@ -1,12 +1,12 @@ { "name": "rome", - "version": "0.16.1", + "version": "0.18.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "rome", - "version": "0.16.1", + "version": "0.18.0", "license": "MIT", "devDependencies": { "@types/node": "^18.0.0", diff --git a/editors/vscode/src/main.ts b/editors/vscode/src/main.ts index 0a8c886fb3c..a94fc98f955 100644 --- a/editors/vscode/src/main.ts +++ b/editors/vscode/src/main.ts @@ -16,13 +16,12 @@ import { StreamInfo, } from "vscode-languageclient/node"; import { isAbsolute, join } from "path"; -import { existsSync, readFileSync } from "fs"; +import { existsSync } from "fs"; import { setContextValue } from "./utils"; import { Session } from "./session"; import { syntaxTree } from "./commands/syntaxTree"; import { Commands } from "./commands"; import { StatusBar } from "./statusBar"; -import { updateSettingsRequest } from "./lsp_requests"; let client: LanguageClient; @@ -90,13 +89,14 @@ export async function activate(context: ExtensionContext) { context.subscriptions.push( client.onDidChangeState((evt) => { - statusBar.setServerState(evt.newState); + statusBar.setServerState(client, evt.newState); }), ); const handleActiveTextEditorChanged = (textEditor?: TextEditor) => { if (!textEditor) { statusBar.setActive(false); + return; } const { document } = textEditor; diff --git a/editors/vscode/src/statusBar.ts b/editors/vscode/src/statusBar.ts index 33d99b7fe2f..99169ebea16 100644 --- a/editors/vscode/src/statusBar.ts +++ b/editors/vscode/src/statusBar.ts @@ -1,5 +1,6 @@ import { StatusBarAlignment, StatusBarItem, ThemeColor, window } from "vscode"; import { State } from "vscode-languageclient"; +import { LanguageClient } from "vscode-languageclient/node"; import { Commands } from "./commands"; /** @@ -24,6 +25,7 @@ export class StatusBar { private serverState: State = State.Starting; private isActive: boolean = false; + private serverVersion: string = ""; constructor() { this.statusBarItem = window.createStatusBarItem( @@ -37,8 +39,15 @@ export class StatusBar { this.update(); } - public setServerState(state: State) { + public setServerState(client: LanguageClient, state: State) { this.serverState = state; + + if (state === State.Running) { + this.serverVersion = client.initializeResult?.serverInfo?.version ?? ""; + } else { + this.serverVersion = ""; + } + this.update(); } @@ -61,7 +70,8 @@ export class StatusBar { status = Status.Error; } - this.statusBarItem.text = `$(${status}) Rome`; + this.statusBarItem.text = + `$(${status}) Rome ${this.serverVersion}`.trimEnd(); switch (status) { case Status.Pending: { diff --git a/editors/vscode/src/status_bar.ts b/editors/vscode/src/status_bar.ts deleted file mode 100644 index d14359a07dd..00000000000 --- a/editors/vscode/src/status_bar.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { StatusBarAlignment, StatusBarItem, ThemeColor, window } from "vscode"; -import { State } from "vscode-languageclient"; -import { Commands } from "./commands"; - -enum Status { - Pending = "refresh", - Ready = "check", - Inactive = "eye-closed", - Warning = "warning", - Error = "error", -} - -export class StatusBar { - private statusBarItem: StatusBarItem; - - private serverState: State = State.Starting; - private isActive: boolean = false; - - constructor() { - this.statusBarItem = window.createStatusBarItem( - "rome.status", - StatusBarAlignment.Right, - -1, - ); - - this.statusBarItem.name = "Rome"; - this.statusBarItem.command = Commands.ServerStatus; - this.update(); - } - - public setServerState(state: State) { - this.serverState = state; - this.update(); - } - - public setActive(isActive: boolean) { - this.isActive = isActive; - this.update(); - } - - private update() { - let status: Status; - if (this.serverState === State.Running) { - if (this.isActive) { - status = Status.Ready; - } else { - status = Status.Inactive; - } - } else if (this.serverState === State.Starting) { - status = Status.Pending; - } else { - status = Status.Error; - } - - this.statusBarItem.text = `$(${status}) Rome`; - - switch (status) { - case Status.Pending: { - this.statusBarItem.tooltip = "Rome is initializing ..."; - break; - } - case Status.Ready: { - this.statusBarItem.tooltip = "Rome is active"; - break; - } - case Status.Inactive: { - this.statusBarItem.tooltip = - "The current file is not supported or ignored by Rome"; - break; - } - // @ts-expect-error Reserved for future use - case Status.Warning: { - this.statusBarItem.tooltip = undefined; - break; - } - case Status.Error: { - this.statusBarItem.tooltip = "Rome encountered a fatal error"; - break; - } - } - - switch (status) { - case Status.Error: { - this.statusBarItem.color = new ThemeColor( - "statusBarItem.errorForeground", - ); - this.statusBarItem.backgroundColor = new ThemeColor( - "statusBarItem.errorBackground", - ); - break; - } - // @ts-expect-error Reserved for future use - case Status.Warning: { - this.statusBarItem.color = new ThemeColor( - "statusBarItem.warningForeground", - ); - this.statusBarItem.backgroundColor = new ThemeColor( - "statusBarItem.warningBackground", - ); - break; - } - default: { - this.statusBarItem.color = undefined; - this.statusBarItem.backgroundColor = undefined; - break; - } - } - - this.statusBarItem.show(); - } - - public hide() { - this.statusBarItem.hide(); - } -} From ec1feb472a77828479ba2027010ce0ae32484d74 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 9 Nov 2022 16:10:19 +0100 Subject: [PATCH 6/7] benchmark: Add pprettier and dprint to benchmark (#3597) --- benchmark/README.md | 17 +- benchmark/dprint.json | 12 + benchmark/package-lock.json | 1211 ++++++++++++++++++++++++++++++++++- benchmark/package.json | 2 + benchmark/run.js | 23 +- 5 files changed, 1237 insertions(+), 28 deletions(-) create mode 100644 benchmark/dprint.json diff --git a/benchmark/README.md b/benchmark/README.md index a54da2d6e53..d565c6df794 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -9,11 +9,17 @@ Setup: MacBook Pro (13-inch, M1, 2020) ### Formatting * Rome's ~25 times faster than Prettier -* Rome's ~7 times faster when restricting it to a single core +* Rome's ~20 times faster than parallel-prettier +* Rome's ~20 times faster than `xargs -P`[^1] +* Rome's 1.5-2 times faster than `dprint` +* Rome single-threaded is ~7 times faster than Prettier. + + +[^1]: Run `time find lib/ examples declarations benchmark -name '*.js' -print0 | xargs -P8 -0 -n 200 npx prettier --write --loglevel=error` in the `target/webpack` directory. I manually tinkered with the `-n` parameter to get the fastest run. ### Linting -* Rome's 2-3 times faster than ESLint -* Rome is ~20-40% slower than ESLint when restricting it to a single core. +* Rome's ~15x times faster than ESLint +* Rome single-threaded is ~4 times faster than ESLint. The speed-ups for the multithreaded benchmarks can vary significantly depending on the setup. For example, Rome is 100 times faster than Prettier on an M1 Max with 10 cores. @@ -23,16 +29,17 @@ The speed-ups for the multithreaded benchmarks can vary significantly depending * It should be possible to speed up Prettier. Rome's architecture isn't that different, and native has its advantages, but Prettier should be able to compete in single-threaded mode. ### Linting +* Rome's linter is fast but there is room for improvements * Rome's linter spends significant time building the semantic model, the control flow graph, and matching queries. I'm convinced there's room for improvement ([3565](https://github.com/rome/tools/pull/3565), [3569](https://github.com/rome/tools/pull/3569)). * Computing the diff for code fixes is expensive. Rome can spend up to 3s computing diffs (not measured by these benchmarks, see explanations below) -* Hypothesis: Rome doesn't use async IO to read files. That's why the single-threaded Rome issues the file read commands one by one. ESLint may be faster in single-threaded linting because it can issue all reads with async IO (so that the OS loads the files in the background while other files are linted). I have yet to verify if ESLint indeed does use async IO. ## Notes We've been careful to create fair benchmarks. This section explains some of the decisions behind the benchmark setup and how these decisions affect the results. Please [let us know](https://github.com/rome/tools/issues) if you have ideas on how to make the benchmarks fairer or if there's a mistake with our setup. ### Formatting -* Compares the wall time of Rome and Prettier to format all files in a project where all files are correctly formatted. +* Compares the wall time of Rome, Prettier, and dprint to format all files in a project where all files are correctly formatted. +* dprint and Prettier support incremental formatting to only format changed files, whereas Rome does not. This benchmark does not measure incremental formatting as it measures cold formatting time. You may see significant speedups on subsequent formatting runs when enabling incremental formatting. * The benchmark limits Prettier to only format JavaScript and TypeScript files because Rome doesn't support other file types. * Rome only prints a summary with the number of formatted files. The prettier benchmark uses `--loglevel=error` for a fairer benchmark so that Prettier doesn't print every filename. diff --git a/benchmark/dprint.json b/benchmark/dprint.json new file mode 100644 index 00000000000..ecafd093a68 --- /dev/null +++ b/benchmark/dprint.json @@ -0,0 +1,12 @@ +{ + "incremental": false, + "typescript": { + }, + "includes": ["**/*.{ts,tsx,js,jsx,cjs,mjs}"], + "excludes": [ + "**/node_modules" + ], + "plugins": [ + "https://plugins.dprint.dev/typescript-0.77.0.wasm" + ] +} diff --git a/benchmark/package-lock.json b/benchmark/package-lock.json index babf523ca4a..68be297fc03 100644 --- a/benchmark/package-lock.json +++ b/benchmark/package-lock.json @@ -9,6 +9,8 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { + "@mixer/parallel-prettier": "^2.0.3", + "dprint": "^0.32.2", "eslint": "^8.26.0", "prettier": "^2.7.1" } @@ -69,6 +71,27 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@mixer/parallel-prettier": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@mixer/parallel-prettier/-/parallel-prettier-2.0.3.tgz", + "integrity": "sha512-42ImvDusmxjpQLHEmZrljV/+L9ynfmaTe5ooLMTTLyELulUJtJW8vBXCadQdodfZ5wjr2Sg3YGIzWE0rnBsfDg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "commander": "^7.0.0", + "glob-stream": "^7.0.0", + "ignore": "^5.1.8", + "ora": "^5.3.0", + "prettier": "^2.0.4", + "rxjs": "^6.6.3" + }, + "bin": { + "pprettier": "dist/index.js" + }, + "peerDependencies": { + "prettier": "^2.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -177,6 +200,37 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -187,6 +241,39 @@ "concat-map": "0.0.1" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -212,6 +299,39 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -230,12 +350,27 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -273,6 +408,18 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -285,6 +432,40 @@ "node": ">=6.0.0" } }, + "node_modules/dprint": { + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.32.2.tgz", + "integrity": "sha512-cGKnZonCFQkcNbptAtJXlzUOqyiyYoD9pINepJ9PvkFi8iwMLChQDSjhMeqT3DDQf5Rof3pYA5LI/bafPpPknQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "yauzl": "=2.10.0" + }, + "bin": { + "dprint": "bin.js" + } + }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -461,6 +642,12 @@ "node": ">=0.10.0" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -488,6 +675,15 @@ "reusify": "^1.0.4" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -573,6 +769,27 @@ "node": ">=10.13.0" } }, + "node_modules/glob-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-7.0.0.tgz", + "integrity": "sha512-evR4kvr6s0Yo5t4CD4H171n4T8XcnPFznvsbeN8K9FPzc0Q0wYqcOWyGtck2qcvJSLXKnU6DnDyfmbDDabYvRQ==", + "dev": true, + "dependencies": { + "extend": "^3.0.2", + "glob": "^7.2.0", + "glob-parent": "^6.0.2", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.1", + "pumpify": "^2.0.1", + "readable-stream": "^3.6.0", + "remove-trailing-separator": "^1.1.0", + "to-absolute-glob": "^2.0.2", + "unique-stream": "^2.3.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/globals": { "version": "13.17.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", @@ -603,6 +820,26 @@ "node": ">=8" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -653,6 +890,19 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -674,6 +924,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -683,6 +951,57 @@ "node": ">=8" } }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -753,6 +1072,31 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -786,6 +1130,21 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -803,6 +1162,68 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/ordered-read-streams/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/ordered-read-streams/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ordered-read-streams/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -872,6 +1293,12 @@ "node": ">=8" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -896,6 +1323,33 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "dev": true, + "dependencies": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -925,6 +1379,20 @@ } ] }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -937,6 +1405,12 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -946,6 +1420,19 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -994,6 +1481,38 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1015,6 +1534,27 @@ "node": ">=8" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1027,34 +1567,103 @@ "node": ">=8" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "node_modules/type-check": { @@ -1081,6 +1690,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1090,6 +1718,21 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1120,6 +1763,25 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -1174,6 +1836,21 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@mixer/parallel-prettier": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@mixer/parallel-prettier/-/parallel-prettier-2.0.3.tgz", + "integrity": "sha512-42ImvDusmxjpQLHEmZrljV/+L9ynfmaTe5ooLMTTLyELulUJtJW8vBXCadQdodfZ5wjr2Sg3YGIzWE0rnBsfDg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "commander": "^7.0.0", + "glob-stream": "^7.0.0", + "ignore": "^5.1.8", + "ora": "^5.3.0", + "prettier": "^2.0.4", + "rxjs": "^6.6.3" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1252,6 +1929,23 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1262,6 +1956,22 @@ "concat-map": "0.0.1" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1278,6 +1988,27 @@ "supports-color": "^7.1.0" } }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "dev": true + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1293,12 +2024,24 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1325,6 +2068,15 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1334,6 +2086,36 @@ "esutils": "^2.0.2" } }, + "dprint": { + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.32.2.tgz", + "integrity": "sha512-cGKnZonCFQkcNbptAtJXlzUOqyiyYoD9pINepJ9PvkFi8iwMLChQDSjhMeqT3DDQf5Rof3pYA5LI/bafPpPknQ==", + "dev": true, + "requires": { + "yauzl": "=2.10.0" + } + }, + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dev": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1461,6 +2243,12 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1488,6 +2276,15 @@ "reusify": "^1.0.4" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -1552,6 +2349,24 @@ "is-glob": "^4.0.3" } }, + "glob-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-7.0.0.tgz", + "integrity": "sha512-evR4kvr6s0Yo5t4CD4H171n4T8XcnPFznvsbeN8K9FPzc0Q0wYqcOWyGtck2qcvJSLXKnU6DnDyfmbDDabYvRQ==", + "dev": true, + "requires": { + "extend": "^3.0.2", + "glob": "^7.2.0", + "glob-parent": "^6.0.2", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.1", + "pumpify": "^2.0.1", + "readable-stream": "^3.6.0", + "remove-trailing-separator": "^1.1.0", + "to-absolute-glob": "^2.0.2", + "unique-stream": "^2.3.1" + } + }, "globals": { "version": "13.17.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", @@ -1573,6 +2388,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -1611,6 +2432,16 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1626,12 +2457,60 @@ "is-extglob": "^2.1.1" } }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", + "dev": true + }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1690,6 +2569,22 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1720,6 +2615,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -1734,6 +2638,64 @@ "word-wrap": "^1.2.3" } }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -1779,6 +2741,12 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -1791,6 +2759,33 @@ "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "dev": true }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "dev": true, + "requires": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -1803,18 +2798,45 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -1839,6 +2861,21 @@ "queue-microtask": "^1.2.2" } }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1854,6 +2891,27 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1884,6 +2942,74 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -1899,6 +3025,22 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1908,6 +3050,21 @@ "punycode": "^2.1.0" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1929,6 +3086,22 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/benchmark/package.json b/benchmark/package.json index adfddc413e8..825079ef8c0 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -9,6 +9,8 @@ "author": "", "license": "MIT", "devDependencies": { + "@mixer/parallel-prettier": "^2.0.3", + "dprint": "^0.32.2", "eslint": "^8.26.0", "prettier": "^2.7.1" } diff --git a/benchmark/run.js b/benchmark/run.js index 7a9c6b24eb8..ff5da16f045 100644 --- a/benchmark/run.js +++ b/benchmark/run.js @@ -1,6 +1,7 @@ const fs = require("fs"); const child_process = require("child_process"); const path = require("path"); +const os = require("os"); const { dir } = require("console"); const TMP_DIRECTORY = path.resolve("./target"); @@ -58,6 +59,9 @@ function benchmarkFormatter(rome) { console.log("―".repeat(80)); console.log(""); + // Run Dprint once to run the installer + child_process.execSync("npx dprint --version"); + for (const [name, configuration] of Object.entries(BENCHMARKS.formatter)) { console.log(`[${name}]`); @@ -72,6 +76,9 @@ function benchmarkFormatter(rome) { .join(" "); const prettierCommand = `node '${resolvePrettier()}' ${prettierPaths} --write --loglevel=error`; + const parallelPrettierCommand = `node '${resolveParallelPrettier()}' ${prettierPaths} --write --concurrency ${os.cpus().length}`; + + const dprintCommand = `${resolveDprint()} fmt --incremental=false --config '${require.resolve("./dprint.json")}' ${Object.keys(configuration.sourceDirectories).map(path => `'${path}/**/*'`).join(" ")}`; const romeCommand = `${rome} format ${Object.keys( configuration.sourceDirectories, @@ -86,7 +93,7 @@ function benchmarkFormatter(rome) { ); // Run 2 warmups to make sure the files are formatted correctly - const hyperfineCommand = `hyperfine -w 2 -n Prettier "${prettierCommand}" -n Rome "${romeCommand}" --shell=${shellOption()} -n "Rome (1 thread)" "${romeSingleCoreCommand}"`; + const hyperfineCommand = `hyperfine -w 2 -n Prettier "${prettierCommand}" -n "Parallel-Prettier" "${parallelPrettierCommand}" -n dprint "${dprintCommand}" -n Rome "${romeCommand}" --shell=${shellOption()} -n "Rome (1 thread)" "${romeSingleCoreCommand}"`; console.log(hyperfineCommand); child_process.execSync(hyperfineCommand, { @@ -97,7 +104,15 @@ function benchmarkFormatter(rome) { } function resolvePrettier() { - return path.resolve("node_modules/prettier//bin-prettier.js"); + return path.resolve("node_modules/prettier/bin-prettier.js"); +} + +function resolveParallelPrettier() { + return path.resolve("node_modules/.bin/pprettier"); +} + +function resolveDprint() { + return path.resolve("node_modules/dprint/dprint"); } function benchmarkLinter(rome) { @@ -112,11 +127,11 @@ function benchmarkLinter(rome) { const projectDirectory = cloneProject(name, configuration.repository); deleteFile(path.join(projectDirectory, ".eslintignore")); - deleteFile(path.join(projectDirectory, "eslint.config.js")); + deleteFile(path.join(projectDirectory, "/eslintrc.js")); // Override eslint config const eslintConfig = fs.readFileSync("./bench.eslint.js"); - fs.writeFileSync(path.join(projectDirectory, ".eslintrc.js"), eslintConfig); + fs.writeFileSync(path.join(projectDirectory, "eslint.config.js"), eslintConfig); const romeConfig = fs.readFileSync("./bench.rome.json"); fs.writeFileSync(path.join(projectDirectory, "rome.json"), romeConfig); From 76a56db132d66fd3df38a10647e3eac9af857413 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 9 Nov 2022 16:10:34 +0100 Subject: [PATCH 7/7] fix(rome_js_analyze): Verify method name of React API calls (#3619) --- crates/rome_js_analyze/src/react.rs | 144 +++++----- .../correctness/no_array_index_key.rs | 32 +-- .../specs/correctness/noArrayIndexKey.jsx | 4 +- .../correctness/noArrayIndexKey.jsx.snap | 267 +++++++++--------- .../noChildrenProp/noChildrenPropInvalid.jsx | 7 + .../noChildrenPropInvalid.jsx.snap | 41 +-- .../noChildrenProp/noChildrenPropValid.jsx | 6 + .../noChildrenPropValid.jsx.snap | 6 + .../noUselessFragments/noChildren.jsx | 2 +- .../noUselessFragments/noChildren.jsx.snap | 2 + .../createElement.js | 2 +- .../createElement.js.snap | 26 +- .../reactCreateElement.js | 2 +- .../reactCreateElement.js.snap | 2 + .../createElement.js | 2 +- .../createElement.js.snap | 5 + 16 files changed, 294 insertions(+), 256 deletions(-) diff --git a/crates/rome_js_analyze/src/react.rs b/crates/rome_js_analyze/src/react.rs index e105e11e9e6..dbede90cd8a 100644 --- a/crates/rome_js_analyze/src/react.rs +++ b/crates/rome_js_analyze/src/react.rs @@ -2,7 +2,7 @@ pub mod hooks; -use rome_js_semantic::SemanticModel; +use rome_js_semantic::{Binding, SemanticModel}; use rome_js_syntax::{ JsAnyCallArgument, JsAnyExpression, JsAnyNamedImportSpecifier, JsCallExpression, JsIdentifierBinding, JsImport, JsImportNamedClause, JsNamedImportSpecifierList, @@ -247,46 +247,46 @@ pub(crate) fn is_react_call_api( ) -> Option { // we bail straight away if the API doesn't exists in React debug_assert!(VALID_REACT_API.contains(&api_name)); + Some(match expression { JsAnyExpression::JsStaticMemberExpression(node) => { - let object = node.object().ok()?; let member = node.member().ok()?; let member = member.as_js_name()?; + + if member.value_token().ok()?.text_trimmed() != api_name { + return Some(false); + } + + let object = node.object().ok()?; let identifier = object.as_js_identifier_expression()?.name().ok()?; - let mut maybe_from_react = identifier.syntax().text_trimmed() == "React" - && member.syntax().text_trimmed() == api_name; - - if let Some(binding_identifier) = model.declaration(&identifier) { - let binding_identifier = - JsIdentifierBinding::cast_ref(binding_identifier.syntax())?; - if let Some(js_import) = binding_identifier - .syntax() - .ancestors() - .find_map(|ancestor| JsImport::cast_ref(&ancestor)) - { - maybe_from_react = js_import.source_is("react").ok()?; + match model.declaration(&identifier) { + Some(binding) => { + let binding_identifier = JsIdentifierBinding::cast_ref(binding.syntax())?; + + if let Some(js_import) = binding_identifier + .syntax() + .ancestors() + .find_map(|ancestor| JsImport::cast_ref(&ancestor)) + { + js_import.source_is("react").ok()? + } else { + false + } } + None => identifier.has_name("React"), } - maybe_from_react } + JsAnyExpression::JsIdentifierExpression(identifier) => { let name = identifier.name().ok()?; - let mut maybe_react = identifier.syntax().text_trimmed() == api_name; - if let Some(identifier_binding) = model.declaration(&name) { - let binding_identifier = - JsIdentifierBinding::cast_ref(identifier_binding.syntax())?; - if let Some(js_import) = binding_identifier - .syntax() - .ancestors() - .find_map(|ancestor| JsImport::cast_ref(&ancestor)) - { - maybe_react = js_import.source_is("react").ok()?; - } - } - maybe_react + + model + .declaration(&name) + .and_then(|binding| is_react_export(binding, api_name)) + .unwrap_or(false) } - _ => return None, + _ => false, }) } @@ -303,24 +303,25 @@ pub(crate) fn jsx_member_name_is_react_fragment( let object = member_name.object().ok()?; let member = member_name.member().ok()?; let object = object.as_jsx_reference_identifier()?; - let mut maybe_react_fragment = object.value_token().ok()?.text_trimmed() == "React" - && member.value_token().ok()?.text_trimmed() == "Fragment"; - if let Some(reference) = model.declaration(object) { - if let Some(js_import) = reference - .syntax() - .ancestors() - .find_map(|ancestor| JsImport::cast_ref(&ancestor)) - { - let source_is_react = js_import.source_is("react").ok()?; - maybe_react_fragment = - source_is_react && member.value_token().ok()?.text_trimmed() == "Fragment"; - } else { - // `React.Fragment` is a binding but it doesn't come from the "react" package - maybe_react_fragment = false; - } + + if member.value_token().ok()?.text_trimmed() != "Fragment" { + return Some(false); } - Some(maybe_react_fragment) + match model.declaration(object) { + Some(declaration) => { + if let Some(js_import) = declaration + .syntax() + .ancestors() + .find_map(|ancestor| JsImport::cast_ref(&ancestor)) + { + js_import.source_is("react").ok() + } else { + Some(false) + } + } + None => Some(object.value_token().ok()?.text_trimmed() == "React"), + } } /// Checks if the node `JsxReferenceIdentifier` is a react fragment. @@ -334,33 +335,7 @@ pub(crate) fn jsx_reference_identifier_is_fragment( model: &SemanticModel, ) -> Option { match model.declaration(name) { - Some(reference) => { - let ident = JsIdentifierBinding::cast_ref(reference.syntax())?; - - let import_specifier = ident.parent::()?; - let name_token = match &import_specifier { - JsAnyNamedImportSpecifier::JsNamedImportSpecifier(named_import) => { - named_import.name().ok()?.value().ok()? - } - JsAnyNamedImportSpecifier::JsShorthandNamedImportSpecifier(_) => { - ident.name_token().ok()? - } - JsAnyNamedImportSpecifier::JsUnknownNamedImportSpecifier(_) => { - return None; - } - }; - - if name_token.text_trimmed() != "Fragment" { - return Some(false); - } - - let import_specifier_list = import_specifier.parent::()?; - let import_specifiers = import_specifier_list.parent::()?; - let import_clause = import_specifiers.parent::()?; - let import = import_clause.parent::()?; - import.source_is("react").ok() - } - + Some(reference) => is_react_export(reference, "Fragment"), None => { let value_token = name.value_token().ok()?; let is_fragment = value_token.text_trimmed() == "Fragment"; @@ -368,3 +343,28 @@ pub(crate) fn jsx_reference_identifier_is_fragment( } } } + +fn is_react_export(binding: Binding, name: &str) -> Option { + let ident = JsIdentifierBinding::cast_ref(binding.syntax())?; + let import_specifier = ident.parent::()?; + let name_token = match &import_specifier { + JsAnyNamedImportSpecifier::JsNamedImportSpecifier(named_import) => { + named_import.name().ok()?.value().ok()? + } + JsAnyNamedImportSpecifier::JsShorthandNamedImportSpecifier(_) => ident.name_token().ok()?, + JsAnyNamedImportSpecifier::JsUnknownNamedImportSpecifier(_) => { + return Some(false); + } + }; + + if name_token.text_trimmed() != name { + return Some(false); + } + + let import_specifier_list = import_specifier.parent::()?; + let import_specifiers = import_specifier_list.parent::()?; + let import_clause = import_specifiers.parent::()?; + let import = import_clause.parent::()?; + + import.source_is("react").ok() +} diff --git a/crates/rome_js_analyze/src/semantic_analyzers/correctness/no_array_index_key.rs b/crates/rome_js_analyze/src/semantic_analyzers/correctness/no_array_index_key.rs index 04ad77e429c..1ca2a3c2257 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/correctness/no_array_index_key.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/correctness/no_array_index_key.rs @@ -5,8 +5,8 @@ use rome_analyze::{declare_rule, Rule, RuleDiagnostic}; use rome_console::markup; use rome_js_semantic::SemanticModel; use rome_js_syntax::{ - JsArrowFunctionExpression, JsCallExpression, JsExpressionStatement, JsFunctionDeclaration, - JsFunctionExpression, JsIdentifierBinding, JsIdentifierExpression, JsMethodClassMember, + JsAnyCallArgument, JsArrowFunctionExpression, JsCallExpression, JsExpressionStatement, + JsFunctionDeclaration, JsFunctionExpression, JsIdentifierBinding, JsMethodClassMember, JsMethodObjectMember, JsParameterList, JsPropertyObjectMember, JsReferenceIdentifier, JsxAttribute, JsxOpeningElement, JsxSelfClosingElement, }; @@ -326,28 +326,24 @@ fn find_react_children_function_argument( "forEach" | "map" ); - let object = member_expression.object().ok()?; - - let mut is_react_children = false; - // case we have `Children` - if let Some(identifier) = JsIdentifierExpression::cast_ref(object.syntax()) { - if identifier.name().ok()?.value_token().ok()?.text_trimmed() == "Children" { - is_react_children = array_call; - } - } else { - // case we have `React.Children` - is_react_children = is_react_call_api(&object, model, "Children")? && array_call; + if !array_call { + return None; } - if is_react_children { + let object = member_expression.object().ok()?; + + // React.Children.forEach/map or Children.forEach/map + if is_react_call_api(&object, model, "Children")? { let arguments = call_expression.arguments().ok()?; let arguments = arguments.args(); let mut arguments = arguments.into_iter(); - let _ = arguments.next()?.ok()?; - let second_argument = arguments.next()?.ok()?; - let second_argument = second_argument.as_js_any_expression()?; - FunctionLike::cast(second_argument.clone().into_syntax()) + match (arguments.next(), arguments.next(), arguments.next()) { + (Some(_), Some(Ok(JsAnyCallArgument::JsAnyExpression(second_argument))), None) => { + FunctionLike::cast(second_argument.into_syntax()) + } + _ => None, + } } else { None } diff --git a/crates/rome_js_analyze/tests/specs/correctness/noArrayIndexKey.jsx b/crates/rome_js_analyze/tests/specs/correctness/noArrayIndexKey.jsx index 488f9ace4bb..efa70cb986b 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noArrayIndexKey.jsx +++ b/crates/rome_js_analyze/tests/specs/correctness/noArrayIndexKey.jsx @@ -1,3 +1,5 @@ +import { Children, cloneElement } from "react"; + // invalid something.forEach((Element, index) => { foo @@ -57,4 +59,4 @@ something.forEach((element, index) => { something.forEach((element, index) => { -}); \ No newline at end of file +}); diff --git a/crates/rome_js_analyze/tests/specs/correctness/noArrayIndexKey.jsx.snap b/crates/rome_js_analyze/tests/specs/correctness/noArrayIndexKey.jsx.snap index 702ceaa1d11..682b1d94dec 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noArrayIndexKey.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/correctness/noArrayIndexKey.jsx.snap @@ -4,6 +4,8 @@ expression: noArrayIndexKey.jsx --- # Input ```js +import { Children, cloneElement } from "react"; + // invalid something.forEach((Element, index) => { foo @@ -64,28 +66,29 @@ something.forEach((element, index) => { }); + ``` # Diagnostics ``` -noArrayIndexKey.jsx:3:21 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:5:21 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 1 │ // invalid - 2 │ something.forEach((Element, index) => { - > 3 │ foo + 3 │ // invalid + 4 │ something.forEach((Element, index) => { + > 5 │ foo │ ^^^^^ - 4 │ }); - 5 │ something.forEach((element, index, array) => { + 6 │ }); + 7 │ something.forEach((element, index, array) => { i This is the source of the key value. - 1 │ // invalid - > 2 │ something.forEach((Element, index) => { + 3 │ // invalid + > 4 │ something.forEach((Element, index) => { │ ^^^^^ - 3 │ foo - 4 │ }); + 5 │ foo + 6 │ }); i The order of the items may change, and this also affects performances and component state. @@ -95,25 +98,25 @@ noArrayIndexKey.jsx:3:21 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:6:21 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:8:21 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 4 │ }); - 5 │ something.forEach((element, index, array) => { - > 6 │ foo - │ ^^^^^ - 7 │ }); - 8 │ things.filter((thing, index) => { + 6 │ }); + 7 │ something.forEach((element, index, array) => { + > 8 │ foo + │ ^^^^^ + 9 │ }); + 10 │ things.filter((thing, index) => { i This is the source of the key value. - 3 │ foo - 4 │ }); - > 5 │ something.forEach((element, index, array) => { + 5 │ foo + 6 │ }); + > 7 │ something.forEach((element, index, array) => { │ ^^^^^ - 6 │ foo - 7 │ }); + 8 │ foo + 9 │ }); i The order of the items may change, and this also affects performances and component state. @@ -123,25 +126,25 @@ noArrayIndexKey.jsx:6:21 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:9:34 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:11:34 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 7 │ }); - 8 │ things.filter((thing, index) => { - > 9 │ otherThings.push(foo); + 9 │ }); + 10 │ things.filter((thing, index) => { + > 11 │ otherThings.push(foo); │ ^^^^^ - 10 │ }); - 11 │ + 12 │ }); + 13 │ i This is the source of the key value. - 6 │ foo - 7 │ }); - > 8 │ things.filter((thing, index) => { + 8 │ foo + 9 │ }); + > 10 │ things.filter((thing, index) => { │ ^^^^^ - 9 │ otherThings.push(foo); - 10 │ }); + 11 │ otherThings.push(foo); + 12 │ }); i The order of the items may change, and this also affects performances and component state. @@ -151,24 +154,24 @@ noArrayIndexKey.jsx:9:34 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:13:21 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:15:21 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 12 │ something.forEach((Element, index) => { - > 13 │ + 14 │ something.forEach((Element, index) => { + > 15 │ │ ^^^^^ - 14 │ }); - 15 │ something.forEach((element, index, array) => { + 16 │ }); + 17 │ something.forEach((element, index, array) => { i This is the source of the key value. - 10 │ }); - 11 │ - > 12 │ something.forEach((Element, index) => { + 12 │ }); + 13 │ + > 14 │ something.forEach((Element, index) => { │ ^^^^^ - 13 │ - 14 │ }); + 15 │ + 16 │ }); i The order of the items may change, and this also affects performances and component state. @@ -178,25 +181,25 @@ noArrayIndexKey.jsx:13:21 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:16:21 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:18:21 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 14 │ }); - 15 │ something.forEach((element, index, array) => { - > 16 │ + 16 │ }); + 17 │ something.forEach((element, index, array) => { + > 18 │ │ ^^^^^ - 17 │ }); - 18 │ things.filter((thing, index) => { + 19 │ }); + 20 │ things.filter((thing, index) => { i This is the source of the key value. - 13 │ - 14 │ }); - > 15 │ something.forEach((element, index, array) => { + 15 │ + 16 │ }); + > 17 │ something.forEach((element, index, array) => { │ ^^^^^ - 16 │ - 17 │ }); + 18 │ + 19 │ }); i The order of the items may change, and this also affects performances and component state. @@ -206,25 +209,25 @@ noArrayIndexKey.jsx:16:21 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:19:34 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:21:34 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 17 │ }); - 18 │ things.filter((thing, index) => { - > 19 │ otherThings.push(); + 19 │ }); + 20 │ things.filter((thing, index) => { + > 21 │ otherThings.push(); │ ^^^^^ - 20 │ }); - 21 │ things.reduce((collection, thing, index) => ( + 22 │ }); + 23 │ things.reduce((collection, thing, index) => ( i This is the source of the key value. - 16 │ - 17 │ }); - > 18 │ things.filter((thing, index) => { + 18 │ + 19 │ }); + > 20 │ things.filter((thing, index) => { │ ^^^^^ - 19 │ otherThings.push(); - 20 │ }); + 21 │ otherThings.push(); + 22 │ }); i The order of the items may change, and this also affects performances and component state. @@ -234,25 +237,25 @@ noArrayIndexKey.jsx:19:34 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:22:35 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:24:35 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 20 │ }); - 21 │ things.reduce((collection, thing, index) => ( - > 22 │ collection.concat() + 22 │ }); + 23 │ things.reduce((collection, thing, index) => ( + > 24 │ collection.concat() │ ^^^^^ - 23 │ ), []); - 24 │ + 25 │ ), []); + 26 │ i This is the source of the key value. - 19 │ otherThings.push(); - 20 │ }); - > 21 │ things.reduce((collection, thing, index) => ( + 21 │ otherThings.push(); + 22 │ }); + > 23 │ things.reduce((collection, thing, index) => ( │ ^^^^^ - 22 │ collection.concat() - 23 │ ), []); + 24 │ collection.concat() + 25 │ ), []); i The order of the items may change, and this also affects performances and component state. @@ -262,24 +265,24 @@ noArrayIndexKey.jsx:22:35 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:26:38 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:28:38 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 25 │ React.Children.map(this.props.children, (child, index) => ( - > 26 │ React.cloneElement(child, { key: index }) + 27 │ React.Children.map(this.props.children, (child, index) => ( + > 28 │ React.cloneElement(child, { key: index }) │ ^^^^^ - 27 │ )) - 28 │ + 29 │ )) + 30 │ i This is the source of the key value. - 23 │ ), []); - 24 │ - > 25 │ React.Children.map(this.props.children, (child, index) => ( + 25 │ ), []); + 26 │ + > 27 │ React.Children.map(this.props.children, (child, index) => ( │ ^^^^^ - 26 │ React.cloneElement(child, { key: index }) - 27 │ )) + 28 │ React.cloneElement(child, { key: index }) + 29 │ )) i The order of the items may change, and this also affects performances and component state. @@ -289,24 +292,24 @@ noArrayIndexKey.jsx:26:38 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:30:45 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:32:45 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 29 │ React.Children.forEach(this.props.children, function (child, index) { - > 30 │ return React.cloneElement(child, { key: index }) + 31 │ React.Children.forEach(this.props.children, function (child, index) { + > 32 │ return React.cloneElement(child, { key: index }) │ ^^^^^ - 31 │ }) - 32 │ + 33 │ }) + 34 │ i This is the source of the key value. - 27 │ )) - 28 │ - > 29 │ React.Children.forEach(this.props.children, function (child, index) { + 29 │ )) + 30 │ + > 31 │ React.Children.forEach(this.props.children, function (child, index) { │ ^^^^^ - 30 │ return React.cloneElement(child, { key: index }) - 31 │ }) + 32 │ return React.cloneElement(child, { key: index }) + 33 │ }) i The order of the items may change, and this also affects performances and component state. @@ -316,22 +319,22 @@ noArrayIndexKey.jsx:30:45 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:35:32 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:37:32 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 34 │ Children.map(this.props.children, (child, index) => ( - > 35 │ cloneElement(child, { key: index }) + 36 │ Children.map(this.props.children, (child, index) => ( + > 37 │ cloneElement(child, { key: index }) │ ^^^^^ - 36 │ )) - 37 │ + 38 │ )) + 39 │ i This is the source of the key value. - > 34 │ Children.map(this.props.children, (child, index) => ( + > 36 │ Children.map(this.props.children, (child, index) => ( │ ^^^^^ - 35 │ cloneElement(child, { key: index }) - 36 │ )) + 37 │ cloneElement(child, { key: index }) + 38 │ )) i The order of the items may change, and this also affects performances and component state. @@ -341,24 +344,24 @@ noArrayIndexKey.jsx:35:32 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:39:39 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:41:39 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 38 │ Children.forEach(this.props.children, function (child, index) { - > 39 │ return cloneElement(child, { key: index }) + 40 │ Children.forEach(this.props.children, function (child, index) { + > 41 │ return cloneElement(child, { key: index }) │ ^^^^^ - 40 │ }) - 41 │ + 42 │ }) + 43 │ i This is the source of the key value. - 36 │ )) - 37 │ - > 38 │ Children.forEach(this.props.children, function (child, index) { + 38 │ )) + 39 │ + > 40 │ Children.forEach(this.props.children, function (child, index) { │ ^^^^^ - 39 │ return cloneElement(child, { key: index }) - 40 │ }) + 41 │ return cloneElement(child, { key: index }) + 42 │ }) i The order of the items may change, and this also affects performances and component state. @@ -368,24 +371,24 @@ noArrayIndexKey.jsx:39:39 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:43:44 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:45:44 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 42 │ Children.forEach(this.props.children, function (child, index) { - > 43 │ const foo = cloneElement(child, { key: index }) + 44 │ Children.forEach(this.props.children, function (child, index) { + > 45 │ const foo = cloneElement(child, { key: index }) │ ^^^^^ - 44 │ return foo; - 45 │ }) + 46 │ return foo; + 47 │ }) i This is the source of the key value. - 40 │ }) - 41 │ - > 42 │ Children.forEach(this.props.children, function (child, index) { + 42 │ }) + 43 │ + > 44 │ Children.forEach(this.props.children, function (child, index) { │ ^^^^^ - 43 │ const foo = cloneElement(child, { key: index }) - 44 │ return foo; + 45 │ const foo = cloneElement(child, { key: index }) + 46 │ return foo; i The order of the items may change, and this also affects performances and component state. @@ -395,22 +398,22 @@ noArrayIndexKey.jsx:43:44 lint/correctness/noArrayIndexKey ━━━━━━━ ``` ``` -noArrayIndexKey.jsx:49:38 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noArrayIndexKey.jsx:51:38 lint/correctness/noArrayIndexKey ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid using the index of an array as key property in an element. - 48 │ things.map((thing, index) => ( - > 49 │ React.cloneElement(thing, { key: index }) + 50 │ things.map((thing, index) => ( + > 51 │ React.cloneElement(thing, { key: index }) │ ^^^^^ - 50 │ )); - 51 │ + 52 │ )); + 53 │ i This is the source of the key value. - > 48 │ things.map((thing, index) => ( + > 50 │ things.map((thing, index) => ( │ ^^^^^ - 49 │ React.cloneElement(thing, { key: index }) - 50 │ )); + 51 │ React.cloneElement(thing, { key: index }) + 52 │ )); i The order of the items may change, and this also affects performances and component state. diff --git a/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropInvalid.jsx b/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropInvalid.jsx index 02c39406f0e..a39b478ae12 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropInvalid.jsx +++ b/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropInvalid.jsx @@ -1,3 +1,5 @@ +import { createElement as aliased } from "react"; + <> @@ -9,3 +11,8 @@ createElement('div', { React.createElement('div', { children: 'foo' }) + + +aliased('div', { + children: 'foo' +}) diff --git a/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropInvalid.jsx.snap b/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropInvalid.jsx.snap index f35e7d29f7e..2873d60944c 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropInvalid.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropInvalid.jsx.snap @@ -4,6 +4,8 @@ expression: noChildrenPropInvalid.jsx --- # Input ```js +import { createElement as aliased } from "react"; + <> @@ -16,19 +18,24 @@ React.createElement('div', { children: 'foo' }) + +aliased('div', { + children: 'foo' +}) + ``` # Diagnostics ``` -noChildrenPropInvalid.jsx:2:16 lint/correctness/noChildrenProp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noChildrenPropInvalid.jsx:4:16 lint/correctness/noChildrenProp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid passing children using a prop - 1 │ <> - > 2 │ + 3 │ <> + > 4 │ │ ^^^^^^^^ - 3 │ - 4 │ + 5 │ + 6 │ i The canonical way to pass children in React is to use JSX elements @@ -36,15 +43,15 @@ noChildrenPropInvalid.jsx:2:16 lint/correctness/noChildrenProp ━━━━━ ``` ``` -noChildrenPropInvalid.jsx:6:5 lint/correctness/noChildrenProp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noChildrenPropInvalid.jsx:12:5 lint/correctness/noChildrenProp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid passing children using a prop - 5 │ createElement('div', { - > 6 │ children: 'foo' - │ ^^^^^^^^ - 7 │ }) - 8 │ + 11 │ React.createElement('div', { + > 12 │ children: 'foo' + │ ^^^^^^^^ + 13 │ }) + 14 │ i The canonical way to pass children in React is to use additional arguments to React.createElement @@ -52,15 +59,15 @@ noChildrenPropInvalid.jsx:6:5 lint/correctness/noChildrenProp ━━━━━━ ``` ``` -noChildrenPropInvalid.jsx:10:5 lint/correctness/noChildrenProp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +noChildrenPropInvalid.jsx:17:2 lint/correctness/noChildrenProp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid passing children using a prop - 9 │ React.createElement('div', { - > 10 │ children: 'foo' - │ ^^^^^^^^ - 11 │ }) - 12 │ + 16 │ aliased('div', { + > 17 │ children: 'foo' + │ ^^^^^^^^ + 18 │ }) + 19 │ i The canonical way to pass children in React is to use additional arguments to React.createElement diff --git a/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropValid.jsx b/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropValid.jsx index b5ea51268e0..bf0efd8dbd5 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropValid.jsx +++ b/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropValid.jsx @@ -1,3 +1,6 @@ +import { cloneElement } from "react"; +import React from "react"; + <> @@ -7,3 +10,6 @@ createElement('div', {}, 'foo') + +cloneElement('div', { children:
}); +React.cloneElement('div', { children:
}); diff --git a/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropValid.jsx.snap b/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropValid.jsx.snap index 4523817da33..d193e41a1ee 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropValid.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/correctness/noChildrenProp/noChildrenPropValid.jsx.snap @@ -4,6 +4,9 @@ expression: noChildrenPropValid.jsx --- # Input ```js +import { cloneElement } from "react"; +import React from "react"; + <> @@ -14,6 +17,9 @@ expression: noChildrenPropValid.jsx createElement('div', {}, 'foo') +cloneElement('div', { children:
}); +React.cloneElement('div', { children:
}); + ``` diff --git a/crates/rome_js_analyze/tests/specs/correctness/noUselessFragments/noChildren.jsx b/crates/rome_js_analyze/tests/specs/correctness/noUselessFragments/noChildren.jsx index 2be0a35fa56..85ad76e5730 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noUselessFragments/noChildren.jsx +++ b/crates/rome_js_analyze/tests/specs/correctness/noUselessFragments/noChildren.jsx @@ -4,4 +4,4 @@ <> - \ No newline at end of file + diff --git a/crates/rome_js_analyze/tests/specs/correctness/noUselessFragments/noChildren.jsx.snap b/crates/rome_js_analyze/tests/specs/correctness/noUselessFragments/noChildren.jsx.snap index 0c8caa8df96..e2b12e7221a 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noUselessFragments/noChildren.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/correctness/noUselessFragments/noChildren.jsx.snap @@ -11,6 +11,7 @@ expression: noChildren.jsx + ``` # Diagnostics @@ -61,6 +62,7 @@ noChildren.jsx:6:5 lint/correctness/noUselessFragments FIXABLE ━━━━━ > 6 │ │ ^^^^^^^^^^^^^^^^^^^^^ 7 │ + 8 │ i Suggested fix: Remove the Fragment diff --git a/crates/rome_js_analyze/tests/specs/correctness/noVoidElementsWithChildren/createElement.js b/crates/rome_js_analyze/tests/specs/correctness/noVoidElementsWithChildren/createElement.js index 45fd0486666..9a524163ac5 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noVoidElementsWithChildren/createElement.js +++ b/crates/rome_js_analyze/tests/specs/correctness/noVoidElementsWithChildren/createElement.js @@ -6,4 +6,4 @@ React.createElement('img', { React.createElement('img', { dangerouslySetInnerHTML: "text" -}) \ No newline at end of file +}) diff --git a/crates/rome_js_analyze/tests/specs/correctness/noVoidElementsWithChildren/createElement.js.snap b/crates/rome_js_analyze/tests/specs/correctness/noVoidElementsWithChildren/createElement.js.snap index 51e6774c7a8..c538cfc609f 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noVoidElementsWithChildren/createElement.js.snap +++ b/crates/rome_js_analyze/tests/specs/correctness/noVoidElementsWithChildren/createElement.js.snap @@ -1,6 +1,5 @@ --- source: crates/rome_js_analyze/tests/spec_tests.rs -assertion_line: 99 expression: createElement.js --- # Input @@ -14,6 +13,7 @@ React.createElement('img', { React.createElement('img', { dangerouslySetInnerHTML: "text" }) + ``` # Diagnostics @@ -42,20 +42,22 @@ createElement.js:7:1 lint/correctness/noVoidElementsWithChildren FIXABLE ━ ! img is a void element tag and must not have the dangerouslySetInnerHTML prop. - 5 │ }, 'child') - 6 │ - > 7 │ React.createElement('img', { - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - > 8 │ dangerouslySetInnerHTML: "text" - > 9 │ }) - │ ^^ + 5 │ }, 'child') + 6 │ + > 7 │ React.createElement('img', { + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + > 8 │ dangerouslySetInnerHTML: "text" + > 9 │ }) + │ ^^ + 10 │ i Suggested fix: Remove the dangerouslySetInnerHTML prop. - 6 6 │ - 7 7 │ React.createElement('img', { - 8 │ - ····dangerouslySetInnerHTML:·"text" - 9 8 │ }) + 6 6 │ + 7 7 │ React.createElement('img', { + 8 │ - ····dangerouslySetInnerHTML:·"text" + 9 8 │ }) + 10 9 │ ``` diff --git a/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtml/reactCreateElement.js b/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtml/reactCreateElement.js index bfd30c586cb..4d78eab0fd6 100644 --- a/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtml/reactCreateElement.js +++ b/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtml/reactCreateElement.js @@ -1,3 +1,3 @@ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'child' } -}); \ No newline at end of file +}); diff --git a/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtml/reactCreateElement.js.snap b/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtml/reactCreateElement.js.snap index f697f49b28e..684283d21eb 100644 --- a/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtml/reactCreateElement.js.snap +++ b/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtml/reactCreateElement.js.snap @@ -7,6 +7,7 @@ expression: reactCreateElement.js React.createElement('div', { dangerouslySetInnerHTML: { __html: 'child' } }); + ``` # Diagnostics @@ -19,6 +20,7 @@ reactCreateElement.js:2:5 lint/security/noDangerouslySetInnerHtml ━━━━ > 2 │ dangerouslySetInnerHTML: { __html: 'child' } │ ^^^^^^^^^^^^^^^^^^^^^^^ 3 │ }); + 4 │ ! Setting content using code can expose users to cross-site scripting (XSS) attacks diff --git a/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtmlWithChildren/createElement.js b/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtmlWithChildren/createElement.js index 5cbae195554..6411485fc1a 100644 --- a/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtmlWithChildren/createElement.js +++ b/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtmlWithChildren/createElement.js @@ -1,3 +1,3 @@ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } }, ['children']) React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } }, 'children') -React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' }, children: 'children' }) \ No newline at end of file +React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' }, children: 'children' }) diff --git a/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtmlWithChildren/createElement.js.snap b/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtmlWithChildren/createElement.js.snap index aa21f4378da..2fd650c30c7 100644 --- a/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtmlWithChildren/createElement.js.snap +++ b/crates/rome_js_analyze/tests/specs/security/noDangerouslySetInnerHtmlWithChildren/createElement.js.snap @@ -7,6 +7,7 @@ expression: createElement.js React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } }, ['children']) React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } }, 'children') React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' }, children: 'children' }) + ``` # Diagnostics @@ -41,6 +42,7 @@ createElement.js:2:30 lint/security/noDangerouslySetInnerHtmlWithChildren ━━ > 2 │ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } }, 'children') │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 3 │ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' }, children: 'children' }) + 4 │ i This is the source of the children prop @@ -48,6 +50,7 @@ createElement.js:2:30 lint/security/noDangerouslySetInnerHtmlWithChildren ━━ > 2 │ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } }, 'children') │ ^^^^^^^^^^ 3 │ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' }, children: 'children' }) + 4 │ i Setting HTML content will inadvertently override any passed children in React @@ -63,6 +66,7 @@ createElement.js:3:30 lint/security/noDangerouslySetInnerHtmlWithChildren ━━ 2 │ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } }, 'children') > 3 │ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' }, children: 'children' }) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 4 │ i This is the source of the children prop @@ -70,6 +74,7 @@ createElement.js:3:30 lint/security/noDangerouslySetInnerHtmlWithChildren ━━ 2 │ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } }, 'children') > 3 │ React.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' }, children: 'children' }) │ ^^^^^^^^^^^^^^^^^^^^ + 4 │ i Setting HTML content will inadvertently override any passed children in React